import paramiko, sys sys.stdout.reconfigure(encoding='utf-8', errors='replace') client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect('101.79.17.164', username='root', password='1q2w3e!Q', timeout=30) def run(label, cmd, timeout=60): print(f'\n[{label}]') _, o, e = client.exec_command(cmd, timeout=timeout) out = o.read().decode('utf-8', errors='replace').strip() err = e.read().decode('utf-8', errors='replace').strip() if out: print(out[:400]) if err and 'warn' not in err.lower(): print('ERR:', err[:200]) run('pgvector 타입 정확성 테스트', """ /opt/guardia/venv/bin/python3 << 'PYEOF' import psycopg2 from pgvector.psycopg2 import register_vector import numpy as np conn = psycopg2.connect( host='localhost', port=5432, dbname='guardia_db', user='guardia', password='G@urd1a_2026!' ) register_vector(conn) # vector 타입 등록 필수 cur = conn.cursor() # numpy array로 삽입 (register_vector 후 자동 변환) emb = np.random.rand(768).astype(np.float32) cur.execute( 'INSERT INTO tb_vector_sr (sr_id, title, content, embedding) VALUES (%s,%s,%s,%s) ON CONFLICT (sr_id) DO UPDATE SET embedding=EXCLUDED.embedding', ('SR-TEST-001', 'pgvector 연동 테스트', 'pgvector 설치 확인', emb) ) conn.commit() # 유사 검색 query = np.random.rand(768).astype(np.float32) cur.execute( 'SELECT sr_id, title, 1 - (embedding <=> %s::vector) AS similarity FROM tb_vector_sr ORDER BY embedding <=> %s::vector LIMIT 3', (emb.tolist(), query.tolist()) ) rows = cur.fetchall() for row in rows: print('SR:', row[0], '| 유사도:', round(float(row[2]), 4)) cur.close(); conn.close() print('SUCCESS: pgvector 연동 완료!') PYEOF """) run('pgvector 버전 확인', """ sudo -u postgres psql guardia_db -c "SELECT extversion FROM pg_extension WHERE extname='vector';" 2>&1 """) run('인덱스 확인', """ sudo -u postgres psql guardia_db -c "SELECT indexname, indexdef FROM pg_indexes WHERE tablename LIKE 'tb_vector%';" 2>&1 """) client.close()