feat(knowledge): 分类过滤与多模态打通到工具/插件边界

- internal/sdk:KnowledgeAPI 增加 SearchIn/AddWithMedia/AttachMedia/
  ReindexDense/DenseStats;新增 MediaAPI(Put/Stat/Get)与 PluginSDK.Media(),
  registry 装配。**公开 SDK 契约一字未动** —— third_party/homeagent-sdk/sdk/
  的 diff 恒为 0(发布纪律的硬约束),走 internal/sdk 这条明确不受冻结约束
  的内部扩展路径。
- proc:新增 knowledge.addWithMedia(正文与媒体清单都走共享内存,与
  doc.insertWithMedia 同形);knowledge.search 支持 category。
- corehandler 用**局部接口 + 类型断言**取扩展能力,而非直接引 internal/sdk:
  后者已依赖 internal/plugin 的类型,直接引会成环(CoreSDK 注释已警示)。
  断言失败明确报"能力不可用",不静默退化成"媒体已写入"。
- agent 工具面:knowledge_search 增加 category;knowledge_create 增加
  media_digests(复用 doc_commit 的 digest 前缀解析 + Stat 回读 MIME)。
  顺带修 knowledge_search 的分类前缀重复(Name 已含分类,旧代码又拼一次,
  实测输出 tech/go/tech/go/并发)。
- agent 启动接线多模态空间,顺序为先接线再 ReindexDense(否则首次启动
  算出的向量因 MediaStore 未就绪而不落盘)。
This commit is contained in:
JianFeeeee
2026-09-26 11:36:55 +08:00
parent 0dcb335cf3
commit 2176917466
13 changed files with 404 additions and 24 deletions

View File

@ -335,6 +335,22 @@ func New(cfg AgentConfig) *Agent {
cfg.DocStore.SetDenseSpace(cfg.MultimodalSpace)
cfg.DocStore.BuildDenseIndex(cfg.MultimodalSpace)
}
// 知识库接入同一多模态空间:媒体作为一等节点参与稠密召回,
// 于是「按图搜知识」「按文搜含图知识」成立。
//
// 稀疏两路(词向量 + TF-IDF)**保持启用**且仍是主召回路径:多模态
// 空间未配置时知识库行为与此前逐字一致(退化为 0.5/0.5 两路融合)。
if cfg.Knowledge != nil {
// 顺序要紧:先接线(含 MediaStore),再重建。ReindexDense 会
// 尝试从 .dense.json 缓存恢复,恢复不了才重算,最后把结果落盘。
// 若先重建后接线,首次启动算出的向量会被丢掉而不落盘。
cfg.Knowledge.SetDenseSpace(cfg.MultimodalSpace)
cfg.Knowledge.SetMediaGetter(cfg.MediaStore)
built, skipped := cfg.Knowledge.ReindexDense()
if built > 0 || skipped > 0 {
log.Printf("[knowledge] 多模态稠密索引: 新建 %d 跳过 %d(其余命中缓存)", built, skipped)
}
}
}
a := &Agent{