跳到主要内容

WeKnora ReAct Agent 与三大能力:从检索问答到自主推理

· 阅读需 9 分钟
一介布衣
全栈开发者

前三篇我们一路沿着数据流走下来:架构分层、文档怎么被解析分片、检索管线怎么把内容捞出来排序。但这些都还停留在「RAG」的范畴——用户问一句,系统检索一次、答一句,是被动的。

WeKnora 真正想做的不止于此。它在检索之上搭了一个 ReAct Agent,让系统能自己规划多步任务、调用工具、写代码、开浏览器、还能把一堆原始文档蒸馏成一个自维护的 Wiki。这是系列收官篇,我们看看问答之上的这层「自主推理」是怎么组织的,也顺便给整个 RAG 全链路收个口。

三大能力:一张递进的地图​

回顾第一篇提到的三个核心能力,它们其实是递进关系:

  • RAG Quick Q&A:最基础,走前三篇讲的那条 12 阶段检索管线,一问一答。
  • ReAct Agent:进阶,能自主编排工具、多步推理、处理复杂任务。
  • Wiki Mode:最上层,让 Agent 主动把文档提炼成结构化、互链、可演进的知识库。

RAG 是「你问我答」,Agent 是「你给目标我自己想办法」,Wiki 是「我帮你把知识重新组织好」。下面重点拆 Agent 这条线。

ReAct:推理与行动的循环​

ReAct = Reasoning + Acting。它的核心是一个循环:模型先思考(我现在该干什么)、再行动(调一个工具)、拿到观察(工具返回结果)、再基于观察继续思考……如此往复,直到任务完成。

这和 RAG 的本质区别在于:RAG 的流程是系统预先编排好的(那条固定装配的管线),而 Agent 的流程是模型在运行时自己决定的——调哪个工具、调几次、按什么顺序,都由模型根据当前状态判断。

WeKnora 的 Agent 编排在 internal/application/service/agent_service.go + internal/agent/ 下。它给模型挂了一整套工具,模型通过 function calling 选择使用。工具注册在 internal/agent/tools/registry.go 的 ToolRegistry 里。

工具生态:Agent 的手脚​

internal/agent/tools/ 下有上百个文件,暴露给模型的工具(工具名就是源码里的常量)大致分几类:

类别工具作用
知识检索search_knowledge / read_document / list_documents第三篇讲的混合检索,Agent 可反复调用
图谱/会话query_knowledge_graph / search_conversations查知识图谱、检索历史会话
记忆search_memory检索跨会话长期记忆
数据分析database_query / data_analysis / data_schema用 DuckDB 对结构化数据做查询分析
网页web_search / web_fetch / read_file联网搜索、抓取网页
沙箱文件list_sandbox_files / write_sandbox_file / edit_sandbox_file读写沙箱里的文件
命令执行shell_exec在沙箱里跑 shell 命令
技能文件write_skill_file / edit_skill_file编写/修改技能脚本
MCPdiscover_mcp_tools / call_mcp_tool发现并调用外部 MCP 工具
推理规划thinking / todo_write顺序思考、写任务清单
Wikiwiki_read_page / wiki_write_page / wiki_replace_text / wiki_rename_page / wiki_search …读写 Wiki 页面
flowchart TD
U["用户目标"] --> AG["ReAct Agent<br/>推理-行动循环"]
AG -->|"search_knowledge"| KB["知识库检索"]
AG -->|"shell_exec / 文件工具"| SB["沙箱<br/>Docker/E2B/Cube"]
AG -->|"discover/call_mcp_tool"| MCP["MCP 外部工具"]
AG -->|"BrowserSkill"| BR["用户自己的浏览器"]
AG -->|"web_search / web_fetch"| WEB["网络"]
AG -->|"search_memory"| MEM["长期记忆"]
AG -->|"wiki_write_page"| WK["Wiki 知识库"]
KB --> AG
SB --> AG
MCP --> AG
BR --> AG
WEB --> AG
MEM --> AG
AG --> R["带引用的最终答案/产物"]

这里有个设计细节值得一提:ToolRegistry 除了 RegisterTool,还有一个 RegisterDeferredTool——注册一个「有执行能力但不主动广告给模型」的工具。MCP 工具就是这么处理的:模型先用 discover_mcp_tools 按需发现有哪些可用工具,再决定调哪个。这避免了把几十上百个 MCP 工具一股脑塞进 prompt、撑爆上下文。

沙箱:让 Agent 安全地跑代码​

Agent 能 shell_exec、能写文件,就意味着它能执行任意代码——这非常危险。WeKnora 的解法是把执行关进会话级持久化沙箱:

  • 三种后端:Docker / E2B / Cube,都是隔离的执行环境(v0.8.0 起移除了本地 host-process 后端,Docker 改成显式 opt-in)。
  • 会话持久化:沙箱在一个会话内保持不变,Agent 上一步写的文件、装的依赖,下一步还在。这对多步任务至关重要。
  • 每租户网络策略:可以按配置限制沙箱的出网范围,甚至有「白名单出网模式」(SSRF_DNS_WHITELIST_ONLY)。
  • 交互能力:v0.8.2 还给沙箱配了交互式终端和图形化桌面,用户能直接看 Agent 在里面干什么。

macOS 桌面版有个特别的做法:没有固定沙箱时,会话跑在操作系统级的 Seatbelt 沙箱里(internal/localsandbox/seatbelt/),绑定到用户选的项目文件夹或一个按日期命名的临时工作区。

BrowserSkill:借用用户自己的浏览器​

v0.8.2 的一个亮点是 BrowserSkill(internal/agent/tools/browserskill*.go + internal/browserskill/)。它让 Agent 通过一个开源浏览器扩展,驱动用户自己的 Chrome / Edge:打开网页、点击、填表单、读内容。

关键设计是「人在环上」:任务在一个专门的窗口里实时预览,可以暂停/恢复/结束;遇到登录、验证码这种需要真人的环节,可以交接给用户处理,处理完再交回 Agent。这比无头浏览器方案更实用——它复用了用户已登录的会话和身份。

长期记忆:Agent 会记住你​

search_memory 背后是 WeKnora 的跨会话长期记忆(v0.8.0 引入)。它把记忆分成几类:profile(画像)/ preference(偏好)/ fact(事实)/ task(任务)/ interest(兴趣)。

工作方式是「自动抽取 + 用户确认」:Agent 从对话里识别出值得长期记住的信息,经用户确认后存入;后续对话需要时,通过 search_memory 按需召回。这让 Agent 不再是每次对话都失忆的一次性工具,而是能积累对用户了解的助手。(有意思的是,v0.7.1 还移除了早期基于 Neo4j 的对话记忆依赖,换成了更轻的实现。)

Wiki Mode:让知识自己长出来​

最高层的能力是 Wiki Mode。它不是简单地把文档存起来,而是让 Agent 主动把原始文档蒸馏成一个结构化、互相链接的 Markdown 知识库,还配一个交互式知识图谱。

支撑它的是一整套 wiki_* 工具:wiki_write_page(写页面)、wiki_replace_text(改内容)、wiki_rename_page(重命名)、wiki_link_mutation(维护页面间的双向链接)、wiki_flag_issue / wiki_read_issue / wiki_update_issue(标记和处理知识缺口)。

更关键的是它可演进:支持浏览器内手工编辑、页面修订历史、行级 diff、一键回滚。知识库不是一次性生成的死文档,而是一个能持续维护、有版本、能追溯的活资产。这正好呼应了整个系列的主题——把散落的文档变成「可查询、能推理、会持续演进」的知识。

平台层:撑起企业级的那部分​

Agent 能力之外,WeKnora 还有一层容易被 demo 项目忽略、但企业落地必需的东西:

  • 多工作区 RBAC:4 级角色矩阵(Owner / Admin / Contributor / Viewer)+ 每资源归属 + 每工作区审计日志。
  • 多数据源接入:飞书 / Confluence / GitLab / Notion / 语雀 / 钉钉文档 / RSS,支持增量和全量同步。
  • 多 IM 渠道:企业微信 / 飞书 / Slack / Telegram / 钉钉 / QQ 机器人等,直接在 IM 里问答。
  • 可观测性:Langfuse 作为唯一的 tracing 后端,记录 ReAct 循环、token 用量、工具调用和完整管线 trace;还有系统管理员的运行时任务队列看板。
  • 任务队列治理:MQ 异步任务 + 按阶段的 worker-pool 治理(core / post-process / enrichment / maintenance + 弹性共享池 + 独立 Wiki 池)。
  • 安全:API Key 和凭据用 AES-256-GCM 静态加密、gRPC TLS、SSRF 防护、密钥脱敏。

这些不是花哨功能,而是「能不能真的上生产」的分水岭。

系列总结:一条完整的 RAG 全链路​

四篇走下来,WeKnora 的全貌已经清晰。用一条数据流把它串起来:

  1. 架构全景:纵向六层数据流 + 横向可插拔基座,Go 主后端 + Python 解析 sidecar 用 gRPC 划清边界。
  2. 分片机制:文档画像 → 三层策略 → 结果校验 → 逐级回退的自适应框架,配父子分块和 ContextHeader 解决粒度与语境。
  3. 检索管线:PipelineBuilder 按需装配的事件驱动管线,混合召回 → rerank → merge → MMR 层层收敛。
  4. Agent 能力:在检索之上用 ReAct 循环编排工具、沙箱、浏览器、记忆和 Wiki,从「被动问答」进化到「自主推理」。

如果要用一句话总结 WeKnora 值得学的地方:它没有发明什么新算法,而是用扎实的工程把 RAG 全链路的每个环节都做成了可插拔、可观测、可自我纠错的模块。分片有 Validator 降级、检索有分层收敛、执行有沙箱隔离、知识有版本回滚——正是这些「工程上的认真」,区分了一个能上生产的框架和一个跑通就算的 demo。

对想深入 RAG 工程的人,WeKnora 是一份难得的、足够复杂又足够规整的参考实现。它的代码就在 github.com/Tencent/WeKnora,MIT 协议,值得 star 一份慢慢读。

系列导航:

  • (一)架构全景:Go 与 Python 双引擎
  • (二)自适应分片机制:三层策略与父子分块
  • (三)RAG 检索管线:12 阶段 Pipeline 剖析
  • (四)ReAct Agent 与三大能力 ← 本文
  • (五·番外)向量库可插拔抽象