Agent工程实践:从WorkFlow到多Agent协作的落地笔记

本文源于项目实践中的一份内部笔记,梳理了从接口调用到多Agent协作的核心工程问题。保持原文风格,略作整理扩充。

一、WorkFlow和Agent:两种流程控制模式

有了单个的接口调用,就需要对调用流程进行控制。根据控制流程角色的不同,分为两种模式:WorkFlow和Agent。

第一种:WorkFlow------流程引擎主导

使用流程引擎进行控制流程,比如在Activity这种流程引擎中添加一个由LLM进行决策的节点。

特点:

  • 流程固定,流程版本化管理,每次修改后需要重新发布

  • 可观测性强,执行流程有预期的

  • 使用场景:有比较固定操作流程,修改频次比较少,比如审批流程。只有在特殊节点添加LLM进行路由决策

  • 这种比较省Token

第二种:Agent------LLM主导

由LLM进行规划和控制下一步应该做什么。

特点:

  • 流程不固定,下一步做什么不固定,没法实现预测。人工介入点不确定

  • 比较费Token,全链路都需要LLM介入决策

  • 工程上衍生出来一些问题:对提示词微调要求极高,上下文管理(上下文会超级大),执行日志记录,Loop次数控制,异常场景控制等

决策补充:确定性维度

除了成本和Token消耗,还有一个确定性维度值得关注:

WorkFlow Agent
行为边界 完全已知 不可穷举
责任归属 流程设计者负责 LLM+提示词共同负责
回退策略 每个节点有明确的fallback 可能无限发散

实际落地建议:从WorkFlow起步,仅在确定性流程中"开窗"给LLM做决策。只有当这个窗口的决策复杂度超出规则引擎可维护的范围时,才考虑将窗口扩大为Agent。渐进式策略比直接上全链路Agent要稳妥得多。

二、Agent控制模式

大模型的两个特点

  1. 输入提示词越大,结果越不准确

  2. 一次输出的文本越多,结果越不准确

解决思路:尽量将问题拆分为小任务完成。

  • 如果任务可以拆分,比如编写不同的模块CRUD代码,那么就拆分为不同子任务进行

  • 如果任务不可以拆分,比如写文章,拆分多次编写就会有明显的书写风格和理解的不同。可以先输出大纲和思路,再拆分为不同子任务编写

整体思路:ReAct

  1. 如果能够搜集信息满足规划需求,就可以先进行大体规划,然后一边执行一边看结果调整规划

  2. 如果刚开始不清楚怎么搞,严重依赖用户的反馈或者外部信息,那就做一步看一步。这种情况是第一种的简化,毕竟刚开始不清楚怎么走几步是胡诌

关于ReAct实现的补充:真正生产级的ReAct需要提示词模板(系统提示+工具描述+格式约束)+ 解析器(从LLM输出中提取Thought/Action/Observation)+ 执行器(工具调用+结果注入)+ 终止条件判断(最大步数、最终答案标记、置信度阈值)。这四层代码+提示词是耦合的,不是单纯"写好提示词"就完事。

多Agent协作模式

  1. 集中规划:思考和规划需要靠一个能力较强的LLM

  2. 编排器-工作者(Orchestrator-Workers):思考和执行对LLM要求不同,可以拆分

  3. 并行执行(Parallelization):如果任务可拆分,让几个Agent并行执行,最后收集总结结果

  4. 评估器-优化器(Evaluator-Optimizer):如果任务输出验收性不好,用一个Agent执行,另一个Agent进行验收

  5. 路由(Routing):如果任务对Agent的要求不同,高级的做高级任务,低级的做低级任务

  6. 完整链路:理解用户需求 → 思考怎么完成 → 规划步骤 → 执行 → 结果合并 → 验收

实现分层

  • WorkFlow:借助外部流程引擎完成

  • ReAct:借助提示词工程完成(配合解析器、执行器、终止判断)

  • Agent拆分和结果合并:用代码编写实现,这种交互模式没必要可配置

补充模式:哨兵-执行者

实践中还有一种常见模式:"哨兵-执行者"(Sentinel-Executor)。一个轻量Agent(甚至纯规则)负责"要不要调用重型Agent",只在必要时才触发大模型推理。典型场景:客服系统里先做意图分类+情绪判断,负面情绪+复杂问题才转给完整Agent。这本质上是路由模式的变体,但增加了一个"拒绝/跳过"选项,对控制成本很有帮助。

三、多Agent组织

三个核心问题

通讯协议:主Agent怎么描述任务;子Agent怎么回复任务结果

实践中建议强制结构化:

json

复制代码
{
  "task_id": "uuid",
  "task_type": "query | generate | summarize | verify",
  "context": { "scope": "...", "constraints": [...] },
  "input": "...",
  "expected_output_schema": {...}
}

子Agent回复必须严格遵循Schema,这样主Agent才能做结果合并和验收。Schema即合同,能减少大量解析异常。

任务图:可以让主Agent进行调用,将主上下文传入;也可以任务图透明,子Agent都可见,将结果写入上下文,写入后标记当前任务执行完成

隔离边界:类似MySQL事务隔离,不同子Agent需要进行逻辑隔离

重点:幻觉的叠加

示例:A → B → C

如果每次准确率有90%,叠加结果是 0.9 × 0.9 × 0.9 = 0.72

实际场景中,0.9³=0.72是乐观估计。错误会放大而非独立随机------A的错误可能导致B在错误前提上"合理推理",反而看起来更可信。

解决方案:

  1. 限制任务深度

  2. 后面节点对前面结果进行交叉验证

  3. 关键节点做"双盲并行"------同一个任务交给两个不同角色的Agent执行,结果比对

四、Agent评测

TDD在这里非常重要。

TDD(测试驱动开发)在Agent场景下不是简单的单元测试,建议分层:

层级 测试内容 方式
工具层 每个Tool的输入输出、异常处理 传统单测
提示词层 同一输入多次输出的一致性 回归测试集 + 语义相似度评估
链路层 多轮交互完整轨迹是否符合预期 黄金数据集 + 人工抽检
业务层 最终结果是否满足业务指标 A/B测试、人工验收

关键原则:提示词变更必须有测试用例覆盖,否则线上漂移完全不可控。

五、Agent执行过程追踪

必须记录的内容

每次Agent运行需要记录:

  • 完整Prompt,含系统提示

  • 多轮交互的完整 messages\[\]

  • 每次工具调用 + 参数 + 返回值

  • 推理链,如有thinking模式

  • 最终输出

  • Token消耗 + 延迟

实践补充:两个额外维度

  1. 决策时的备选方案:LLM在每一步除了选择的Action,还考虑了哪些备选?这对调试"为什么选错"很有价值

  2. 回放能力:记录的不只是数据,还要能重现执行环境(工具版本、外部API的mock状态),否则离线Debug时复现不了问题

存储建议

所有追踪数据结构化存储(JSONL),而不是散落在日志里。后续做评测、审计、可视化都会依赖这个。

写在最后

整个笔记贯穿着一条关键原则:不要把Agent当成黑盒。

  • WorkFlow模式把流程"白盒化"

  • 多Agent协作把职责"白盒化"

  • 评测把质量"白盒化"

  • 追踪把过程"白盒化"

这四层白盒化叠加在一起,才能让Agent系统在生产环境里可维护。可维护性,是Agent工程和AI研究的根本区别。


本文基于项目实践笔记整理,希望对从事Agent工程落地的同学有所帮助。

相关推荐
笨蛋不要掉眼泪1 小时前
Java虚拟机:常用参数
java·开发语言·python
带娃的IT创业者1 小时前
重新定义前端构建速度:深度解析 SWC 如何用 Rust 颠覆 JavaScript 工具链
前端·javascript·rust·前端构建·swc
happy_0x3f2 小时前
前端应用的离线暂停更新策略
开发语言·前端·php
亦暖筑序2 小时前
AgentScope-Java 入门:用 Middleware 审计 Agent 调用
java·ai编程·agentscope
你驴我2 小时前
WhatsApp 消息撤回与编辑的幂等性设计实践
java·服务器·前端·后端·python
我头发多我先学2 小时前
Linux入门:简要认识Linux和基础指令
linux·运维·服务器
新中地GIS开发老师3 小时前
零基础WebGIS开发入门 | GeoJSON数据持久化
前端·javascript·gis·webgis·三维gis开发
青山木3 小时前
Hot 100 ---腐烂的橘子
java·数据结构·后端·算法·leetcode·广度优先
小龙报3 小时前
【优选算法】1. 水果成蓝 2.找到字符串中所有字母的异位词
java·c语言·数据结构·数据库·c++·redis·算法