feat(phase3): Task1 embedding链路验证 - embo-01(1536维)+pgvector检索打通
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
"""
|
||||
探路脚本 — 调 MiniMax embo-01,打印原始返回 JSON
|
||||
确认向量字段位置和维度后再写正式 service。
|
||||
"""
|
||||
|
||||
import httpx
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
# 加载 .env
|
||||
from dotenv import load_dotenv
|
||||
_env_path = Path(__file__).parent.parent / ".env"
|
||||
load_dotenv(str(_env_path))
|
||||
|
||||
api_key = os.environ.get("MINIMAX_EMBED_API_KEY", "")
|
||||
group_id = os.environ.get("MINIMAX_GROUP_ID", "")
|
||||
|
||||
if not api_key or api_key == "your_api_key_here":
|
||||
print("[ERROR] MINIMAX_EMBED_API_KEY not configured, please edit backend/.env")
|
||||
exit(1)
|
||||
if not group_id or group_id == "your_group_id_here":
|
||||
print("[ERROR] MINIMAX_GROUP_ID not configured, please edit backend/.env")
|
||||
exit(1)
|
||||
|
||||
print(f"API Key (first 4 chars): {api_key[:4]}...")
|
||||
print(f"GroupId: {group_id}")
|
||||
print()
|
||||
|
||||
# 最小调用
|
||||
test_text = "这是一段测试文本,用于验证 embo-01 接口返回结构。"
|
||||
|
||||
print(f"Sending request, test text: {test_text}")
|
||||
print("-" * 60)
|
||||
|
||||
try:
|
||||
resp = httpx.post(
|
||||
"https://api.minimax.chat/v1/embeddings",
|
||||
headers={
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"GroupId": group_id,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
json={"model": "embo-01", "texts": [test_text], "type": "db"},
|
||||
timeout=30.0,
|
||||
)
|
||||
print(f"HTTP status: {resp.status_code}")
|
||||
print()
|
||||
data = resp.json()
|
||||
print(json.dumps(data, indent=2, ensure_ascii=False))
|
||||
|
||||
# 提取向量,验证维度
|
||||
print()
|
||||
print("-" * 60)
|
||||
vectors = data.get("vectors", [])
|
||||
if vectors and len(vectors) > 0:
|
||||
embedding = vectors[0]
|
||||
dim = len(embedding)
|
||||
print(f"[OK] Embedding field: vectors[0]")
|
||||
print(f"[OK] Embedding dimension: {dim}")
|
||||
if dim != 1536:
|
||||
print(f"[STOP] Dimension is NOT 1536! Got {dim} - stopping here")
|
||||
else:
|
||||
print(f"[OK] Dimension correct: 1536")
|
||||
print(f"[OK] API call successful, structure confirmed.")
|
||||
else:
|
||||
print("[WARNING] vectors not found in response")
|
||||
|
||||
except Exception as e:
|
||||
print(f"[ERROR] Request failed: {e}")
|
||||
@@ -0,0 +1,79 @@
|
||||
"""
|
||||
全链路验证脚本 — TPS 知识库 embedding 最小链路
|
||||
|
||||
验证步骤:
|
||||
1. 读取 backend/sample_md/ 下的 5 篇 .md 文件
|
||||
2. 调用 embo-01 转成向量(打印维度)
|
||||
3. 存入 knowledge_items + knowledge_embeddings(打印行数)
|
||||
4. 执行语义检索(打印查询句 + 最相似笔记)
|
||||
5. 查 episodes 表行数(打印,只读不动)
|
||||
"""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
from dotenv import load_dotenv
|
||||
from sqlmodel import text
|
||||
|
||||
# 加载 .env
|
||||
_env_path = Path(__file__).parent.parent / ".env"
|
||||
load_dotenv(str(_env_path))
|
||||
|
||||
from app.services.knowledge_service import KnowledgeService
|
||||
from app.db.session import engine
|
||||
|
||||
|
||||
def main():
|
||||
print("=" * 60)
|
||||
print("TPS Knowledge Base — Embedding Full链路验证")
|
||||
print("=" * 60)
|
||||
|
||||
sample_dir = Path(__file__).parent.parent / "sample_md"
|
||||
md_files = sorted(sample_dir.glob("*.md"))
|
||||
print(f"\n[FIND] Found {len(md_files)} .md files in sample_md/")
|
||||
|
||||
ks = KnowledgeService()
|
||||
|
||||
# 1. 写入知识库
|
||||
print("\n[STEP 1] Storing MD files into knowledge base...")
|
||||
items_stored = []
|
||||
for mf in md_files:
|
||||
title = mf.stem # 文件名(不含扩展名)作为标题
|
||||
content = mf.read_text(encoding="utf-8")
|
||||
item = ks.store_md_file(
|
||||
title=title,
|
||||
content_md=content,
|
||||
source_file_name=mf.name,
|
||||
source_type="manual",
|
||||
)
|
||||
items_stored.append(item)
|
||||
print(f" - Stored: {item.title} (id={item.id})")
|
||||
|
||||
ki_count = ks.get_item_count()
|
||||
ke_count = ks.get_embedding_count()
|
||||
print(f"\n[OK] knowledge_items rows: {ki_count}")
|
||||
print(f"[OK] knowledge_embeddings rows: {ke_count}")
|
||||
|
||||
# 2. 语义检索
|
||||
print("\n[STEP 2] Semantic search test...")
|
||||
query = "五代战斗机的隐身技术有哪些关键要素?"
|
||||
print(f"Query: {query}")
|
||||
results = ks.search_similar(query, top_k=3)
|
||||
print(f"\n[OK] Top 3 similar notes:")
|
||||
for i, r in enumerate(results, 1):
|
||||
print(f" {i}. [{r['similarity']}] {r['title']}")
|
||||
|
||||
# 3. 查 episodes 表行数(只读不动)
|
||||
print("\n[STEP 3] Episodes table (read-only)...")
|
||||
with engine.connect() as conn:
|
||||
result = conn.execute(text("SELECT COUNT(*) FROM episodes"))
|
||||
episode_count = result.scalar()
|
||||
print(f"[OK] episodes table row count: {episode_count}")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("Verification complete.")
|
||||
print("=" * 60)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user