feat(knowledge): 新增 query_keywords 工具,基于关键词命中的 BM25 检索 - #769
feat(knowledge): 新增 query_keywords 工具,基于关键词命中的 BM25 检索#769xiangfei258 wants to merge 2173 commits into
Conversation
- 新增 install_skill 工具,支持从 Sandbox 路径或 Git 仓库安装 skill - 支持管理员权限校验(admin/superadmin) - 安装后自动持久化到 agent config,新对话自动生效 - 动态激活当前会话,无需重启 - 新增 AgentConfigRepository.add_skills_to_config_json() 原子 JSONB 操作 - 新增 21 个单元测试,覆盖权限、Schema、安装流程等场景
- 将 install_skill 改为 async def,消除 asyncio.run() 事件循环冲突 - 修复 agent_config_repository 表名及 jsonb 类型转换 - 增加数据库连接池配置,避免高并发耗尽连接 - 修复远程 skill 批量安装列表引用共享 bug - 修复 slug 冲突 warning 误报(目录名 vs SKILL.md name) - 新增 UserRepository 支持外部传入 db 会话 - 更新测试适配 async 签名
- 修正 AgentConfigRepository 技能写入路径,确保技能保存至 config_json->context->skills - 修复 test_install_skill 单元测试的各种 mock 与断言,解决由于接口变更和依赖不匹配导致的失败
- 拆分技能安装流程,避免慢速拉取阶段占用数据库连接 - 使用 ORM 读改写并加行锁追加 agent 配置 skills,避免重复和并发丢更新 - 强化沙盒目录下载错误处理并补充相关单元测试
1. 修复 mention_router 中的 IDOR 越权安全漏洞,加入 thread 归属权校验,定义强类型 Pydantic Schema。 2. 修复 mention_search_service 中 ensure_thread_dirs 的 GET 副作用、空 Query 扫描和 MAX_SEARCH_DEPTH 深度问题,使用标准 Base64 编解码。 3. 增加前端 mention_api.js 参数的安全兜底。 4. 重构 AgentPanel 自动展开策略,彻底解决大仓库克隆时的卡死问题: - 将 fetchThreadFiles 改为 recursive=false 避免递归大目录。 - 重构为只有在发生显性的物理文件写入(用户上传附件成功、用户保存交付件到工作区成功)的回调中才精准触发侧边栏自动展开,完美契合用户心智模型与性能诉求。 5. 精简 roadmap.md 文档,更新相关单元测试。
…stall feat(skills): 支持远程安装搜索、仓库历史记录与批量删除
- 默认的知识库类型新增图谱抽取能力 - 移除 LightRAG 以及原有的知识图谱支持 - 移除所有兼容性的代码
- 更新了 KnowledgeBaseManager 以支持新的文件管理方法。 - 在 workspace_router 中为知识库文件操作新增了端点,包括文件树列表、文件预览和文件下载。 - 在 workspace_api.js 中添加了相应的 API 调用,用于知识库交互。 - 增强了 AgentFilePreview 组件,支持预览变体之间的切换。 - 更新了导航逻辑,重定向至知识管理标签页,而非数据库视图。 - 修改了 WorkspaceView 以处理知识库条目和预览,包括加载和展示知识文件。 - 通过在文件操作期间提供加载与错误状态的反馈,改善了用户体验。
- 新增 MilvusGraphVectorStore 和 KnowledgeGraphRepository - 新增文件大小从 MinIO 补全的逻辑(上传时 + 启动时) - 重构 FileTable、GraphDetailPanel、KnowledgeGraphSection 等前端组件 - 新增文件大小回退测试和 kb_utils 测试 - 优化 file_utils 工具函数 - 更新 roadmap 文档
- 新增 MilvusRetrievalConfig 数据类,支持向量/关键词/混合/图检索参数化配置 - 新增 query_seed_subgraph 和图检索融合逻辑 - MilvusGraphVectorStore 新增 search_entities/search_triples - MilvusGraphService.get_status 支持构建任务状态与进度查询 - cypher 语句增加 entity_id/triple_id 属性 - 前端 KnowledgeGraphSection 和 SearchConfigModal 适配新配置 - 新增 igraph 依赖
- LLM 抽取器收敛为固定 Prompt + 可选 Schema 约束,禁止自定义完整 Prompt - 图谱构建改用 asyncio worker 队列并发,并发数由 extractor_options.concurrency_count 控制 - 已锁定的图谱配置允许修改同类参数,类型保持锁定 - OpenAIBase 透传 model_params 到流式和非流式调用
- update_kb_config 不再触发全量 _save_metadata,避免内存 metadata 覆盖数据库已有图谱配置 - 补全文件大小时改用 _persist_file 逐文件写入 - delete_file_chunks_only 通过 chunk_repo 检查文件是否有图谱数据再决定是否清理
- _find_query_target 返回 db_id 供检索结果标注来源 - _normalize_retrieval_result_metadata 新增 resource_id 参数写入 metadata
- 抽取器类型改为卡片式选择,未配置时在图谱画布上显示配置入口 - LLM 抽取器支持 Schema 约束、并发队列数和模型参数 JSON - 已锁定配置允许修改同类型参数,类型本身保持锁定 - GraphCanvas 修复 resize 时尺寸为零的问题,resize 后延迟 fitView - 索引管理面板增加刷新按钮与修改配置入口
- 工具调用折叠栏简化按钮样式,调整缩进与间距 - ListKbsTool 紧凑内边距 - BaseToolCall loader 颜色调整 - FileTable 溢出菜单宽度统一
- LLM 抽取器测试:禁止自定义 Prompt、Schema 拼接、配置锁定修改 - metadata 持久化测试:验证 _save_metadata 不覆写数据库已有图谱配置 - 检索测试:验证 resource_id 写入 metadata - roadmap 补充图谱抽取器配置优化条目
之前编辑误将 MCP 环境变量修复条目与 HTML 预览 iframe 高度修复 条目拼接为一行,且吃掉了 HTML 条目开头描述。现拆分为两条独立 记录并补回完整描述。
…rogress fix: 修复知识库文档处理任务状态不一致与进度跳变问题
…y-input fix: 修复添加/编辑 MCP 弹窗环境变量无法新增的问题
创建知识库时将已归一化的 share_config 和 created_by 随首次知识库记录插入写入数据库,避免创建后再二次更新带来的短暂不一致。 Fixes: xerrors#763
将 yuxi.models 的模型选择导出改为惰性加载,并延迟读取全局 knowledge_base 实例,避免热重载和单测导入阶段触发循环导入。
将 web 与 docs 的 esbuild 锁定到 0.28.1,修复 Dependabot 高危告警;docs 同步升级 Vite/plugin-vue override 以兼容 patched esbuild;web 补充 brace-expansion override 清理 npm audit 中的中危告警。
1. 旧导图兼容bug:kb.mindmap_file_ids 为空时从叶子节点反推文件映射, 避免原有文件下次被误判为新增 2. 移除删除接口中的导图清理调用,导图是否过期由 diff 接口判断, 用户点击增量更新时再统一处理 3. changelog 条目移至 v0.7.1 开发记录顶部,移除文件删除自动清理导图描述
…remental-update # Conflicts: # docs/develop-guides/changelog.md
图例 type 设为 scroll 约束为单行并显示翻页箭头,解决智能体数量多时图例换行侵占图表区域的问题。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
图例 type 设为 scroll 约束为单行并显示翻页箭头,同时设置 pageIconColor/pageIconInactiveColor 保证暗色模式下翻页箭头清晰可见,与图例文字颜色风格一致。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…mental-update feat: 优化思维导图构建接口,支持增量构建和更新
fix(web): 智能体调用统计图例过多时启用滚动模式,避免挤压坐标轴
There was a problem hiding this comment.
Code Review
This pull request introduces a new query_keywords tool to the knowledge base toolkit, enabling keyword-based (BM25) searches as a complement to semantic search. The changes include the definition of the QueryKeywordsInputSchema input model, comprehensive unit tests for the new tool, and updates to the project's changelog and roadmap. The feedback suggests improving the robustness of the query_keywords tool by filtering out empty or whitespace-only strings from the keywords list before performing validation.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| if not keywords: | ||
| return "请提供关键词列表" |
There was a problem hiding this comment.
为了提高工具的鲁棒性,建议在检查 keywords 之前先过滤掉空字符串或仅包含空格的无效关键词。否则,如果传入 ["", " "] 这样的参数,虽然能绕过 if not keywords 的检查,但后续拼接出的 query_text 将为空或仅包含空格,从而导致检索异常。
通过列表推导式过滤无效关键词可以有效避免这一问题。
| if not keywords: | |
| return "请提供关键词列表" | |
| keywords = [k.strip() for k in keywords if k.strip()] | |
| if not keywords: | |
| return "请提供关键词列表" |
- 新增 QueryKeywordsInputSchema,接收 keywords 列表 - 新增 query_keywords 工具函数,强制 search_mode=keyword 走 BM25 通道 - 过滤空字符串和纯空格关键词,避免检索异常 - 注册到 get_common_kb_tools(),Agent 可自动发现 - 更新 changelog 和 roadmap
5f4945f to
faccf70
Compare
|
关键词检索其实不仅仅是这个意思,这里想要弥补的短板是精准匹配,类似于 grep 这种,但是知识场景和代码场景不同,又要有一定的模糊匹配。所以我初步的设想就是:
这里 bm25 是由 milvus 本身支持的,不需要做太多工作。但是精准匹配我不确定 milvus 是否支持,如果不支持,如何保证性能的同时完成检索,也需要考虑进去。 |
|
感谢反馈,你说得对,当前 BM25 确实无法保证精准子串匹配排在前面。 我查了一下,Milvus 2.6+ 新增了 # slop=0 精准短语匹配,作为 filter 筛选出包含完整短语的 chunk
filter = "PHRASE_MATCH(content, \"扭转减振器\", 0)"
# 配合 BM25 做排序
collection.search(
data=[query_text],
anns_field="content_sparse",
param=bm25_search_params,
limit=50,
expr=filter,
output_fields=output_fields,
)对应你的三个需求:
但目前项目用的 Milvus 是 v2.5.6, 所以这个功能的完整实现需要升级 Milvus 到 2.6+,想听听你的想法。 |
|
版本升级是没关系的,只要正常的功能都还在就行 |
按作者评审反馈,query_keywords 此前纯 BM25 无法保证精准命中排前。改为基于 Milvus 2.6 PHRASE_MATCH 实现「精准优先 + BM25 兜底」检索策略: - 升级 Milvus v2.5.6 -> v2.6.16(etcd v3.5.25 / minio RELEASE.2024-05-28), 同步更新 compose 与镜像拉取/打包脚本;客户端 pymilvus 已锁 3.0.0 无需动。 - KB 与图谱 content 字段新增 enable_match=True 以支持 PHRASE_MATCH。 - _collection_supports_bm25 增加 enable_match 自检:存量 KB 集合首次访问时 自动 drop 重建+重索引(懒触发、按 KB);图谱集合仅对新建生效(图谱检索纯 向量、不用 PHRASE_MATCH,重建需重跑 LLM 抽取,成本不成比例)。 - aquery keyword 分支重写:PHRASE_MATCH 过滤的精准命中在前(BM25 降序), 不足 final_top_k 时纯 BM25 兜底,按 chunk_id 去重;新增 expr 构造 helper (转义防注入、多关键词 or 连接)、_merge_precise_and_backfill。 - _build_chunk_from_hit 新增 is_precise_match 标记写入 metadata(build_search_output 仅透传 metadata,故标记须放 metadata 才能存活到工具输出)。 - query_keywords 传 precise_match/phrase_match_terms,并过滤空/纯空白关键词。
|
按 @xerrors 老师的反馈重做了 本次改动检索策略:精准优先 + BM25 兜底(对应老师三条要求)
多关键词走 Milvus 升级 2.5.6 → 2.6.16(etcd v3.5.25 / minio RELEASE.2024-05-28),6 个文件(2 compose + 2 init 脚本 + 2 打包脚本)同步。客户端 pymilvus 本就锁 3.0.0,升级服务端是补齐而非引入错配。已起 2.6 实测: schema + 存量自动重建:KB 与图谱 content 字段加
|
|
关于 embedding 重建这里需要慎重考虑,对于大型系统来说,自动触发重建的成本开销。需要确认重建是否需要重新计算 embedding?为什么不是从原始的 embedding 迁移过去?这个需要确认。 另外是 Codex 发现的问题:
|
按评审反馈调整存量集合升级策略并修复 Codex 指出的正确性问题: - 向量迁移替代空重建:存量集合自检缺 enable_match 时,drop 前用 query_iterator 读出全量 embedding 原样回灌新集合,不重算; content_sparse 由新集合 BM25 Function 自动生成,迁移后 flush 保证 PHRASE_MATCH 倒排可见。embedding 模型变更分支仍走重算不迁移。 - 修复 or/and 优先级:多关键词 PHRASE_MATCH 的 or 子句整体加括号, 避免与 file_name 的 and 拼接时 file_name 仅约束首个关键词。 - 修复重排前截断:keyword 分支 _merge_precise_and_backfill 改传 recall_top_k 而非 final_top_k,开启重排/图检索时候选池不再失效。 - 补齐 enable_match 自检单测 fixture,新增迁移/优先级/截断单测, 新增精准匹配集成测试。 测试:test_milvus_kb 22 + test_kbs_tools 12 + 集成精准匹配 2 全绿
|
@xerrors 老师反馈已按你的思路重做,commit 改动1. 向量迁移替代空重建(回应「为什么不从原始 embedding 迁移」) 2. Codex 指出的三处已修
单测 34(milvus_kb 22 + kbs_tools 12)+ 集成精准匹配 2 全绿。
|
|
关于这个迁移,需要判断,如果升级后不执行迁移带来的后果是(a)系统发现 有问题,无法正常完成 KB 检索。(b)关键词检索无法生效,但是原有的检索仍可以正常使用? 如果是 A,则需要考虑更妥善的方法,这种就需要在系统启动的时候就完成检查并在日志给出提示,开发者确认后执行迁移命令。对于后者作为可以在知识库页面给出一个提示,手动完成迁移,并显示进度(tasker)。由于迁移脚本是临时的,因此建议放到一个独立的service 文件里面。 另:建议不要直接使用 Agent 提交 Comment,不然我像是在和 Agent 对话 |
变更描述
实现 roadmap v0.7.1 中的「知识库工具新增 query_keywords 工具,专门用于基于关键词命中的排序」。
新增
query_keywordsAgent 工具,接收关键词列表,走 BM25 通道检索,与query_kb的语义检索互为补充。改动内容:
knowledge/schemas.py:新增QueryKeywordsInputSchema(kb_id + keywords + file_name)agents/toolkits/kbs/tools.py:新增query_keywords工具函数,强制search_mode="keyword"走 BM25 通道,注册到get_common_kb_tools()test/unit/toolkits/test_kbs_tools.py:新增 6 个单元测试,修复旧测试_patch_retrievers的 monkeypatch 方式docs/develop-guides/changelog.md:v0.7.1 开发记录docs/develop-guides/roadmap.md:勾选已完成项测试验证:
在 Docker 环境中通过对话让 Agent 调用
query_keywords,搜索关键词「扭转减振器」,BM25 排序结果准确:精确命中的段落 score 最高,上下文提及次之,远端关联最低。{ "kb_id": "kb_om6wjcmnr1", "results": [ { "id": "file_005d51_chunk_5", "metadata": { "score": 7.05 } }, { "id": "file_005d51_chunk_0", "metadata": { "score": 3.96 } }, { "id": "file_005d51_chunk_1", "metadata": { "score": 0.97 } } ] }单元测试全部通过(16/16)。
变更类型
测试
相关日志或者截图
Agent 工具调用截图已在对话中验证通过。
说明
后续可以考虑给
query_kb也暴露search_mode参数(vector/keyword/hybrid),这样 Agent 只需选一个工具,通过参数选模式,比选两个工具的决策成本更低。底层 Milvus/Dify/Notion 已经支持这三种模式了,只是当前 schema 没暴露出来。