Compare commits
2 Commits
c6232d8325
...
2e063e2ac0
| Author | SHA1 | Date |
|---|---|---|
|
|
2e063e2ac0 | |
|
|
6e455d37be |
|
|
@ -87,11 +87,11 @@ Session = 消息列表,ORM 直写 PG `messages`(append-only,jsonb 存 LiteLLM
|
||||||
|
|
||||||
### 3.8 个人知识库(`core/kb.py` + `core/kb_ingest.py`,✅ 2026-07-22)
|
### 3.8 个人知识库(`core/kb.py` + `core/kb_ingest.py`,✅ 2026-07-22)
|
||||||
|
|
||||||
用户自建资料(规范/报告/标准/内部文档)的长期查阅层,与 §3.7 记忆同范式:**纯文件 + prompt 注入契约,无向量无 DB**(判据同"真实文件为准":个人库几十~百余文件,agentic search 足够;索引若引入只能是可重建派生缓存)。**两层格局**:zcbot 内建 `.kb/` 私有小库(本节)+ 院检索服务共享大库(document_search,zcbot 只当客户端)——分工标准 = 文件数 × 查询频次,路由规则写进注入契约(学科文献→院库 / 自建资料→`.kb`)。
|
用户自建资料(规范/报告/标准/内部文档)的长期查阅层,与 §3.7 记忆同范式:**纯文件 + prompt 注入契约,无向量无 DB**(判据同"真实文件为准":个人库几十~百余文件,agentic search 足够;索引若引入只能是可重建派生缓存)。**两层格局**:zcbot 内建 `.kb/` 私有小库(本节)+ 院检索服务共享大库(document_search,zcbot 只当客户端)——分工标准 = 文件数 × 查询频次,路由靠各自工具/契约描述自然分流,不在 kb 契约里点名 document_search(2026-07-22 收窄:契约只管自己怎么用,少一层耦合)。
|
||||||
|
|
||||||
- **做成机制而非 skill**(判据:有独立于会话的持久状态需用户管理 → 机制):落盘 `user_root/.kb/<库名>/`(INDEX.md + docs/ 转换后 md + sources/ 原件)。**"已入库"判据 = INDEX.md 有条目**,sources 有而 INDEX 无 = 待入库 → 入库幂等、崩溃可恢复、零 migration。dotfile 命名同 `.memory` 双向防呆,GET /v1/files 天然隐藏。
|
- **做成机制而非 skill**(判据:有独立于会话的持久状态需用户管理 → 机制):落盘 `user_root/.kb/<库名>/`(INDEX.md + docs/ 转换后 md + sources/ 原件)。**"已入库"判据 = INDEX.md 有条目**,sources 有而 INDEX 无 = 待入库 → 入库幂等、崩溃可恢复、零 migration。dotfile 命名同 `.memory` 双向防呆,GET /v1/files 天然隐藏。
|
||||||
- **入库管线**(`core/kb_ingest.py`,上传即触发 + 手动兜底):markitdown Python API 转 md → 扫描件 PDF(文本近零)走方舟文档理解 OCR 兜底(§8.13 同通道)→ deepseek flash 单次 chat 写 标题/摘要/关键词(失败降级文件名+正文开头,不阻塞)→ 追加 INDEX 行。编排照定时执行器:create_task + to_thread + per-(user,库) 内存锁去重;进度存内存供前端轮询,崩了靠 FS 判据续跑。
|
- **入库管线**(`core/kb_ingest.py`,上传即触发 + 手动兜底):markitdown Python API 转 md → 扫描件 PDF(文本近零)走方舟文档理解 OCR 兜底(§8.13 同通道)→ deepseek flash 单次 chat 写 标题/摘要/关键词(失败降级文件名+正文开头,不阻塞)→ 追加 INDEX 行。编排照定时执行器:create_task + to_thread + per-(user,库) 内存锁去重;进度存内存供前端轮询,崩了靠 FS 判据续跑。
|
||||||
- **agent 侧零新工具**:`kb_block`(照 memory_block)把 INDEX 全文 + 契约(路由规则 / INDEX 行格式 / 答题标来源)注 prompt,**用户有库才注入**;fs 工具在 user_root 内可读写、docker 沙箱整 user_root bind → `.kb` 天然可达。INDEX 行格式是对话内手动入库与后台产出的同一契约。
|
- **agent 侧零新工具**:`kb_block`(照 memory_block)把 INDEX 全文 + 契约(主动查阅无需点名 / INDEX 行格式 / 答题标来源)注 prompt,**用户有库才注入**;fs 工具在 user_root 内可读写、docker 沙箱整 user_root bind → `.kb` 天然可达。INDEX 行格式是对话内手动入库与后台产出的同一契约。
|
||||||
- **API 薄壳**(`/v1/kb*` 8 端点):列/建/删库、详情(带入库进度)、上传即入库、手动 ingest、看/删单篇。**不设 HTTP 检索端点**——检索是 agent 的事。前端两栏 modal(kb.js)管上传/删除,查询全走对话。
|
- **API 薄壳**(`/v1/kb*` 8 端点):列/建/删库、详情(带入库进度)、上传即入库、手动 ingest、看/删单篇。**不设 HTTP 检索端点**——检索是 agent 的事。前端两栏 modal(kb.js)管上传/删除,查询全走对话。
|
||||||
- **记账**:`usage_events` kind="kb_ingest"(OCR 那笔走 kind="vision"),无 task 上下文 → 0022 放宽 task_id 可 NULL,溯源靠 units JSONB `{"kb", "source"}`。
|
- **记账**:`usage_events` kind="kb_ingest"(OCR 那笔走 kind="vision"),无 task 上下文 → 0022 放宽 task_id 可 NULL,溯源靠 units JSONB `{"kb", "source"}`。
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ state.json 已删除(元数据全在 PG)。
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Callable, Optional, Tuple
|
from typing import Any, Callable, Optional, Tuple
|
||||||
|
|
@ -379,6 +380,14 @@ def _build_system_prompt(
|
||||||
wd_path = "/workspace"
|
wd_path = "/workspace"
|
||||||
else:
|
else:
|
||||||
wd_path = str(wd_abs)
|
wd_path = str(wd_abs)
|
||||||
|
# 渲染器调用命令按 backend 换:docker 是容器内 bind 的 /sandbox 路径 + 容器 python;
|
||||||
|
# host(本地 dogfood)按宿主真实路径 + 当前解释器(venv,依赖齐)—— 否则 agent 拿着
|
||||||
|
# 容器路径在宿主上调,必 FileNotFoundError。skill 文档里的 /sandbox 写法是 docker
|
||||||
|
# 专属管线,不受此影响。
|
||||||
|
if is_docker:
|
||||||
|
render_cmd = "python /sandbox/rendering/render.py"
|
||||||
|
else:
|
||||||
|
render_cmd = f'"{sys.executable}" "{ROOT / "rendering" / "render.py"}"'
|
||||||
today = datetime.now().strftime("%Y-%m-%d")
|
today = datetime.now().strftime("%Y-%m-%d")
|
||||||
tname = task_name or "<未指定>"
|
tname = task_name or "<未指定>"
|
||||||
short_id = task_id.hex[:8]
|
short_id = task_id.hex[:8]
|
||||||
|
|
@ -414,7 +423,7 @@ def _build_system_prompt(
|
||||||
f"**优先**把正文写成 Markdown(`<task_dir>/sections/*.md`,纯文本、零转义 / 零语法风险),"
|
f"**优先**把正文写成 Markdown(`<task_dir>/sections/*.md`,纯文本、零转义 / 零语法风险),"
|
||||||
f"再调平台渲染器出 docx —— **别在 run_python 里手撸 python-docx 内联大段中文正文**"
|
f"再调平台渲染器出 docx —— **别在 run_python 里手撸 python-docx 内联大段中文正文**"
|
||||||
f"(中文引号 / 全角标点混进源码极易 SyntaxError、反复返工烧 token):\n\n"
|
f"(中文引号 / 全角标点混进源码极易 SyntaxError、反复返工烧 token):\n\n"
|
||||||
f" python /sandbox/rendering/render.py --profile report --format docx <task_dir>/sections/ -o <task_dir>/<报告名>.docx\n\n"
|
f" {render_cmd} --profile report --format docx <task_dir>/sections/ -o <task_dir>/<报告名>.docx\n\n"
|
||||||
f"渲染器自动管字体(正文宋体小四 / 标题黑体 / 1.5 倍行距)、目录(加 `--toc`)、"
|
f"渲染器自动管字体(正文宋体小四 / 标题黑体 / 1.5 倍行距)、目录(加 `--toc`)、"
|
||||||
f"表格、`` 居中插图 + 图题编号、mermaid 图。已加载 proposal / paper 等 skill 时"
|
f"表格、`` 居中插图 + 图题编号、mermaid 图。已加载 proposal / paper 等 skill 时"
|
||||||
f"按其 render 指引的 profile 走(更具体),通用报告用 `--profile report`。\n"
|
f"按其 render 指引的 profile 走(更具体),通用报告用 `--profile report`。\n"
|
||||||
|
|
|
||||||
|
|
@ -241,9 +241,9 @@ def save_source(workspace_dir: Path, user_id: UUID, name: str, filename: str, da
|
||||||
|
|
||||||
_KB_CONTRACT = """\
|
_KB_CONTRACT = """\
|
||||||
用法规矩:
|
用法规矩:
|
||||||
- **路由**:找**材料学科学术文献**优先 `document_search`(院内共享大库);查**用户自建
|
- **主动查阅**:回答前先扫一眼下方各库条目,标题 / 摘要 / 关键词与用户问题相关就先
|
||||||
资料**(个人上传的规范 / 报告 / 标准 / 内部文档)用下面的知识库 —— 先看各库 INDEX
|
`read` 对应 `docs/*.md` 正文再作答(量大时 `grep` 先缩范围)。**无需用户点名
|
||||||
条目定位,再 `read` 对应 `docs/*.md` 正文,量大时 `grep` 先缩范围。
|
"知识库"** —— 用户资料里可能已有的内容,宁可多查一次,不要凭空回答。
|
||||||
- **答题标来源**:引用了哪个库哪篇就在回答里注明(标题或文件名)。
|
- **答题标来源**:引用了哪个库哪篇就在回答里注明(标题或文件名)。
|
||||||
- **对话内入库**:用户在对话里给了值得长期留的资料时,可直接写入:原件放
|
- **对话内入库**:用户在对话里给了值得长期留的资料时,可直接写入:原件放
|
||||||
`sources/`(没有原件就跳过)、正文转成 markdown 写 `docs/<slug>.md`、再往该库
|
`sources/`(没有原件就跳过)、正文转成 markdown 写 `docs/<slug>.md`、再往该库
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue