生成 t-SNE 可视化图片 Args: query: 查询文本 kb_names: 知识库名称列表 kb_manager: 知识库管理器 Returns: 图片路径或 None
(
query: str,
kb_names: list[str],
kb_manager: KnowledgeBaseManager,
)
| 12 | |
| 13 | |
| 14 | async def generate_tsne_visualization( |
| 15 | query: str, |
| 16 | kb_names: list[str], |
| 17 | kb_manager: KnowledgeBaseManager, |
| 18 | ) -> str | None: |
| 19 | """生成 t-SNE 可视化图片 |
| 20 | |
| 21 | Args: |
| 22 | query: 查询文本 |
| 23 | kb_names: 知识库名称列表 |
| 24 | kb_manager: 知识库管理器 |
| 25 | |
| 26 | Returns: |
| 27 | 图片路径或 None |
| 28 | |
| 29 | """ |
| 30 | try: |
| 31 | import faiss |
| 32 | import matplotlib # type: ignore[reportMissingImports] |
| 33 | import numpy as np |
| 34 | |
| 35 | matplotlib.use("Agg") # 使用非交互式后端 |
| 36 | import matplotlib.pyplot as plt # type: ignore[reportMissingImports] |
| 37 | from sklearn.manifold import TSNE # type: ignore[reportMissingImports] |
| 38 | except ImportError as e: |
| 39 | raise Exception( |
| 40 | "缺少必要的库以生成 t-SNE 可视化。请安装 matplotlib 和 scikit-learn: {e}", |
| 41 | ) from e |
| 42 | |
| 43 | try: |
| 44 | # 获取第一个知识库的向量数据 |
| 45 | kb_helper: KBHelper | None = None |
| 46 | for kb_name in kb_names: |
| 47 | kb_helper = await kb_manager.get_kb_by_name(kb_name) |
| 48 | if kb_helper: |
| 49 | break |
| 50 | |
| 51 | if not kb_helper: |
| 52 | logger.warning("未找到知识库") |
| 53 | return None |
| 54 | |
| 55 | kb = kb_helper.kb |
| 56 | index_path = kb_helper.kb_dir / "index.faiss" |
| 57 | |
| 58 | # 读取 FAISS 索引 |
| 59 | if not index_path.exists(): |
| 60 | logger.warning(f"FAISS 索引不存在: {index_path!s}") |
| 61 | return None |
| 62 | |
| 63 | index = faiss.read_index(str(index_path)) |
| 64 | |
| 65 | if index.ntotal == 0: |
| 66 | logger.warning("索引为空") |
| 67 | return None |
| 68 | |
| 69 | # 提取所有向量 |
| 70 | logger.info(f"提取 {index.ntotal} 个向量用于可视化...") |
| 71 | if isinstance(index, faiss.IndexIDMap): |
no test coverage detected