ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

智能体架构设计:从执行路径地图到子系统协作的完整工程实践

智能体架构设计:从执行路径地图到子系统协作的完整工程实践 带过 Agent 项目的朋友应该都有同感demo 阶段的智能体怎么跑都顺一旦开始往里面塞多模态输入、长对话记忆、外部工具调用、沙盒执行这些模块系统就迅速从“一个 Python 脚本”膨胀成“一个分布式系统”。这个时候最缺的不是某个功能而是一张能把所有子系统、所有执行路径都串起来的地图。我最近对 Hermes Agent 做了一次完整的架构梳理从输入入口到工具执行再到记忆落库把每个子系统之间怎么协作、一条请求到底走了哪些路径都摸了一遍。这篇博文就是这次梳理的整理版会按系统边界拆解、按请求路径追踪把 Hermes Agent 当成一个活的工程系统来看而不是一个黑盒。适合正在做 Agent 开发、想了解成熟智能体框架内部设计、或者准备自研 Agent 编排引擎的朋友参考。1. 为什么需要一张执行路径地图1.1 单机脚本到智能体系统的进化最开始写 Agent其实就是一个大 while 循环接收用户消息拼 prompt调模型把模型输出返回给用户。这个阶段只有一个“模型调用子系统”没有任何路由、记忆、权限的概念。但当 Agent 开始接入浏览器操作、本地文件系统、代码执行器、外部 API 这些工具之后单循环的代码就撑不住了。每一步都要回答几个问题用户意图要不要拆解上下文从哪来调用工具的权限谁审批工具返回的结果存到哪里sandbox 里跑坏了怎么回滚这些问题本质上都是“子系统边界”的问题。Hermes Agent 的架构设计思路就是把这些问题提前用工程手段划分清楚。我梳理后的整体结构分为六大子系统感知输入、认知规划、行动执行、持久记忆、安全治理、运行时调度。每条用户请求会依次穿过这些子系统构成一条完整的执行路径。1.2 执行路径地图到底画的是什么所谓执行路径地图不是画一个静态的模块依赖图而是画“一条消息进来之后系统内部发生了什么”。它的核心价值在于三个维度第一依赖顺序。哪些子系统是必经之路哪些是可并行分支。比如意图解析是必经的但长短期记忆检索可以和上下文组装并行这在工程上是两条独立路径。第二状态流转。在路径的哪个节点会产生状态变化比如会话状态从“待解析”变成“待执行”再变成「已完成」。状态流转能直接帮助排查“卡住了”的问题——是卡在模型响应还是卡在工具调用超时。第三失败分支。每一条路径不是单向的错误、重试、审批拒绝、模型输出格式非法都会跳转到其他路径。没有地图遇到异常就只能在日志海里捞针有了地图第一眼就能定位是在第几个路由节点断的。1.3 首次架构梳理时我踩过的坑做这次梳理之前我犯过一个典型错误按依赖注入关系去画模块图。画出来确实很规整一个箭头上连一个模块但完全没法用来排查问题。为什么因为依赖图表达的是编译期的静态关系而执行路径关心的是运行期的时序关系。同一个模块可能在一条请求里被访问三次也可能被并行的两个分支同时访问这两种情况在依赖图里看不出来。后来的做法是换成时序视角每个子系统分配一个唯一阶段标识在上下文中传递一个 request_id从入口开始打点。把打点数据聚合出来才是真正的执行路径地图。Hermes Agent 本身在可观测性上做了类似设计后面我会在接口契约章节详细说。2. Hermes Agent 核心子系统逐层拆解2.1 感知子系统输入捕获与意图归一化感知子系统是 Agent 的“五官”。它负责把用户发送的多种输入形式统一转成内部标准结构。Hermes Agent 在这一点上做得比较系统——它没有把输入处理散落到各个业务模块里而是在入口层做了一个标准化的统一接口。这个子系统内部有三个层次。第一层是协议适配例如命令行交互、桌面应用、API webhook 都会有不同的接入格式这一层负责解析原始输入第二层是内容归一化把文本、图片路径、附件引用等统一转成内部定义的 message 结构消息里的每个字段都有明确的 schema 约束第三层是基础校验比如会话身份校验、输入长度限制、指令白名单过滤。这里有一个容易被忽略的细节意图归一化不是 NLP 语义理解而是工程层面的统一格式。感知子系统不应该承担“理解用户意图”的职责它只需要保证“信息无失真地传递到规划子系统”。理解意图是认知子系统的任务。把这两层混在一起是 Agent 工程里最常见的设计错误之一。2.2 认知与规划子系统上下文组织与执行计划生成认知子系统是 Hermes Agent 的“大脑”也是架构里最复杂的一层。它的职责可以拆成三块上下文组装、模型路由、计划拆解。上下文组装要解决的是“模型这次调用到底能看到什么”。Hermes Agent 不是简单地把所有历史记录全部塞进 prompt而是按相关性检索——它会从持久化存储中拉取当前会话最近的对话记录、与当前任务相关的长期记忆片段、以及工具描述列表一起组装成一个上下文窗口。这相当于给模型建立了一个“临时工作台”只放当前任务需要的东西。计划拆解是执行路径里比较有意思的一段模型返回的响应不一定是单一动作可能是需要顺序执行的多个步骤。Hermes Agent 在这时候会先做一次 json 解析如果模型输出格式不合法触发一次重试如果合法但步骤之间存在明确的先后依赖再生成一个 DAG 结构给运行时调度。最后模型生成的步骤列表本身也是一种“计划”。模型路由的取舍也很现实简单问答和小任务走快速模型复杂推理和代码生成走强模型。这个路由是可以在配置里定义的很多 Agent 项目没有这一步导致成本失控Hermes Agent 把它内建成了架构的一部分。2.3 行动子系统Tool 调用与 Skill 执行沙盒行动子系统是 Agent 的“手脚”一旦认知子系统决定了要做什么行动子系统就负责真正做出来。Hermes Agent 在行动层面区分了两个概念Tool 和 Skill它们的执行机制完全不同。Tool 是“一次调用一个函数”的原子操作比如查询天气、读写文件、调用一个 HTTP API。每个 Tool 有一个输入参数 schema模型通过 JSON 参数调用Hermes Agent 负责把模型生成的 JSON 参数与真实的函数签名做映射、校验、执行然后返回结构化结果。Skill 则是“一组有状态的操作流程”它可能包含多个 Tool 调用、有中间状态、有条件分支。比如“发布一篇文章到博客”就是一个 Skill它要检查草稿、构建文章、调用 API 发布、验证结果期间任何一步失败都会跳到重试或回滚逻辑。这个区别极端重要——Tool 适合简单作业Skill 适合复杂项目两者在架构上所需支撑完全不是一个量级。行动执行默认在隔离沙盒中进行尤其是代码执行、文件操作这类高风险动作。沙盒不是可有可无的装饰它是 Agent 系统安全性的最后一道防线。Hermes Agent 的沙盒会限制文件系统访问范围、网络访问策略、进程权限这个我在后面安全治理部分还会展开。2.4 记忆子系统会话记忆与长期上下文管理记忆子系统是决定 Agent 能否“越用越聪明”的核心也是最难做好的部分。我在看 Hermes Agent 的实现时觉得它做了一个清晰的分层短期会话记忆、长期事实记忆、工作记忆。短期会话记忆是当前对话轮次内的上下文缓存通常保存在内存里按会话维度隔离。它追求的是速度和容量一般会在上下文组装阶段部分写入模型的 prompt。这里有一个平衡存得太多模型会被无关信息干扰存得太少用户会觉得 Agent“失忆”。Hermes Agent 的做法是按消息的关键性加权把高价值消息完整保留低价值消息只保留摘要。长期事实记忆是跨会话沉淀的关键信息包括用户偏好、项目背景、历史任务结果。它的存储介质是持久化存储写入前要经过“记忆提炼”环节——从当前会话中判断哪些信息值得长期保存而不是把所有对话都灌进去。我见过不少 Agent 项目在这里偷懒结果长期记忆变成了一个无限膨胀的垃圾场检索质量急剧下滑。工作记忆则是当前任务的中转状态相当于任务局部变量任务结束后就会被清理。三层记忆的分工本质上是一个数据生命周期的划分临时数据、业务数据、持久数据各归其位执行路径的各个阶段再按需读取。2.5 安全治理子系统权限审批与审计追踪所有 Agent 项目到最后都会遇到一个问题模型生成了危险的代码怎么办工具调用越权了怎么办这个问题没有统一的、完美的答案但架构上可以把风险控制在可观测、可阻断、可追责的范围内。Hermes Agent 安全治理体系里有三把钥匙角色权限、动作审批、操作审计。角色权限是“谁有资格做什么”。用户、管理员、系统进程被划分为不同的角色不同角色能调用的工具集完全不同。这不是摆设尤其是多用户场景下角色隔离是防越权的地基。动作审批是“高危操作谁来确认”。当模型请求调用高敏感工具比如删除文件、发送邮件、执行不受限代码系统会挂起执行要求人类授权后放行。审批机制通常不是简单的 yes/no而是搭配超时策略一段时间没有响应就默认拒绝。操作审计是“做了什么完全有记录”。每次工具调用之前系统都会记录意图、参数、发起者、目标对象调用之后再记录结果、耗时、错误。审计信息会写入独立事件流不跟业务数据放同一个存储避免互相干扰。有了这三层即使模型真的做出了危险操作至少还能在它扩大影响前被审批拦截或者事后通过审计日志快速定位问题。真实生产环境中安全是妥协的艺术——不能为绝对安全牺牲可用性但可以用分层机制把风险压到可控水平。2.6 运行时调度并发处理与任务编排最后一个子系统是运行时调度它本身不产生业务语义但所有语义的执行都离不开它。我梳理的时候发现Hermes Agent 的运行时有几个设计选型值得单独拿出来讲。并发控制层面Agent 系统跟传统 Web 服务的并发模型不同一个会话可能同时存在多个“半活动”的任务分支比如主对话正在等模型响应后台工具调用已经返回了。这里的并发单位不是请求而是任务。Hermes Agent 使用异步任务队列来管理并发每个任务都有生命周期状态排队、运行、等待审批、成功、失败调度器按优先级和依赖关系决定执行顺序。任务编排层面计划拆解之后生成的步骤会提交给调度器。调度器不只按顺序执行还支持条件分支、并行分组、重试策略。这个编排模型跟 CI/CD 流水线的思路很像但不同之处在于每个步骤的执行者可以是模型、工具、或者人混合编排是 Agent 任务编排的核心特征。还有一个核心机制是 backpressure背压。当工具返回大量数据或者记忆检索耗时超过阈值系统不能无限吞入数据导致内存炸掉。Hermes Agent 在事件层面做了队列长度上限和数据抽样策略超限时直接截断并投递告警事件保证主路径的响应不被拖垮。3. 一条用户请求的执行全程追踪3.1 从入口路由到会话恢复现在真正把一条请求从头到尾走一遍。假设用户通过桌面客户端发送了一条消息“帮我把上一版周报里的数据更新成最新的然后发到团队频道”。请求首先到达网关层经过协议适配后生成一个标准消息对象分配 request_id同时自动关联所在的 session_id。如果 Hermes Agent 判断这是新会话会创建会话目录并初始化空上下文如果这是老会话会从记忆子系统拉取最近的短期会话摘要。这里有个容易被忽略的关键点会话恢复不只是把历史消息原样回灌而是恢复“状态”。包括之前断点任务的进度、工具上一次执行的结果、还有哪些未完成动作。没有状态恢复用户说“把上一版周报更新一下”Agent 根本无法知道“上一版”是哪一版。Hermes Agent 在会话存储中单独维护了一个状态对象保证断线重连后任务能尽量接着跑而不是每次从零开始。我看着这张图真的感慨——以前的 Agent 是“接收指令返回回答”现在的 Agent 是“感知状态恢复上下文再判断动作”完全不是一个复杂度层级。3.2 意图解析与上下文组装感知层把消息结构标准化之后进入认知层。第一步是意图解析和任务分类是直接问答还是需要调用工具还是需要执行多步计划。Hermes Agent 这个阶段通常会用一个轻量模型做快速判断判断结果决定后续的路径分支。紧接着是上下文组装。这步我的经验是组装顺序很重要。Hermes Agent 把上下文分为四个区块——系统提示定义行为边界、工具清单与 schema、相关记忆碎片、用户当前消息。系统提示和数据占位符会对齐工具描述不会被对话历史截断这些细节如果字面顺序不对模型的响应质量会显著下降。组装完成后会把完整 prompt 提交给模型路由。路由根据任务类型把请求分发给合适的模型比如普通问答走快速模型复杂编码任务走强模型。这个路由不是简单的字符串匹配而是算一个任务复杂度估计复杂度低到阈值就直接短路返回不进规划子系统。3.3 计划生成单步指令还是多步编排模型返回响应之后认知层进入执行路径的岔路口。如果模型只返回一个普通文本回复路径直接跳转回话轮结束不需要经过行动层。如果模型返回了工具调用就会生成一个计划。Hermes Agent 的计划数据格式是一个 JSON 数组每个元素是一个步骤对象包含动作类型、目标工具、参数、分支条件。系统会先做一次 schema 校验校验失败会触发模型重试重试超过阈值就回退为“明确告知用户无法处理”。校验通过之后计划提交到运行时调度器。调度器不会盲目把所有步骤一股脑执行掉而是先做依赖分析哪些步骤可以并行哪些必须按顺序。例如“提取最新数据”和“获取团队频道列表”可以并行但“生成周报正文”必须依赖“提取最新数据”的结果。调度器按依赖关系生成执行 DAG然后逐级驱动执行路径。3.4 工具调用执行与沙盒环境动作DAG 就绪后行动子系统开始接管。每个工具调用都会走一遍相同的四步流程参数注入、权限检查、执行调用、结果回收。参数注入阶段系统把模型生成的 JSON 参数与工具 schema 做类型转换和范围校验。比如一个温度查询工具的温度单位参数必须枚举 Celsius/Fahrenheit如果模型传了 Kelvin这里就会被拦截并触发修正。权限检查是安全治理的口子。行动子系统给每个工具都打了风险等级标签低风险工具直接放行中风险工具记录审计但无需审批高风险工具进入审批等待。用户消息里的“发到团队频道”这个动作在风险模型里属于中高等级Hermes Agent 不会在无人许可下直接把内容推送出去而是生成一个审批请求等用户确认后继续执行。执行调用时的沙盒机制在不同工具上的体现不太一样对于代码执行类工具沙盒是一个真实隔离的容器对于文件操作工具沙盒体现为路径白名单规则对于外部 API 请求沙盒是网络访问规则。这个分层沙盒的思路我认为是所有 Agent 项目都必须有的——不要等真的出了安全问题再补架构阶段就应该把“能做什么”的边界画好。3.5 结果汇总与记忆沉淀每个工具的返回结果都会被打包成统一的结果对象写回会话工作区。调度器收集 DAG 中所有依赖完成后认知层把结果组装成最终回复通过输出通道返回给用户。但执行路径到这里还没结束——记忆沉淀阶段在回复之后触发。系统会对本次会话做一次摘要提炼把关键决策、偏好信息、未完成任务抽取出来判断哪些需要写入长期记忆。写入长期记忆前会做一次去重和关联避免同样的信息反复存储。这里我踩过一个实际教训如果把记忆沉淀放在请求执行的同步路径里会导致每次回复都要额外等一次模型摘要调用延迟增加两到三秒。所以记忆沉淀必须放在异步事件流里主路径与记忆写入解耦。Hermes Agent 的架构里记忆写入是通过事件总线异步触发的主路径只负责标记“本次会话需要沉淀”不阻塞用户响应。3.6 失败分支执行路径的“另一条路”执行路径图最重要的部分其实是失败分支。工具调用失败有几种常见情况API 超时、返回格式异常、权限被拒、执行环境崩溃。每种失败都有对应的处理策略。超时和瞬时错误走重试机制重试次数和退避策略是配置化的返回格式异常会反馈给模型重新生成工具参数而不是直接报错权限被拒会转为审批请求或终止执行环境崩溃则走隔离回滚把当前执行环境销毁重建保证污染不扩散。还有一种失败是逻辑层面的模型规划了错误的步骤顺序比如先发送再生成数据。这类失败没法靠重试解决需要靠人工介入。Hermes Agent 在审计日志中会把规划过程完整记录用户可以在界面上看到 Agent 当时是怎么想的以及在哪一步决策出了问题。4. 子系统间的接口契约与事件机制4.1 同步调用与异步事件的取舍拆开 Hermes Agent 的架构之后会发现一个规律不是所有子系统之间都采用同步调用。它把交互分成了两类同步 RPC 风格和异步事件风格。主链路入口到认知到行动到返回走同步调用因为用户请求天然需要实时响应链路各环节必须同步等待结果。但记忆沉淀、审计日志、事件通知这些支撑性动作全部走异步事件通过消息通道解耦。同步和异步的边界划分原则很简单跟用户响应路径强相关的动作走同步跟用户响应路径弱相关的动作全部异步化。这个设计在工程实践上有非常直接的好处。高并发场景下同步调用会被慢速第三方服务拖累异步事件则天然可以缓冲和批量处理。Hermes Agent 通过这两种模式的分离实现了主链路的低延迟和支撑链路的吞吐弹性。4.2 事件总线的数据流设计每个子系统的状态变更都会向外广播事件事件是连接所有子系统的“血液”。这些事件分两种一种是关注“发生了什么”的领域事件如 ToolExecuted、PlanGenerated另一种是关注“系统状态”的基础事件如 SandboxCreated、QueueFull。领域事件被上层各子系统订阅比如记忆子系统监听 ToolExecuted 事件来执行记忆沉淀安全子系统监听所有事件来审计。基础事件被运维监控订阅用于系统健康度分析和容量规划。事件结构里最关键的是 trace_id 和 span_id 字段。trace_id 贯穿一条请求从入口到出口的全链路span_id 标识每一步内部处理过程。利用这两个字段可以把分散的子系统日志串成一条完整路径实现真正意义上的“全链路追踪”。任何 Agent 项目在架构设计时都应该强制所有子系统传递这两个字段而不是只在自己的日志里打 request_id 就完事。4.3 可观测性设计对排查问题的价值架构梳理完我最大的体会是Agent 系统的可观测性比传统 Web 服务更困难因为链路里多了“模型输出”这个不稳定因素。普通服务方法的输入输出是可预期的但模型的输出内容每次都不同且可能是非法 JSON、重复调用、错误参数。Hermes Agent 的做法是三层观测日志、指标、链路追踪。日志记录每个子系统的详细事件指标统计响应时长、错误率、重试次数、模型 token 消耗链路追踪则把日志按 trace_id 串联。排查问题的典型场景用户反馈“Agent 有时候不执行工具”。先看链路追踪找到请求在哪个子系统的耗时异常再看日志确认模型返回是走了工具调用分支还是走了普通回复分支最后再看指标确认是不是模型路由错误地把请求分给了弱模型导致输出格式不合格被重试策略静默处理。三层观测对上了问题定位基本上十分钟之内就能完成。5. 常见问题与排查技巧实录5.1 高频故障排查速查表我把这次梳理之后实际遇到的问题整理成一个速查表对应排查路径和解决方向大家可以贴在项目文档里。故障现象可能根因排查路径建议处理工具调用总是失败重试模型输出参数与工具 schema 不匹配检查模型原样输出和工具 schema 一致性调整工具描述加上参数示例会话上下文混乱Agent“失忆”短期记忆清理策略失效检查记忆子系统摘要提炼逻辑增加关键消息权重标记高并发下主链路延迟飙高同步调用链中混入了慢异步操作检查事件总线积压情况和同步调用链把弱相关动作剥离出主链路守卫审批超时丢任务审批请求没有超时重发机制检查审批事件的投递确认逻辑增加事件重发与超时升级策略模型输出被静默修正导致行为不符参数修正逻辑过于激进检查参数注入阶段类型转换规则对高风险修正动作增加审计告警长期记忆检索到大量无关内容记忆写入缺乏提炼环节检查长期记忆的写入前过滤逻辑增加记忆提炼模型调用这种表的价值在于它不只是一个“答案清单”更是一套排查思路。比如模型输出参数不匹配这个问题多数人第一反应是改 prompt但实际上更可靠的方向是调整工具描述配合示例参数让模型知道每个字段的边界比反复强调“不要输出错误格式”有效得多。5.2 基于路径地图的调试实操心得最后分享几个我在打开执行路径地图后调试习惯上的变化。第一先看分支再看日志。以前遇到问题我会直接去 log 里面搜异常关键字但 Agent 系统的很多问题不是异常而是“走了错误的分支但没有抛错”。比如模型该调用工具的时候走了普通回复系统不会报错只是行为不符合预期纯搜日志很难看出来。现在我会先看链路追踪里请求实际路径的分支选择确认系统“怎么走的”再回头看对应分支上的日志。第二给模型输出加断点。在认知子系统组装好 prompt 之后、模型返回之后这两个位置至少要把模型原始输出保存一份。否则模型输出格式变更导致解析失败时只能看到解析器的报错看不到模型到底是什么输出排查效率极低。Hermes Agent 在架构上把模型原始响应安全地记录到了审计存储中这个设计在调试时期帮了大忙。第三备份事件流比备份数据库更重要。Agent 系统几乎每个重要动作都有事件记录事件流本身就是最完整的“系统事实”。当出现难以复现的偶发问题直接回放那段时间的事件流能还原整个现场这比从数据库里查几个字段要可靠得多。我现在每次架构评审都会确认各子系统的事件是否有完整的 trace_id 链路如果没有这个系统上线后一定会为排查付出高额成本。第四用沙盒日志联动排查行动层问题。沙盒不只是隔离执行环境还会记录完整的执行日志。当工具执行结果不符合预期比如代码运行了但文件没生成光看 tool 返回的 output 是看不明白的必须进沙盒看真实执行日志。行动子系统的结果回收接口应该把沙盒日志暴露给审计链路就算默认不上报也要留一个手动拉取的入口。Hermes Agent 的这套架构整体上没有玄学成分全是工程权衡的累积。从执行路径地图的角度看它系统就从一个庞大的代码仓库变成了一条可以逐段排查、逐层观测的清晰管道。接下来如果想把这套架构落成自己的 Agent 系统可以按我梳理的子系统边界一个一个建先把感知、认知、行动、记忆四条主路径跑通再把安全和事件总线补上一个生产级 Agent 骨架就立起来了。
返回列表