Skip to content

知识库检索(Tier B)—— 分块、父子、混合检索 ​

读者:要把「文档进知识库 → Agent 能引用章节」接到自己 SaaS 上的建设者或 AI coding agent。 状态基准:2026-09-03。结构感知分块、父子两级检索、hybrid 双路召回、chapter_path 面包屑均已实装。存量 KB 标 legacy,不 rebuild 则行为不变。 活契约:本节 curl 对齐当前 FastAPI 请求体(KnowledgeBaseCreateIn / KnowledgeSearchIn)。仓库 openapi.yaml 里知识库创建 schema 仍带 scope/slug 等设计意向字段,不要照抄那份创建体。 鉴权:建设态用管理面 JWT(knowledge:create / knowledge:ingest / knowledge:debug / knowledge:rebuild)。运行态检索由会话内置工具 kb_search 完成,接入方不直接调 search。


0. 心智(30 秒) ​

上传文档 → 按 KB 冻结的 chunk_strategy 切块
         → 子块建向量;父块 = 章节文本、不建向量
         → 检索命中子块后上卷父块(单次结果有体量预算)
         → hit 带 chapter_path(章节面包屑);legacy 库为 null
绑到会话 Agent 的 bindings.knowledge_base_ids 后,模型经 kb_search 取上下文

改分块策略不会立刻重切已有文档:chunk_strategy 冻结的是「下一次 rebuild 用什么」。要看到新策略,必须显式 rebuild。


1. 创建知识库 ​

bash
curl -sk -X POST "$BASE/api/v1/builder/knowledge-bases" \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{
    "project_id":"'$PROJECT_ID'",
    "name":"退款政策",
    "description":"售后与退款FAQ",
    "embedding_model_id":"'$EMBED_MODEL_ID'",
    "embedding_dim":1536,
    "chunk_strategy":{
      "strategy":"auto",
      "min_chars":256,
      "max_chars":768,
      "overlap_chars":96
    }
  }'
# → Envelope.data.id = KB_ID
#   embedding_model_id / embedding_dim 写入后冻结;换模型 = 新建 KB

约束(照抄会 422):

字段实装口径
project_id必填 UUID(KB 挂项目,不是租户级 slug)
embedding_model_id已注册的 embedding 模型 UUID
embedding_dim必须 1536(当前基线;其它维度直接拒)
chunk_strategy可省略;省略则管线用默认。写入后改策略只影响下次 rebuild
strategyauto | by_section | by_paragraph | fixed

auto:按 markdown 标题切 section,section 内按中英分句符合并,不跨标题。by_section / by_paragraph / fixed 顾名思义。中文分句符(。!?;)会保留,不会被吞成空格硬切。

存量、未写策略的 KB:chunk_strategy.strategy = "legacy"。它们继续走旧切法,直到你 PATCH 策略并 rebuild。


2. 上传文档与 rebuild ​

建设台(web-builder → 项目 → Resource Modeling → Knowledge Bases)或 API:

  • 登记 / 上传文档:POST /api/v1/builder/knowledge-bases/{kb_id}/documents(multipart 上传或登记外部源)
  • 支持文件类型(实装白名单):txt / markdown / json / csv / pdf
  • 异步流水线:pending → queued → parsing → chunking → embedding → completed(失败可 retry)
  • 全库重切:POST /api/v1/builder/knowledge-bases/{kb_id}/rebuild(staging 版本 + 原子切换;大库耗时与内存随文档量上升,先在小库试)

调试预览分块:GET .../documents/{document_id}/chunks,预览项含 chapter_path。


3. 调试检索(建设态) ​

bash
curl -sk -X POST "$BASE/api/v1/builder/knowledge-bases/$KB_ID/search" \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"query":"七天无理由退款要多久处理?","top_k":5,"hybrid":true}'

请求体(KnowledgeSearchIn):

字段含义
query必填
top_k1~50,默认 4
score_threshold可选;hybrid=true 时作用在融合分上
hybrid默认 false = 纯向量。true = 向量 + CJK bigram 全文双路,RRF(k=60) 融合

每条 hit:

json
{
  "chunk_id": "...",
  "document_id": "...",
  "chunk_index": 0,
  "content": "……章节或段落文本……",
  "score": 0.81,
  "chapter_path": "售后政策 / 退款 / 七天无理由",
  "metadata": {}
}
  • chapter_path:结构感知分块的章节面包屑;legacy 库为 null。
  • 父子检索:命中的是子块向量;返回内容按父块上卷、同父合并。单次工具结果有体量预算(约 16KiB),超限按命中子块邻域截断,避免撑爆轮次 token 护栏。
  • rerank:平台侧可对融合结果再排;计量写入 cost_records(call_kind=rerank)。接入方无新扣点字段。

4. 绑到会话 Agent ​

发布会话 Agent 时把 KB 放进 bindings.knowledge_base_ids(可多库)。发布体对齐活着的 AgentPublishIn,与 hello-agent §10.1 / cookbook §3 同一形状:

json
"bindings": {
  "primary_model_group_id": "<GROUP_UUID>",
  "knowledge_base_ids": ["<KB_UUID>"],
  "skill_ids": [],
  "tool_ids": []
}

运行时模型调用内置 kb_search。工具输出每条含 content 与 chapter_path,便于引用「来自哪一节」。接入方不要自己再打建设态 search——会话通道已经包好。

chat-dry-run 的配置读数含 kb_count,发布前可确认绑定生效。


5. 给产品经理的预期 ​

现象原因处置
中文长文检索像「切碎的字」仍是 legacy 切法PATCH chunk_strategy 为 auto 后 rebuild
hit 没有章节名chapter_path 为 null同上;或文档本身没有标题结构
换了策略但检索没变策略只作用于下次 rebuild显式 rebuild,等 staging 切到 active
一轮里 Agent「看到的」被截断父子上卷触达体量预算缩小查询、拆 KB、或接受截断(护栏优先于灌全文)
hybrid=true 仍偏向量CJK bigram 是零依赖起步,不是 jieba 级分词对专名 / 货号类查询更有帮助;不够再走后续分词升级

6. 相关页 ​