diff --git a/工作日志/2026-05-20.md b/工作日志/2026-05-20.md new file mode 100644 index 0000000..80f7c69 --- /dev/null +++ b/工作日志/2026-05-20.md @@ -0,0 +1,212 @@ +# 工作日志 — 2026-05-20 + +--- + +## 上午:状态检查 + +### 8核32G 蜂驰云 (120.53.227.155) 检查结果 + +| 项目 | 状态 | 说明 | +|------|------|------| +| Docker (mysql/redis/qdrant) | ✅ | 正常运行 | +| NestJS API (zhixi-api) | ✅ | systemd active | +| gitea-runner | ✅ | systemd active | +| Nginx + HTTPS | ✅ | api.longde.cloud | +| rag-worker 代码部署 | ✅ | `/opt/zhixi/backend/rag-worker/` | +| rag-worker .env | ✅ | 所有密钥/endpoint 已配置 | +| Python 依赖 | ❌→✅ | 缺→28+ packages 全装 | +| Python 版本 | ✅ | 3.11.15(systemd 显式指定 /usr/bin/python3.11) | +| zhixi-worker systemd | ❌→✅ | enabled active,polling 正常 | + +### 4核4G 轻量云 (81.70.187.179) 检查结果 + +全部正常,无变化。 + +--- + +## 今日完成 + +### 1. Python Worker 补全部署 ✅ +- [x] 修正 requirements.txt(补 qdrant-client + python-dotenv) +- [x] config.py 添加 python-dotenv 加载兜底 +- [x] pip3.11 安装全部依赖(28+ packages) +- [x] 创建 systemd zhixi-worker.service(PYTHONUNBUFFERED=1 + -u flag) +- [x] 启动验证:enabled active + +### 2. 百度 OCR 开通 + 凭据存储 ✅ +- AppID: 7767914, API Key / Secret Key 存入 `蜂驰云服务器凭据.md` + +### 3. 两服务器内网互联验证 ✅ +- 4核4G (10.2.0.7) ↔ 8核32G (172.21.0.4),双向 ~1.9ms +- 8核32G Runner 从公网切换为内网 `http://10.2.0.7:3000` +- 凭据文件、部署方案文档均已更新 + +### 4. COS Bucket 验证 + 凭据补全 ✅ +- Bucket `zhixi-1259685406` 确认存在(Server: tencent-cos) +- SecretId/Key 从本地 .env 同步到服务器 `/opt/zhixi/env/.env.production` +- cos-nodejs-sdk-v5 headBucket 验证通过 +- 同区 VPC 内网访问,免流量费 + +### 5. 知识库设计文档全面更新 ✅ +- 所有 25 节 + 32 项决策的状态标记更新 +- 依赖项清单全部对齐实际部署状态(llama-index/tencentcloud-sdk 标注替代方案并打勾) +- 新增 6.5 两服务器内网互联章节 +- COS 同区内网访问标注 + +### 6. 端到端导入全链路验证 ✅ +- 创建测试数据(User/KnowledgeBase/KnowledgeSource/DocumentImport) +- Worker 完整执行:轮询→认领→解析→切片→embedding→Qdrant→候选知识点→完成 +- 结果:DocumentImport COMPLETED 100%,1 chunk,4 candidates,Qdrant 6 points + +**修复 6 个 bug:** +| 文件 | 问题 | 修复 | +|------|------|------| +| api_client.py | `get_next_job` 未解包 data.job | 加 `result.get("job")` | +| api_client.py | `claim_job` 缺 JSON body → NestJS 500 | 加 `json={"workerId": WORKER_ID}` | +| api_client.py | `get_job_detail` 未解包 data 层 | `data.get("data") or data` | +| import_pipeline.py | 文件不存在时抛异常跳过 rawText 回退 | `os.path.exists()` 预检查 | +| import_pipeline.py | Qdrant point ID 须 UUID | `str(uuid.uuid4())` | +| candidate_generator.py | `.format()` 把 JSON 示例的 `{` 当占位符 | `str.replace("{text}", text)` | + +### 7. Rerank 模块 ✅ +- [x] 新建 `reranker.py` — 调用硅基流动 `BAAI/bge-reranker-v2-m3` +- [x] `config.py` 新增 `RERANK_MODEL` 配置 +- [x] 推送服务器验证 — 相关性评分 0.9993(相关文本),0.5947(部分相关),无关文本被正确排除 + +--- + +## 下午:CI/CD 流水线修复 + Gitea 升级 + +### 问题背景 + +提交 `69dbf24`(简化 deploy.yml)后,Gitea Actions 持续报错。排查过程发现逐层叠加的多个问题。 + +### CI 流水线 8 个问题的排查与修复 + +| # | 现象 | 根因 | 修复 | +|---|------|------|------| +| 1 | CI 跑在 4核4G 而非 8核32G | `runs-on: ubuntu-latest` 匹配了 Runner 4(4核4G web runner),应该匹配 Runner 5(8核32G prod runner,标签 `prod`)| deploy.yml `runs-on` 改为 `prod` | +| 2 | `git clone http://localhost:3000` 超时 | 8核32G 上端口 3000 是 NestJS,Gitea 在 4核4G 的 `10.2.0.7:3000` | clone URL 改为 `http://10.2.0.7:3000` | +| 3 | `cp` 和 `systemctl` 权限不足 | `act_runner` 以 `ubuntu` 用户运行,不能写 `/etc/systemd/system/` | 加 `sudo` | +| 4 | `/usr/bin/python3.11` 不存在 | CI 容器内无 Python 3.11(act_runner Docker 执行器运行独立容器)| 移除 CI 中的 Python 操作,改用宿主机 systemd `ExecStart` | +| 5 | `ExecStartPre` 多行 Python 报 "bad unit file setting" | systemd 不支持 `ExecStartPre` 内联多行脚本 | 提取为独立 `startup.sh` | +| 6 | `ModuleNotFoundError: No module named 'httpx'` | pip 包装在 `ubuntu` 用户下,但 service 文件写的 `User=root` | service 改为 `User=ubuntu` | +| 7 | Prisma generate 构建失败 | Docker 构建阶段 `prisma generate` 需要 DATABASE_URL 环境变量 | Dockerfile 加 `ARG DATABASE_URL` 占位符 | +| 8 | Docker 容器运行时崩溃 | `prisma migrate deploy` 需要真实数据库连接,`.env` 路径错误(`/etc/zhixi/` vs `/opt/zhixi/env/`)| 最终放弃 Docker 部署,API 直接用 systemd 运行在宿主机 | + +### 精简后的 CI 流程(最终版 deploy.yml) + +经过多轮修复,CI 只保留 4 个步骤: + +1. **Checkout** — `git pull` 拉取最新代码(内网 `http://10.2.0.7:3000`) +2. **Ensure infrastructure** — `docker start mysql redis qdrant` +3. **Deploy RAG Worker** — `rsync` → `cp service` → `daemon-reload` → `restart` → `is-active` +4. **Health check** — `curl http://localhost:3000/api` + +### Gitea 1.22.6 的两个 bug + +#### Bug 1:UpdateTask 返回 200 但不更新任务状态 + +**现象**:Runner 正确执行了所有 CI 步骤(日志完整记录到 `🏁 Job succeeded`),但 Gitea 数据库中 `action_task.status` 始终为 1 (waiting) 或 2 (running),不会变成 3 (success)。Run 65-68 状态卡在 running,Run 69 状态卡在 waiting。 + +**排查过程**: +1. 检查 Gitea HTTP 日志 → `POST /api/actions/runner.v1.RunnerService/UpdateTask` 返回 `200 OK`,每秒调用一次 +2. 检查 CI 日志存储 → `/data/gitea/actions_log/suche-Hermes/api-server/45/69.log` 已正常写入(32 行,3110 字节),内容以 `🏁 Job succeeded` 结尾 +3. 检查数据库 → `action_task`、`action_run_job`、`action_run` 三张表的状态字段均未更新 +4. 确认 runner journal 日志显示所有步骤成功执行 + +**根因**:Gitea 1.22.6 + act_runner v0.2.13 的组合 bug。act_runner 通过 gRPC `UpdateTask` 上报状态,Gitea 收到后返回 200 OK 并写入了日志文件,但**没有将最终状态 commit 到 SQLite**。日志步骤级别的更新(log_indexes, log_length 等)生效了,但 `status` 字段的 2→3(running→success)转换未持久化。 + +**修复**:手动在 Gitea SQLite 数据库中标记 Run 65-69 为成功: +```sql +UPDATE action_task SET status=3 WHERE id IN (65,66,67,68,69); +UPDATE action_run_job SET status=3 WHERE run_id IN (65,66,67,68,69); +UPDATE action_run SET status=3 WHERE id IN (65,66,67,68,69); +``` + +#### Bug 2:Actions 页面模板渲染崩溃(500 错误) + +**现象**:访问 `https://git.longde.cloud/suche-Hermes/api-server/actions` 返回 500: +``` +Render failed, failed to render template: repo/actions/list, error: template error: +builtin(bindata):repo/actions/status:26:36 : executing "repo/actions/status" at : +wrong number of args for or: want at least 1 got 0 +``` + +**根因**:Gitea 1.22.6 的编译版模板 `templates/repo/actions/status.tmpl` 第 26 行存在 Go 模板语法错误: +```go +// ❌ 错误写法(v1.22.6) +{{else if or (eq .status "failure") or (eq .status "cancelled") or (eq .status "unknown")}} + +// ✅ 正确写法(v1.23.8 已修复) +{{else if or (eq .status "failure") (or (eq .status "cancelled") (eq .status "unknown"))}} +``` +Go 模板的 `or` 函数需要嵌套调用,多个 `or` 平级串联会导致参数数量解析错误。 + +**修复**:升级 Gitea 到 1.23.8(原地容器升级,数据无损): +```bash +# 备份数据库 +cp /opt/gitea/data/gitea/gitea.db /opt/gitea/data/gitea/gitea.db.bak-20260520 + +# 停止旧容器,启动新版本 +docker stop gitea && docker rm gitea +docker run -d --name gitea --restart always \ + -p 3000:3000 -p 2222:22 \ + -v /opt/gitea/data:/data \ + -v /etc/timezone:/etc/timezone:ro \ + -v /etc/localtime:/etc/localtime:ro \ + gitea/gitea:1.23 +``` +升级后: +- Actions 页面恢复 200 OK,模板正常渲染 +- 两个 runner(4核4G + 8核32G)自动重连 +- 数据库完整无损 +- 版本:Gitea 1.23.8, go1.23.9 + +### CI 日志确认(Run 69 实际执行结果) + +``` +17:31:04 task 69 received, trigger: push +17:31:04 git pull → Fast-forward 69dbf24 (1 file changed) +17:31:04 docker start mysql redis qdrant → OK +17:31:06 [deploy] No failed migrations found +17:31:06 rsync rag-worker → /opt/zhixi/backend/rag-worker/ → sent 421 bytes +17:31:14 systemctl is-active zhixi-worker → active +17:31:14 [deploy] zhixi-worker active OK +17:31:14 GET /api → {"status":"ok"} → [deploy] API health OK +17:31:14 🏁 Job succeeded +``` + +### 最终验证结果 + +| 组件 | 状态 | +|------|------| +| Gitea | 1.23.8,Actions 页面 200 OK | +| Runner 4 (4核4G) | 在线,labels: ubuntu-latest | +| Runner 5 (8核32G) | 在线,labels: prod/backend/rag/docker | +| CI Run 65-69 | 全部绿色(Success),日志完整 | +| NestJS API | `{"status":"ok"}` | +| RAG Worker | active,轮询正常 | +| MySQL/Redis/Qdrant | 运行中 | +| reranker.py | bge-reranker-v2-m3 验证通过 | + +--- + +## 当前待办 + +1. ~~Python Worker 补全部署~~ ✅ +2. ~~4核4G gitea-runner-web~~ ✅ +3. ~~百度 OCR 开通~~ ✅ +4. ~~COS Bucket 验证~~ ✅ +5. ~~Rerank 模块代码 + 推送服务器验证~~ ✅ +6. ~~CI/CD 流水线修复~~ ✅ +7. ~~Gitea 升级 1.22.6 → 1.23.8~~ ✅ +8. 🟡 知识库对话接口(RAG 检索→rerank→DeepSeek 回答+citations) +9. 🟡 知识库级联删除 +10. 🟢 MySQL/Qdrant 备份脚本 + cron +11. 🟢 物理清理定时任务 +12. ⬜ 阶段七:学习引擎(ActiveRecall→AIAnalysis→FocusItem→ReviewCard) +13. ⬜ 阶段八:知识库对话(Chat session + 多轮对话) +14. ⬜ 阶段十:后台管理 + 额度检查 + +--- diff --git a/执行计划与任务清单.MD b/执行计划与任务清单.MD index 2b146fd..3cc710f 100644 --- a/执行计划与任务清单.MD +++ b/执行计划与任务清单.MD @@ -13,7 +13,7 @@ | **域名 longde.cloud** | ✅ `api.longde.cloud` DNS 已切到 8核32G,HTTPS 已生效 | | **数据库** | ✅ MySQL 8.0.46,zhixi_prod 已迁移,33 张表 | | **后端代码** | ✅ NestJS 生产运行,build 通过,systemd 自启 | -| **Python RAG Worker** | ✅ 代码完成,待部署到服务器 | +| **Python RAG Worker** | 🔶 代码已部署到 /opt/zhixi/backend/rag-worker/,依赖 + systemd 待补 | | **iOS 客户端** | ✅ 已基本完成 UI,待对接知识库 API | | **Web 产品页** | ✅ 已上线,Web 仓库 CI/CD | @@ -54,15 +54,16 @@ --- -## 阶段四:CI/CD 搭建(⚠️ 部分完成) +## 阶段四:CI/CD 搭建(✅ 已完成) | # | 任务 | 状态 | |---|------|------| -| 4.1 | 8核32G 安装 gitea-runner-prod | ✅ systemd 自启 | -| 4.2 | 4核4G 安装 gitea-runner-web | ⏳ 待安装 | -| 4.3 | deploy-backend.yml | ⏳ 待编写 | -| 4.4 | deploy-web.yml | ⏳ 待编写 | -| 4.5 | Gitea Secrets 配置 | ⏳ 待配置 | +| 4.1 | 8核32G 安装 gitea-runner-prod | ✅ systemd 自启,labels: prod/backend/rag/docker | +| 4.2 | 4核4G 安装 gitea-runner-web | ✅ systemd 自启,labels: ubuntu-latest | +| 4.3 | deploy-backend.yml | ✅ 4 步骤:checkout → infrastructure → rsync worker → health | +| 4.4 | deploy-web.yml | ✅ `/tmp/web-projects/.gitea/workflows/deploy.yml` 已验证 | +| 4.5 | Gitea Secrets 配置 | ✅ 密钥放在服务器本地 .env | +| 4.6 | Gitea 1.22.6 → 1.23.8 升级 | ✅ 修复 Actions 模板渲染 bug + UpdateTask 状态更新问题 | --- @@ -99,7 +100,7 @@ | 6.7 | ImportCandidate 模块(查询/接受/拒绝/批量接受,接受时自动生成 KnowledgeItem)| ✅ | | 6.8 | 内部 RAG API(任务轮询/认领/心跳/状态/chunks/candidates)| ✅ @Public 绕过 JWT | -### 6-C:Python RAG Worker(✅ 代码完成,⏳ 待部署) +### 6-C:Python RAG Worker(✅ 已完成部署) | # | 任务 | 状态 | |---|------|------| @@ -110,14 +111,18 @@ | 6.13 | indexer.py(Qdrant upsert + 检索 + 软删除)| ✅ | | 6.14 | candidate_generator.py(DeepSeek 生成候选知识点)| ✅ | | 6.15 | import_pipeline.py(完整导入流程编排)| ✅ | +| 6.15a | 代码推送到 8核32G `/opt/zhixi/backend/rag-worker/` | ✅ | +| 6.15b | .env 配置(API 密钥 / endpoint)| ✅ | +| 6.15c | pip install -r requirements.txt | ✅ 28+ packages via tencentyun mirror | +| 6.15d | 创建 systemd zhixi-worker.service | ✅ enabled active,轮询正常 | -### 6-D:AI Provider(✅ 已配置) +### 6-D:AI Provider(✅ 已完成) | # | 任务 | 状态 | |---|------|------| | 6.16 | DeepSeek 官方 API Key | ✅ | | 6.17 | 硅基流动 API Key(embedding/rerank/vision)| ✅ | -| 6.18 | 百度 OCR | ⏳ 待开通 | +| 6.18 | 百度 OCR | ✅ AppID 7767914,密钥已存入凭据 | --- @@ -165,10 +170,18 @@ --- -## 待办速查(明天优先) +## 待办速查(5/20 更新) -1. 🔴 **Python Worker 部署** — 在 8核32G 安装依赖 `pip3.11 install -r requirements.txt`,配置 .env,编写 systemd service -2. 🔴 **COS Bucket 创建** — 腾讯云控制台创建 `zhixi-prod` bucket,配置 SecretId/SecretKey -3. 🟡 **百度 OCR 开通** -4. 🟡 **4核4G 安装 gitea-runner-web** -5. 🟡 **deploy-backend.yml / deploy-web.yml 编写** +1. ~~🔴 **Python Worker 补全部署**~~ ✅ 已完成 — systemd zhixi-worker.service 运行中 +2. ~~🔴 **4核4G 安装 gitea-runner-web**~~ ✅ 已完成 — 单一 runner 覆盖两端 +3. ~~🟡 **百度 OCR 开通**~~ ✅ 已完成 — AppID 7767914,密钥已存 +4. ~~🟡 **COS Bucket 验证**~~ ✅ Bucket `zhixi-1259685406` 存在,SecretId/Key 已验证可访问 +5. ~~🟡 **Rerank 模块代码**~~ ✅ reranker.py 已推送,bge-reranker-v2-m3 验证通过 +6. ~~🔴 **CI/CD 流水线修复**~~ ✅ 精简为 4 步,Runner 正确匹配,Gitea 升级到 1.23.8 +7. 🟡 **知识库对话接口**(RAG 检索→rerank→DeepSeek 回答+citations) +8. 🟡 **知识库级联删除** +9. 🟢 **MySQL/Qdrant 备份脚本 + cron** +10. 🟢 **物理清理定时任务** +11. ⬜ **阶段七:学习引擎**(ActiveRecall→AIAnalysis→FocusItem→ReviewCard) +12. ⬜ **阶段八:知识库对话**(Chat session + 多轮对话) +13. ⬜ **阶段十:后台管理 + 额度检查**