v1.2.0 回答了两个问题:检索做得够不够好?agent 用起来顺不顺?第一个问题的答案是「够了,而且有证据」——四条最直觉的优化路线全部被对照实验排除;第二个问题的答案是这一版的主特性:把检索结果做成 agent 友好的渐进披露形态,并补上环境发现能力。
检索质量闭环:四条路线的实验裁决
这个周期我们把评测体系扩展到无结构连续文本(中文会议转写,VCSUM 数据集,make eval-vcsum),然后跑了一串单变量对照实验,每条结论都有同指纹报告背书(RETRIEVAL_BENCHMARK.md):
- 语义分块正式排除:用人工话题边界伪造「完美语义切分」语料做 oracle 实验,切点完全对齐的上限增益只有 ±2 个百分点——任何语义分块实现都不可能超过这个上限,方向关闭;
- LLM 上下文头生成不立项:人工话题标题做上下文头能把指标推到上限(+7.9pp 向量 / +36.7pp FTS),但本地 7B 与云端 DeepSeek 两档生成版都只吃到 FTS 增益的百分之十几,模型跨档而结果不动——瓶颈是摘要措辞与提问措辞的错位,不是模型能力;
- 繁简归一化关闭:实测对 hybrid/rerank 零收益(向量通道本就免疫繁简),长文档轨的剩余落差 100% 归属文档内章节竞争;
- 最终结论:段落级检索 98%、无结构长文档 94%(rerank 开启),推荐配置就是 hybrid + rerank。
检索渐进披露:detail: full | lean
此前一次 knowledge_search 返回 top 10 × 完整父块正文,一次调用约 4~5 万字符,agent 的上下文窗口被迅速污染。现在检索支持两档响应(REST 与 MCP 均默认 full,lean 显式选择):
full:完整父块正文 + 命中子块元数据(现状行为的超集);lean:每个命中只返回最佳命中子块正文(evidence,即”为什么命中”的即时证据),父块正文置空、chunk_id保留作钻取句柄——配合现有的chunk_get,agent 先扫证据、再按需取完整上下文。
实测 lean top 10 序列化体积约为 full 的三分之一(13.7k 对 41k+ 字符)。这是 Claude Code Grep/Read 同款的渐进披露模式:先给「在哪、为什么命中」,再让 agent 决定读什么。
破坏性变更:matched_children 不再携带子块正文
matched_children[].content 从 REST/MCP 契约中移除。它是构造性冗余——琅嬛的父块就是子块按序拼接而成,子块正文永远是父块正文的子串,在 full 档下纯属重复传输。位置标记、chunk_id 与通道分数等元数据全部保留。需要子块正文的调用方改用 detail=lean 的 evidence 或 chunk_get。
MCP 发现类工具:7 → 10
agent 被接入一个 workspace 后,现在可以自己搞清楚环境里有什么:
knowledge_base_list:列出有权访问的知识库;document_list:分页浏览库内文档(标题/类型/状态);document_get:读一篇文档的归一化全文与章节大纲(max_chars截断保护)。
全部只读、复用现有 service,零 schema 迁移。至此 agent 的完整工作循环是:发现(list)→ 检索(search lean)→ 细读(document_get / chunk_get)→ 再检索。
验证
go test ./...(50 包)、make test-integration(51 包,临时 docker PostgreSQL)、Web Console pnpm check / test / build(333 个测试)全部通过;两档 detail 的排序一致性、lean 体积预算、契约字段移除均有专项断言。