别再把 Agent 当成一个 Prompt:从 OpenClaw 看懂智能体系统的真正架构
摘要
很多人第一次做 AI Agent,通常会写出这样的程序:接收用户问题,拼接提示词,调用大模型,再根据模型返回的参数执行工具。
这种方案可以运行,也能演示,但距离真正可用的智能体系统还有很远。
一个能够长期运行、连接多个业务入口、拥有记忆、执行工具并保证数据安全的 Agent,背后必须有完整的基础设施,包括消息网关、会话管理、上下文组装、工具执行、记忆检索、权限隔离和状态持久化。
OpenClaw 最值得研究的地方,并不是它接入了多少聊天软件,而是它展示了一套相对完整的 Agent 工程架构。
本文不讨论安装教程,而是从系统设计角度拆解:一个真正可用的智能体平台究竟应该怎样运行。
关键词: AI Agent、OpenClaw、Gateway、Agent Runtime、上下文工程、工具调用、记忆系统、多智能体
一、真正的 Agent,不是“模型加工具”
先看一个最常见的 Agent 实现:
user_input = input("请输入问题:")
messages = [
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_input}
]
response = model.chat(
messages=messages,
tools=tools
)
if response.tool_call:
result = execute_tool(response.tool_call)
从功能上看,它已经具备三个要素:
-
能理解用户问题;
-
能选择工具;
-
能执行工具。
但它仍然只能算一个 Agent Demo。
因为一旦进入真实环境,问题会立刻出现:
-
多个用户同时发消息,怎么区分会话?
-
飞书、网页和移动端的消息格式不同,谁来统一?
-
模型可以调用哪些工具,由谁决定?
-
同一个工具被重复调用两次怎么办?
-
历史对话过长,如何压缩?
-
私聊、群聊和管理员的权限是否相同?
-
工具执行失败后,任务如何恢复?
-
整个操作过程如何审计?
这些问题都不是靠一段提示词能解决的。
因此,一个完整的智能体系统至少需要三层:
接入与控制层:Gateway
↓
智能体运行层:Agent Runtime
↓
认知模型层:LLM
大模型只是负责理解、规划和生成。
真正让 Agent 能够稳定运行的,是模型外面的那一整套运行时。
二、Gateway:智能体系统的统一入口
在一个真实的智能体平台中,用户可能从不同入口发起任务:
网页
飞书
钉钉
Telegram
WhatsApp
命令行
移动端
业务系统 API
这些渠道的协议、身份认证和消息格式都不同。
如果每一个 Agent 都直接适配这些平台,系统很快就会变成一团乱麻。
更合理的方式,是在最前面增加一个 Gateway。
飞书消息 ──┐
网页请求 ──┼→ Gateway → Agent Runtime
移动端消息 ─┘
Gateway 主要负责四件事:
-
接收消息;
-
验证用户身份;
-
找到对应会话;
-
将任务路由给正确的 Agent。
注意,Gateway 不应该负责具体的模型推理。
它更像一个机场塔台。
它不负责驾驶飞机,但所有飞机什么时候起飞、进入哪条跑道、由哪个机组处理,都必须经过塔台调度。
这也是 OpenClaw 架构中最重要的设计之一:
消息通信和 Agent 执行必须解耦。
这样做以后,新增一个飞书入口,只需要增加飞书适配器,不需要修改 Agent 的核心逻辑。
三、渠道适配器:把不同平台翻译成统一消息
每个聊天平台的消息结构都不一样。
例如,飞书可能返回一套事件 JSON,Telegram 使用 Bot API,WhatsApp 又有自己的消息协议。
但进入 Agent Runtime 之前,它们应该被转换成统一格式:
{
"channel": "feishu",
"sender_id": "user_1024",
"conversation_type": "group",
"conversation_id": "group_2001",
"text": "帮我整理今天的工作日报",
"attachments": [],
"metadata": {
"mentioned": true
}
}
这就是经典的适配器模式。
渠道适配器通常负责:
身份验证
消息解析
附件提取
访问控制
消息格式转换
回复发送
Agent 不需要知道消息来自飞书还是 WhatsApp。
它只需要处理标准化后的内部消息对象。
这套设计对于企业智能体平台尤其重要。
今天系统入口可能是网页,明天可能需要接飞书,后天又可能需要嵌入 ERP。
只要内部任务协议不变,外部入口就可以不断扩展。
四、会话不是聊天记录,而是安全边界
很多系统把 Session 理解为聊天记录的 ID。
实际上,在 Agent 系统中,会话还承担着更重要的职责:定义安全边界。
例如,可以把会话分成三类:
main:系统所有者自己的会话
dm:其他用户的私聊会话
group:群聊会话
不同会话允许执行的操作应该完全不同。
main 会话:
可以读取工作目录
可以执行命令
可以修改系统配置
dm 会话:
只能访问指定知识库
不能执行危险命令
工具必须在沙箱运行
group 会话:
只能调用公开工具
不能读取私人记忆
不能访问敏感业务数据
因此,一条消息进入系统以后,不能直接交给模型。
正确顺序应该是:
识别用户
→ 解析会话
→ 确定信任级别
→ 计算权限
→ 过滤工具
→ 执行 Agent
这条原则非常关键:
不是模型想调用什么工具,就给它什么工具,而是系统先决定它有权看到哪些工具。
模型负责做选择,系统负责划边界。
五、上下文组装:系统提示词不是一个文件
很多 Agent 项目会维护一份非常长的系统提示词。
随着功能增加,提示词越来越长:
角色定义
业务规则
工具说明
输出格式
安全要求
记忆信息
工作流程
异常处理
最后几乎所有规则都被塞进同一个 Prompt。
这种方案的问题是,无关信息会持续占用上下文,并干扰模型判断。
更合理的方式,是把系统上下文拆成多个独立部分:
基础规则
Agent 人设
当前会话历史
当前用户权限
任务相关 Skill
记忆检索结果
当前可用工具
每一轮执行时,再根据任务动态组装。
可以把它理解成一个上下文编译器:
基础指令
+ 当前 Agent 配置
+ 当前会话信息
+ 当前任务相关技能
+ 相关历史记忆
+ 可用工具定义
= 本轮模型上下文
这里最重要的一点是:不要一次加载全部 Skill。
例如用户正在处理报销,系统只需要加载报销 Skill;用户正在生成接口文档,就加载技术文档 Skill。
用户请求
↓
意图识别
↓
匹配相关 Skill
↓
动态注入上下文
这种按需注入的方式,可以显著减少 Token 消耗,也能降低提示词之间互相干扰的概率。
六、Agent Runtime:真正执行工作的地方
Agent Runtime 是整个系统中最核心的部分。
它每一轮通常要完成四个步骤。
1. 确定会话
根据用户、渠道和会话类型,确定本轮请求属于哪个 Session。
2. 组装上下文
加载:
会话历史
系统规则
Agent 配置
相关 Skill
记忆检索结果
工具定义
3. 执行模型与工具循环
模型可能不会一次性生成最终答案,而是先调用工具。
模型请求执行命令
→ Runtime 执行命令
→ 将结果返回模型
→ 模型继续推理
→ 再次调用工具
→ 生成最终答案
伪代码大致如下:
for step in range(MAX_STEPS):
response = model.generate(
messages=context,
tools=available_tools
)
if response.has_tool_call():
result = tool_executor.execute(
response.tool_call
)
context.append({
"role": "tool",
"content": result
})
else:
return response.text
raise RuntimeError("Agent 超过最大执行步数")
4. 保存状态
执行结束后,需要保存:
用户消息
模型回复
工具调用参数
工具执行结果
错误信息
耗时
最终状态
所以 Agent Runtime 本质上不是一段简单循环,而是一个受约束的状态机。
它必须考虑:
-
最大执行步数;
-
单个工具超时;
-
整体任务超时;
-
工具重复调用;
-
参数校验失败;
-
模型进入循环;
-
中断后的任务恢复。
七、工具调用真正的难点,是控制副作用
查询天气、读取文件、搜索知识库,这些工具即使重复调用,通常也不会产生严重问题。
但下面这些操作不同:
发送邮件
提交报销
创建订单
修改数据库
删除文件
发布消息
触发生产任务
它们都会产生副作用。
假设网络发生超时,系统不知道工具是否执行成功,于是重新调用一次,结果可能出现:
邮件发送两次
订单创建两次
报销提交两次
数据库重复写入
解决这类问题,需要使用幂等键。
{
"tool": "submit_expense",
"idempotency_key": "expense-user01-20260713-001",
"arguments": {
"amount": 380
}
}
服务端收到请求后,先检查这个幂等键是否已经执行过。
如果已经成功执行,则直接返回之前的结果,不再重复操作。
因此,工具系统可以分成两类:
无副作用工具:允许自动重试
有副作用工具:必须幂等、审批和审计
这是 Agent 从演示系统走向生产系统时必须补上的能力。
八、记忆系统的核心,不是“全部塞进上下文”
模型上下文长度有限,但用户历史会持续增长。
因此,一个成熟的 Agent 不能把所有历史消息一直发送给模型。
更合理的方式是建立分层记忆。
工作记忆
保存最近几轮对话,直接进入当前上下文。
特点:准确、实时、容量小
情节记忆
保存过去发生过的任务和事件。
上周完成了招聘匹配算法调整
昨天修改了样板库删除逻辑
此前确定优先使用阿里云 OCR
需要时通过搜索找回。
长期事实记忆
保存相对稳定的信息。
用户偏好的输出格式
项目使用的技术栈
企业业务规则
固定工作流程
权限配置
这类信息更适合结构化保存,而不是完全依赖聊天历史。
九、为什么记忆检索要同时使用向量和关键词
仅使用向量数据库,并不能解决所有检索问题。
向量搜索擅长寻找语义接近的内容。
例如:
查询:成衣报价标准
历史内容:服装成本核算规则
即使关键词不同,向量检索也可能找到它。
但对于下面这些内容,关键词检索更可靠:
订单号 HF20260713001
函数名 candidate_matching.py
错误码 50013
接口路径 /api/v1/orders
因此,更成熟的记忆检索应该采用混合搜索:
最终得分
= 向量语义得分
+ BM25 关键词得分
+ 时间权重
+ 来源权重
+ 权限过滤
这里还有一个容易忽视的问题:检索之前必须先做权限过滤。
不能先从所有数据中检索,再让模型判断哪些内容可以看。
正确方式应该是:
先按用户权限过滤数据范围
→ 再执行语义和关键词检索
→ 最后将结果注入上下文
十、多 Agent 的价值,不是角色扮演
现在很多多 Agent 系统喜欢设计一组角色:
规划 Agent
执行 Agent
审核 Agent
总结 Agent
这种方式在一些复杂任务中有用,但多 Agent 更重要的价值,其实是隔离。
一个 Agent 实例应该拥有独立的:
工作空间
系统提示词
模型
记忆
工具
权限
知识库
例如:
招聘 Agent:
访问简历、JD 和候选人数据库
技术文档 Agent:
访问代码仓库、接口文档和架构资料
服装设计 Agent:
访问面料库、款式库和趋势资料
它们不应该共享全部数据和权限。
真正的多 Agent,不只是让多个模型互相对话,而是:
用职责边界降低复杂度,用权限隔离控制风险。
十一、插件系统决定了平台能否长期扩展
一个 Agent 平台不可能在核心代码里预先实现所有功能。
因此,扩展能力通常应该通过插件完成。
常见插件类型包括:
渠道插件
工具插件
记忆插件
模型提供商插件
一个典型的插件加载流程是:
扫描插件目录
→ 读取插件声明
→ 校验配置 Schema
→ 加载入口文件
→ 注册到系统注册表
→ 由对应模块调用
例如:
飞书插件 → 注册到渠道路由器
数据库工具插件 → 注册到工具执行器
Milvus 记忆插件 → 注册到记忆检索模块
本地模型插件 → 注册到模型提供商列表
插件化的真正价值在于:
新增能力,不需要修改核心系统
这也是平台型架构与普通业务代码之间的重要区别。
十二、为什么 UI 也应该从 Agent 主进程中拆出去
当 Agent 需要生成按钮、列表、表单等可交互界面时,可以让模型输出声明式 UI 描述,再由独立的前端服务渲染。
流程大致如下:
Agent 生成 UI 描述
→ UI 服务解析
→ WebSocket 推送到浏览器
→ 浏览器渲染界面
→ 用户点击按钮
→ 事件返回 Agent
→ Agent 更新界面
这里最重要的架构思想不是 UI 本身,而是故障隔离。
Agent Gateway 负责核心任务
UI 服务负责界面渲染
即使 UI 服务出现故障,也不应该导致整个 Agent Gateway 停止工作。
这个思路同样适用于:
文件解析服务
OCR 服务
浏览器执行服务
代码沙箱
异步任务服务
高风险、资源消耗大或者容易崩溃的模块,尽量不要和主控制进程绑定在一起。
十三、一个完整请求到底经历了什么
把前面的模块串起来,一条消息的完整执行链路大致如下:
用户发送消息
↓
渠道适配器解析消息
↓
Gateway 验证用户身份
↓
解析 Session 和信任级别
↓
选择对应 Agent
↓
计算当前工具权限
↓
加载系统规则和相关 Skill
↓
从记忆系统检索历史信息
↓
组装模型上下文
↓
调用大模型
↓
执行工具调用
↓
将工具结果返回模型
↓
生成最终答案
↓
保存会话和执行日志
↓
格式化并发送回复
可以发现,真正调用模型只占整个流程中的一小部分。
Agent 系统真正复杂的地方,是模型调用前后的控制机制:
给模型什么信息
允许模型做什么
工具如何执行
执行结果如何保存
异常如何恢复
全过程如何审计
十四、企业 Agent 平台应该优先建设什么
如果要从零建设一个企业级 Agent 平台,我不会先追求更多模型,也不会先做复杂的多 Agent 协作。
我会优先完成下面几项能力。
第一,统一 Agent Gateway
所有网页、飞书、钉钉和业务系统请求,都经过同一个控制入口。
第二,建立标准任务协议
外部渠道全部转换成统一消息结构,避免 Agent 与具体平台耦合。
第三,建立上下文组装器
统一管理系统规则、会话历史、Skill、记忆和工具定义。
第四,把业务流程做成 Skill
例如:
需求采集 Skill
报销审核 Skill
技术文档 Skill
样板匹配 Skill
招聘评分 Skill
第五,建立工具权限系统
工具权限必须同时受到全局策略、Agent 策略、用户权限和会话类型约束。
第六,所有写操作增加幂等和审批
尤其是发消息、改数据库、创建订单和触发生产任务。
第七,建立完整执行日志
每一次模型调用、工具调用、参数、结果和错误,都必须可以追踪。
总结
研究 OpenClaw 这类项目,真正值得学习的并不是某个配置文件,也不是它接入了多少聊天平台。
最值得学习的是它背后的系统化思路。
第一,Agent 不是一段 Prompt,而是一套运行时系统。
第二,Gateway 负责入口、身份、会话和路由,Agent Runtime 负责推理与执行。
第三,会话不仅保存聊天记录,也是权限和沙箱的安全边界。
第四,上下文应该按任务动态组装,而不是把全部规则一次塞给模型。
第五,工具调用必须具备参数校验、超时、幂等、审批和审计能力。
第六,记忆系统需要分层存储,并结合向量搜索与关键词检索。
第七,多 Agent 真正的价值,是职责、数据和权限隔离。
判断一个 Agent 项目是否成熟,可以直接问下面几个问题:
入口是否统一?
会话如何隔离?
上下文如何组装?
Skill 如何按需加载?
工具权限如何控制?
写操作如何防止重复?
记忆如何检索和压缩?
执行失败后如何恢复?
全过程是否可以审计?
如果这些问题没有答案,那么它大概率仍然只是一个能调用工具的 Demo。
真正的智能体平台,从来不只是让模型“会思考”。
更重要的是,让模型在一个可控、可扩展、可恢复的系统中完成工作。
更多推荐


所有评论(0)