Files
tps-dashboard/logs/phase3_log_task1.md
T
2026-05-26 18:59:39 +08:00

117 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Phase 3 开发日志
> 本文件记录 Phase 3(知识库基础设施)各 Task 的已完成事实。
> 续接快照(待办/决策)见单独文件,不混入本 log。
---
## Task 1 — embedding 最小链路验证 ✅(2026-05-26 完成)
### 目标
用最小代价验证 Phase 3 的命脉:文本能否转成正确维度的向量、整条「解析→embedding→入库→语义检索」链路能否跑通。不碰 schema、不碰前端、不碰 docx。
### 关键结论(地基事实,后续 Task 依赖)
- **embedding 服务确定为 MiniMax embo-01**。前期查证已排除 DeepSeek(官方无 embedding 接口)。
- **embo-01 输出维度 = 1536**,与 `001_init.sql``knowledge_embeddings.embedding vector(1536)` 完全匹配,无需改维度、无需改宪法。
- **embo-01 真实接口结构**(实测确认,非凭印象):
- 请求:`{"model":"embo-01", "texts":[...], "type":"db"|"query"}` —— 注意是 `texts` 数组,不是 OpenAI 的 `input`
- 返回:向量在 `vectors` 字段(`data["vectors"][0]`),不是 OpenAI 的 `data[0].embedding`
- 存文档用 `type="db"`,查询用 `type="query"`,不可混。
- 调用需 `Authorization: Bearer {API_KEY}` + `GroupId` 两个凭证(MiniMax 特有 GroupId)。
- **检索方式**:使用 pgvector 数据库原生余弦距离算子 `<=>`,不在 Python 侧计算。
- **凭证管理**API Key + GroupId 存于 `backend/.env``MINIMAX_EMBED_API_KEY` / `MINIMAX_GROUP_ID`),代码从 .env 读取,未进任何代码、未进 git.env 已在 .gitignore)。
- 注意:embedding 接口地址 `https://api.minimax.chat/v1/embeddings`,与 Cline 写代码所用的 M2.7 chat 接口是两套独立配置,互不影响。
### 新增/改动文件(已 commit & pushcommit 38873ac
- `backend/requirements.txt`+pgvector==0.2.5
- `backend/app/core/config.py`+引导凭证字段)
- `backend/app/models/knowledge.py`(新增,embedding 字段用 pgvector.Vector
- `backend/app/services/embedding_service.py`(新增,embo-01 调用封装)
- `backend/app/services/knowledge_service.py`(新增,写库 + SQL 向量检索)
- `backend/scripts/test_embo01_api.py`(探路脚本)
- `backend/scripts/verify_embedding.py`(全链路验证脚本)
- `backend/sample_md/`(空目录,测试文件已清)
### 收尾
- 验证用测试数据已全部清除:knowledge_items = 0 行,knowledge_embeddings = 0 行,sample_md/ 空。
- 知识库当前为干净空库,等待真实笔记导入。
### 顺手核实到的现状(未处理,留待办)
- episodes 表当前仅 7 行。
- Phase 2 的「批量导入」前端有入口但从未真实导入过收视数据(制片人确认:是流程上没提醒导入,加上收视表里有测试数据不会删)。属 Phase 2 遗留债,记入 backlog,另行处理,不并入 Phase 3。
---
## Task 2 — 知识库管理后台(最小可用版)✅(2026-05-26 完成)
### 目标
做一条端到端跑通的链路:上传 .md 笔记 → 解析 yaml frontmatter → 入库(含语义向量)→ 列表展示 → 删除。不改 schema、不碰认证、不引向量索引以外的新依赖。
### 新增/改动文件(4 次独立 commit)
| 文件 | 动作 | 说明 |
|------|------|------|
| `backend/requirements.txt` | 改 | +python-frontmatter==1.1.0 |
| `backend/app/services/knowledge_service.py` | 扩展 | +parse_md_file() + delete_item() + list_items() + get_distinct_sources();复用 EmbeddingService |
| `backend/app/api/knowledge.py` | 新增 | 4 个接口:POST /upload、GET /items、DELETE /items/{id}、GET /sources |
| `backend/app/main.py` | 改 | +app.include_router(knowledge_router) |
| `frontend/src/services/knowledgeService.js` | 新增 | 封装 4 个 API 调用 |
| `frontend/src/pages/KnowledgeBase/KnowledgeBase.jsx` | 重写 | 上传区(Dragger) + 筛选栏(Select) + 列表(Table) + 删除(Popconfirm) |
### yaml frontmatter 解析映射(按真实样本,写死)
```python
# 类型 → source_type(硬映射,不猜测)
杂志文章/军报 military_report
节目文稿 manuscript
报题单 baoti
# 标题
名称 标题 title
# 作者
作者 编导 author
# 出处详情(存 JSONB 的 source_detail
期刊 + 期号 拼接"航空知识 2026年第1期"
# 播出日期
容错"待补充"等非日期文本 null
# 权重
原样存 JSONB不展示不排序Phase 4 排序用
# 双链 [[...]]
_extract_double_brackets() 原样存入 JSONB 预留给 Phase 4
```
### 关键设计决策
1. **source_detail 存 JSONB 不 ALTER**Task Brief 说"不要新增表字段"`tags` JSONB 列已用于存权重,故 source_detail 也放进来,不 ALTER TABLE。查询时从 `tags->>'source_detail'` 解压。
2. **来源筛选动态从 DB 取**`get_distinct_sources()` 查库里所有 `tags->>'source_detail'` DISTINCT 值,下拉选项不写死,新增一本杂志自动出现。
3. **embedding 复用**:直接调用 `EmbeddingService.embed_single(content_md, embed_type="db")`1536 维向量已验证,不重写。
4. **删除 CASCADE**:数据库层已有 `ON DELETE CASCADE`Python 侧只删 `KnowledgeItem` 即可。
### 测试结果(已验证)
| 验收项 | 结果 |
|--------|------|
| 两篇 md 均成功入库 | ✅ id=27(光辉之路)、id=28(超级战舰) |
| 杂志篇显示作者"钱峰",无播出时间 | ✅ author=钱峰, publish_date=null |
| 节目篇显示编导"左鑫",播出日期"待补充"不显示 | ✅ author=左鑫, publish_date=null |
| source_detail 正确存下("航空知识 2026年第1期" | ✅ tags 中可见 |
| 来源筛选下拉可据此筛 | ✅ /api/knowledge/sources 返回 `航空知识 2026年第1期` |
| knowledge_embeddings 有对应行(向量已生成) | ✅ 两行,19207/19174 字符(1536 维) |
| 删除有二次确认,确认后条目+向量一并消失 | ✅ 删除 id=27 验证,embeddings 级联消失 |
### commit 历史
- `779429a` feat: 添加 python-frontmatter 依赖用于解析 md yaml frontmatter
- `7b6ae24` feat: 知识库管理后台上传/列表/删除API,含frontmatter解析
- `7155a18` feat: 知识库管理前端页面,含上传/列表/筛选/删除
### 潜在风险
1. **windows CRLF 警告**:每次 commit 都有 CRLF→LF 警告,不影响功能但难看,属 git 全局配置问题(core.autocrlf),下次提醒用户设一下。
2. **"待补充"播出日期**:节目文稿的播出日期"待补充"正确存为 null,列表"播出/发表时间"格无值时不显示(render: val || null)。
3. **删除后 sources 下拉残留**:删除后 `get_distinct_sources()` 重新查会去掉已删条目的 source_detail,正常。
4. **embo-01 调用失败时整条上传失败**:当前是 try-except 包装,失败时返回 errors 数组,不污染已入库数据(因为单条原子),但前端需要展示 errors 反馈(已实现)。