ARTICLE DETAIL

资讯详情

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

长任务Agent工程实战:Context、Loop与Graph架构设计

长任务Agent工程实战:Context、Loop与Graph架构设计 1. 从单次问答到长任务执行Agent 工程的重心到底挪到了哪里很多人第一次接触 AI Agent都是从“帮我写一段代码”“帮我总结这篇文章”开始的。这种单次问答的交互方式本质上和搜索引擎、聊天机器人没有太大区别——你给一个输入它返回一个输出任务就结束了。但当你真正把 Agent 用在实际项目里比如让它自动完成一个跨多个系统的数据同步任务、持续监控某个指标并在异常时触发修复流程、或者根据用户反馈迭代生成内容你会发现事情完全变了味。单次回答的工程重点在 Prompt 上。你花大量时间打磨提示词调整温度参数优化输出格式这些工作确实有价值但它们只覆盖了 Agent 生命周期中极短的一瞬间。当任务从“一次调用”变成“持续运行几小时甚至几天”工程工作的重心就从 Prompt Engineering 转移到了 Context Engineering、Loop Engineering 和 Graph Engineering 上。这不是概念炒作而是实际开发中踩坑踩出来的认知升级。我最初做 Agent 项目时也以为把提示词写好就万事大吉。结果上线后发现Agent 在第三轮对话就开始遗忘之前的约束条件第五轮开始重复执行已经完成的操作第十轮直接陷入死循环疯狂消耗 token。这些问题没有一个能靠改提示词解决它们全部属于工程架构层面的缺陷。后来我花了两周时间重构整个执行框架才真正理解为什么社区里越来越多人强调“Agent 工程”而不是“Prompt 工程”。这篇文章适合两类人一是正在从单次 API 调用向长任务 Agent 转型的开发者二是已经踩过坑但还没找到系统化解决方案的工程师。我会把长任务 Agent 的工程工作拆解成几个核心模块每个模块都配上我实际项目中的配置参数、代码片段和避坑经验。你不需要有很深的分布式系统背景但至少要写过一些调用大模型 API 的代码否则部分内容可能会觉得跳跃。2. 长任务 Agent 的工程架构到底长什么样2.1 为什么单次调用的架构撑不住长任务单次调用的架构极其简单用户输入 → 拼接提示词 → 调用模型 → 解析输出 → 返回结果。整个流程是无状态的每次请求都是独立的不需要考虑上下文管理、状态持久化、错误恢复这些问题。但长任务 Agent 完全不同它需要维护一个持续演进的状态机需要记住过去发生了什么、当前处于哪个阶段、下一步该做什么、哪些操作已经执行过不能重复。我见过太多团队试图用单次调用的思路去套长任务场景结果就是不断在提示词里堆砌历史记录把整个对话历史塞进 context window。这种做法在任务轮次少于十轮时勉强能用一旦超过二十轮token 消耗呈指数级增长而且模型对超长上下文的注意力会严重衰减。实测下来当 context 超过 8000 token 后模型对早期指令的遵循率会下降 40% 以上。正确的做法是把 Agent 的执行过程建模成一个显式的状态机。每个状态代表任务的一个阶段状态之间的转移由明确的条件触发而不是靠模型自由发挥。这样做的好处是状态转移逻辑可以被测试、被调试、被优化而不是一个黑盒。我在最近一个自动化运维 Agent 项目中把整个任务拆成了 12 个状态每个状态都有明确的进入条件、执行动作和退出条件。上线后任务成功率从 67% 提升到了 94%平均执行时间反而缩短了 30%。2.2 核心模块拆解Context、Loop、Graph 各管什么长任务 Agent 的工程架构可以拆成三个核心模块它们各自解决不同层面的问题但又紧密耦合。Context Engineering管的是“Agent 在每个决策点能看到什么信息”。这不仅仅是把历史记录塞进去那么简单而是要有策略地选择、压缩、排序上下文。你需要决定哪些信息是当前决策必需的哪些可以摘要化哪些应该完全丢弃。我通常会把上下文分成四层系统指令层不变、任务状态层结构化数据、近期动作层最近 N 步的详细记录、长期记忆层摘要化的历史。每层的更新频率和保留策略都不一样。Loop Engineering管的是“Agent 如何持续运转而不失控”。这包括循环检测、超时控制、重试策略、资源配额、优雅退出等机制。没有这些机制Agent 要么陷入死循环烧光预算要么在遇到暂时性错误时直接崩溃。我在 Loop 层面设置了三道防线单步超时30 秒、单任务总超时15 分钟、最大循环次数50 次。任何一道防线触发Agent 都会进入安全退出流程保存当前状态并生成诊断报告。Graph Engineering管的是“多个 Agent 或多个工具之间如何编排”。当任务复杂到单个 Agent 无法胜任时就需要拆成多个专职 Agent用图结构定义它们之间的调用关系和数据流向。这比简单的串行调用复杂得多因为你要处理并发、依赖、错误传播、结果聚合等问题。我目前负责的一个内容生产流水线就用了 Graph 架构一个 Planner Agent 负责拆解任务三个 Worker Agent 分别负责资料搜集、初稿撰写、质量审核一个 Coordinator Agent 负责调度和汇总。整个图有 7 个节点、11 条边每条边都有明确的数据契约。2.3 状态持久化让 Agent 挂了也能接着跑长任务 Agent 最怕的就是跑到一半进程挂了所有进度丢失。我早期做的一个数据迁移 Agent 就吃过这个亏跑了四个小时迁移了 80% 的数据结果服务器重启一切归零。从那以后我把状态持久化作为长任务 Agent 的第一优先级需求。状态持久化的核心是“检查点”机制。Agent 每完成一个关键步骤就把当前状态序列化后写入持久化存储。恢复时从最后一个检查点加载继续执行。听起来简单但实际做的时候有几个关键决策检查点的粒度多细存什么数据用什么存储我的经验是检查点粒度取决于单步执行的成本。如果单步执行很快比如一次 API 调用可以每步都存如果单步很慢比如跑一个训练任务可以每完成一个阶段存一次。存储内容至少包括当前状态标识、已完成步骤列表、待执行步骤列表、关键中间结果、时间戳。存储介质用关系型数据库就够了不需要上什么复杂的分布式存储除非你的 Agent 集群规模很大。注意状态序列化时一定要考虑版本兼容性。我遇到过恢复时因为代码更新导致旧状态无法反序列化的问题后来在状态对象里加了一个 schema_version 字段恢复时先检查版本不兼容就触发迁移逻辑或人工介入。3. Context Engineering 实操让 Agent 在长任务中不“失忆”3.1 上下文分层策略与 token 预算分配Context Engineering 的核心矛盾是模型需要足够的信息来做正确决策但 context window 是有限的而且 token 越多成本越高、注意力越分散。解决这个矛盾的方法不是简单地截断或摘要而是建立一套分层策略给每层分配明确的 token 预算。我通常把上下文分成四层每层的 token 预算和更新策略如下表所示层级内容token 预算更新频率保留策略系统指令层角色定义、行为约束、输出格式500-800不变始终保留任务状态层当前阶段、已完成步骤、待办事项300-500每步更新始终保留近期动作层最近 5-10 步的详细记录1500-2500每步更新滑动窗口长期记忆层历史摘要、关键决策记录800-1200每 5 步更新压缩保留这个分配不是拍脑袋定的而是根据实际任务调试出来的。系统指令层不能太短否则模型容易跑偏也不能太长否则挤占其他层的空间。任务状态层用结构化格式JSON 或 YAML比自然语言更省 token而且模型解析起来更准确。近期动作层保留最近 5-10 步是经验值太少会导致模型缺乏短期记忆太多会稀释注意力。长期记忆层用摘要模型定期压缩把冗长的历史记录变成关键决策点。总 token 预算控制在 4000-5000 之间比较稳妥。超过这个数模型对早期指令的遵循率会明显下降。我实测过同样一个任务context 控制在 4000 token 时成功率为 91%放到 8000 token 时成功率降到 73%放到 12000 token 时直接掉到 52%。这个衰减曲线非常陡峭所以宁可多花点心思做摘要也不要无脑堆上下文。3.2 摘要压缩的具体实现与参数调优摘要压缩是 Context Engineering 中最需要精细调优的环节。做得太激进关键信息丢失导致 Agent 决策失误做得太保守token 降不下来。我目前用的方案是“滑动窗口 定期摘要 关键事件标记”三件套。滑动窗口负责近期动作层只保留最近 N 步的完整记录。N 的取值取决于任务的复杂度和单步的信息量。对于简单的 API 调用类任务N10 就够了对于涉及多轮推理的复杂任务N 可以降到 5因为每步的信息量更大。定期摘要负责长期记忆层。每完成 5 步就调用一次摘要模型把最近 5 步的记录压缩成一段 100-150 字的摘要。摘要的提示词我调了很多版最终稳定下来的版本是这样的SUMMARY_PROMPT 你是一个任务执行记录摘要器。请将以下 Agent 执行记录压缩成一段简洁的摘要保留以下信息 1. 执行了哪些关键操作 2. 得到了什么关键结果 3. 遇到了什么错误或异常 4. 做出了什么重要决策 丢弃以下信息 - 重复性的操作细节 - 中间过程的冗余输出 - 已经确认无误的常规检查 输出格式一段不超过 150 字的自然语言描述。 执行记录 {execution_log} 摘要关键事件标记是补充机制。有些步骤虽然不在最近窗口中但包含关键决策或错误信息需要单独标记并保留在长期记忆中。我通常会让 Agent 在每步执行后自评一个重要性分数1-5分数大于等于 4 的步骤会被强制保留在长期记忆中不参与摘要压缩。实操心得摘要模型不要用和主 Agent 相同的模型。用一个小模型比如 7B 参数级别的做摘要就够了成本低、速度快而且摘要质量对大模型来说绰绰有余。我用 70B 模型做摘要时每步摘要成本约 0.003 元换成 7B 模型后降到 0.0004 元质量差异几乎可以忽略。3.3 上下文注入顺序对决策质量的影响这是一个容易被忽略但影响巨大的细节上下文各层的排列顺序会显著影响模型的决策质量。我做过一组对比实验同样的内容不同的排列顺序任务成功率差异能达到 15 个百分点。最优的排列顺序是系统指令层 → 任务状态层 → 长期记忆层 → 近期动作层 → 当前决策请求。这个顺序的逻辑是先给模型定角色和约束再告诉它当前任务状态然后补充历史背景最后给出近期详细记录和当前要决策的问题。模型在阅读时注意力会自然地从宏观到微观聚焦最后落在当前决策上。最差的排列顺序是把近期动作层放在最前面。这样模型一上来就被大量细节淹没等到读系统指令时注意力已经消耗得差不多了导致行为约束遵循率大幅下降。我实测过近期动作层前置时模型违反输出格式要求的概率从 8% 飙升到 31%。还有一个细节任务状态层用 JSON 格式比自然语言描述效果好。JSON 的结构化特性让模型更容易解析和定位关键字段而且 token 效率更高。我通常会把任务状态定义成这样{ task_id: migrate_20240521_001, current_phase: data_validation, completed_steps: [connect_source, connect_target, schema_check], pending_steps: [row_count_check, sample_compare, full_migration], blockers: [], last_error: null, retry_count: 0 }这种格式模型解析起来几乎不会出错而且更新时只需要改对应字段不需要重写整段描述。4. Loop Engineering 实操让 Agent 持续运转而不失控4.1 循环检测的三种模式与触发条件Agent 陷入死循环是长任务中最常见也最致命的问题。我总结下来死循环主要有三种模式每种模式的检测方法和处理策略都不一样。第一种是完全重复循环Agent 反复执行完全相同的操作得到完全相同的结果。这种最容易检测只需要维护一个最近 N 步操作的哈希值列表发现重复就触发告警。我通常设置 N3连续三步操作哈希相同就判定为死循环。第二种是振荡循环Agent 在两个或多个状态之间来回切换比如“检查数据 → 发现异常 → 修复 → 检查数据 → 发现异常 → 修复”永远跳不出去。这种检测起来复杂一些需要维护状态转移历史检测是否存在周期性模式。我的做法是记录最近 10 次状态转移如果发现某个状态组合重复出现超过 3 次就判定为振荡循环。第三种是渐进偏离循环Agent 没有完全重复但每轮操作都在偏离目标比如不断生成新的子任务但从不完成。这种最难检测因为它表面上看起来是在“推进工作”。我的应对策略是设置一个“目标对齐检查”机制每 5 步让 Agent 自评一次“当前操作与原始目标的关联度”如果连续两次自评分数低于阈值就触发人工介入。三种循环的检测参数和处置策略对比如下循环类型检测方法触发条件处置策略完全重复操作哈希比对连续 3 步哈希相同立即终止保存状态振荡循环状态转移模式检测同一状态组合出现 3 次暂停并请求人工确认渐进偏离目标对齐自评连续 2 次自评低于 3 分回滚到上一个检查点注意循环检测本身也会消耗 token 和计算资源所以检测频率要合理。我通常是在每步执行后做轻量检测哈希比对每 5 步做一次重量检测模式分析。这样既能及时发现问题又不会给正常执行带来太大负担。4.2 超时控制与优雅退出的工程实现超时控制是 Loop Engineering 的安全网。没有超时控制一个失控的 Agent 可以在几小时内烧掉你一个月的 API 预算。我的超时控制分三层单步超时、阶段超时、总任务超时。单步超时是最细粒度的控制防止某一步操作卡死。我通常设置 30 秒因为绝大多数 API 调用和工具执行都能在 30 秒内完成。如果某类操作确实需要更长时间比如跑一个数据导出可以单独配置更长的超时。阶段超时是中间层控制防止某个阶段无限期拖延。比如“数据验证”阶段设置了 5 分钟超时如果 5 分钟内没有完成验证就强制进入下一阶段或触发人工介入。阶段超时的值需要根据实际业务来定我一般会先跑几次基准测试取平均耗时的 3 倍作为超时阈值。总任务超时是最后一道防线。我通常设置 15-30 分钟具体取决于任务复杂度和业务容忍度。总超时触发后Agent 会进入优雅退出流程保存当前状态、生成执行报告、发送告警通知、释放占用的资源。优雅退出的实现要点是“可恢复”。退出前必须把状态持久化到检查点这样下次可以从断点继续而不是从头再来。我通常会在退出流程中做这几件事def graceful_shutdown(agent_state, reason): # 1. 保存检查点 checkpoint { state: agent_state.to_dict(), timestamp: time.time(), shutdown_reason: reason, schema_version: CURRENT_SCHEMA_VERSION } save_checkpoint(checkpoint) # 2. 生成诊断报告 report generate_diagnostic_report(agent_state) # 3. 发送告警 send_alert( levelwarning, titlefAgent 优雅退出: {reason}, bodyreport ) # 4. 释放资源 release_resources(agent_state) # 5. 记录退出日志 log_shutdown(agent_state.task_id, reason)这套流程看起来简单但实际写的时候有很多细节要注意。比如保存检查点时要确保序列化不会失败生成报告时要控制报告大小别把整个执行日志都塞进去发送告警要设置重试机制防止告警服务暂时不可用导致告警丢失。4.3 重试策略什么该重试什么不该重试重试是 Loop Engineering 中另一个关键机制但很多人对重试的理解有偏差以为“遇到错误就重试”是万能药。实际上错误分很多种有些错误重试有用有些错误重试只会浪费资源。我把错误分成三类暂时性错误、永久性错误、未知错误。暂时性错误包括网络超时、API 限流、服务暂时不可用等。这类错误重试通常能解决但要注意重试策略。我用的是指数退避加随机抖动第一次重试等 1 秒第二次等 2 秒第三次等 4 秒以此类推最大等待时间 30 秒。随机抖动是在等待时间上加一个 ±20% 的随机量防止多个 Agent 同时重试造成惊群效应。永久性错误包括参数错误、权限不足、资源不存在等。这类错误重试一万次也没用应该立即失败并记录详细错误信息。我见过有团队对所有错误都无脑重试三次结果一个参数错误导致 Agent 卡了 90 秒才失败白白浪费了时间和 token。未知错误是最难处理的因为你不知道重试有没有用。我的策略是第一次遇到未知错误时重试一次如果还是同样的错误就判定为永久性错误不再重试。同时把错误信息记录到诊断报告中供后续分析。重试策略的配置我通常放在一个独立的配置对象里方便调整RETRY_CONFIG { max_retries: 3, base_delay: 1.0, max_delay: 30.0, backoff_factor: 2.0, jitter_range: 0.2, retryable_errors: [ TimeoutError, RateLimitError, ServiceUnavailableError ], non_retryable_errors: [ ValidationError, PermissionError, NotFoundError ] }实操心得重试日志一定要详细记录。我遇到过一个问题Agent 在某个步骤反复重试但最终成功了表面上看没问题但实际上每次重试都产生了副作用比如重复发送了消息。后来我在重试逻辑里加了“副作用标记”对于有副作用的操作重试前先检查是否已经执行过避免重复执行。5. Graph Engineering 实操多 Agent 编排的工程细节5.1 什么时候该拆多 Agent什么时候不该拆多 Agent 架构不是银弹拆得不好反而会增加复杂度和故障点。我判断是否该拆多 Agent 的标准很简单单个 Agent 的 context window 是否已经成为瓶颈或者单个 Agent 的职责是否已经过于混杂导致决策质量下降。如果单个 Agent 的 context 能控制在 4000 token 以内而且职责清晰比如就是“根据输入生成输出”那完全没必要拆。拆了之后你要处理 Agent 间通信、数据一致性、错误传播等问题复杂度上升好几个数量级。但如果出现以下情况就该考虑拆了一是任务需要多种截然不同的能力比如既要写代码又要做设计评审单个 Agent 的提示词很难同时覆盖二是任务的不同阶段需要不同的工具集把所有工具都塞给一个 Agent 会导致工具选择准确率下降三是任务需要并行处理多个子任务单个 Agent 只能串行执行。我目前负责的内容生产流水线就是典型的该拆场景。Planner 需要很强的推理能力来拆解任务Worker 需要很强的执行能力来调用工具Reviewer 需要很强的判断能力来评估质量。这三种能力用同一个模型很难同时达到最优拆开之后每个 Agent 可以用最适合的模型和提示词整体效果提升明显。5.2 图结构设计节点、边与数据契约Graph Engineering 的核心是定义清楚节点、边和数据契约。节点是 Agent 或工具边是调用关系数据契约是节点之间传递的数据格式。节点设计的关键是“单一职责”。每个节点只做一件事做好一件事。我见过有人把“搜集资料”和“撰写初稿”放在同一个节点里结果这个节点既要做搜索又要做生成提示词写得极其复杂效果还不好。拆成两个节点后每个节点的提示词都简洁明了效果反而更好。边设计的关键是“明确触发条件”。边不是简单的“A 完成后执行 B”而是“A 完成后如果满足条件 X则执行 B如果满足条件 Y则执行 C”。这种条件边让图结构有了分支和循环能力能表达更复杂的逻辑。数据契约是节点间通信的“接口定义”。我通常用 JSON Schema 来定义每个节点的输入和输出格式这样可以在运行时做校验防止数据格式错误导致下游节点崩溃。比如 Planner 节点的输出契约是这样的{ type: object, required: [sub_tasks, execution_order], properties: { sub_tasks: { type: array, items: { type: object, required: [task_id, task_type, description, dependencies], properties: { task_id: {type: string}, task_type: {enum: [search, write, review]}, description: {type: string}, dependencies: {type: array, items: {type: string}} } } }, execution_order: { type: array, items: {type: string} } } }有了这个契约Worker 节点拿到 Planner 的输出后可以直接按格式解析不需要做各种防御性判断。如果格式不对直接在边层面拦截并报错而不是让错误传播到下游。5.3 并发控制与错误传播的处理多 Agent 架构中并发是提升效率的关键但也是引入 bug 的重灾区。我处理并发的基本原则是能并行就并行但并行度要可控错误要能隔离。并行度控制我通常用信号量或线程池来实现。比如内容生产流水线中资料搜集可以并行发起 5 个搜索请求但最多同时跑 3 个防止把搜索 API 打爆。这个并行度不是拍脑袋定的而是根据下游服务的承载能力和实际测试结果来调的。错误传播的处理更复杂。在串行流程中一个节点出错整个流程就停了处理起来简单。但在图结构中一个节点出错它的下游节点怎么办是全部跳过还是部分继续我的策略是“错误隔离 降级执行”。错误隔离是指一个节点的错误不会导致整个图崩溃只会影响依赖它的下游节点。不依赖它的节点继续正常执行。这需要在图调度器里维护依赖关系出错时只标记受影响的下游节点为“跳过”。降级执行是指对于非关键节点出错后可以走降级路径。比如 Reviewer 节点出错时可以跳过审核直接进入发布流程但会在最终结果里标记“未经审核”。这样虽然质量可能打折扣但至少任务能完成而不是卡在审核环节。注意错误传播的处理策略一定要在图的定义里显式声明不要靠默认行为。我早期做的一个图默认行为是“一个节点出错整个图停止”结果一个非关键节点的临时故障导致整个任务失败。后来改成显式声明每个节点的错误处理策略问题才解决。6. 常见问题与排查技巧实录6.1 Agent 执行到一半突然“失忆”怎么办这是长任务 Agent 最常见的问题之一。表现是 Agent 在某个步骤突然忘记了之前的约束条件或任务目标开始做出莫名其妙的决策。排查思路如下首先检查 context 是否超限。如果 context 接近或超过模型的 context window模型会自动截断早期内容导致“失忆”。解决方法是在 context 构建阶段就做好摘要压缩确保总 token 在安全范围内。其次检查摘要压缩是否丢失了关键信息。有时候摘要模型会把关键约束条件当成“冗余信息”压缩掉。解决方法是调整摘要提示词明确要求保留约束条件和任务目标或者在摘要后附加一个“关键约束”字段强制保留。最后检查是否有状态更新遗漏。如果 Agent 的状态机在某个转移点没有正确更新任务状态层模型就会基于过时的状态做决策。解决方法是在每个状态转移点加断言确保状态更新成功后再继续执行。6.2 循环检测误报太多怎么调循环检测的误报是指Agent 并没有真正陷入死循环但检测机制判定为循环并终止了任务。误报太多会严重影响任务成功率。误报的主要来源是检测阈值设置过严。比如完全重复循环的检测如果设置“连续 2 步哈希相同就触发”那正常的重试操作也会被误判。我通常把阈值设为 3 步给正常重试留出空间。另一个来源是哈希计算方式不合理。如果哈希只基于操作类型而不包括参数那“用不同参数调用同一个工具”也会被误判为重复。我的做法是哈希包含操作类型和关键参数确保只有真正完全相同的操作才会被判定为重复。对于振荡循环的检测误报通常是因为状态转移模式检测的窗口太小。如果窗口只有 5 步正常的“检查-修复-再检查”流程可能被误判。我通常把窗口设为 10 步并且要求模式重复出现至少 3 次才触发。6.3 多 Agent 之间数据不一致的排查方法多 Agent 架构中数据不一致是另一个高频问题。表现是 Agent A 认为任务已经完成但 Agent B 认为任务还在进行中。排查思路如下首先检查数据契约是否严格执行。如果某个节点没有按契约格式输出数据下游节点可能解析失败但没报错导致状态不一致。解决方法是在每条边上加数据校验格式不对直接拦截。其次检查并发写入是否有冲突。如果两个 Agent 同时更新同一个状态字段后写入的会覆盖先写入的导致状态丢失。解决方法是对共享状态加锁或者用乐观锁加版本号来控制并发写入。最后检查错误处理是否一致。如果一个 Agent 出错后走了降级路径但另一个 Agent 不知道就会导致状态不一致。解决方法是在图定义里明确每个节点的错误处理策略并且把错误状态作为数据契约的一部分传递下去。6.4 常见问题速查表问题现象可能原因排查方法解决方案Agent 突然失忆context 超限或摘要丢信息检查 token 数和摘要内容压缩 context调整摘要提示词循环检测误报阈值过严或哈希不合理查看检测日志和操作记录放宽阈值改进哈希算法多 Agent 数据不一致契约未执行或并发冲突检查边校验和并发日志加数据校验加锁或版本号任务卡住不推进某节点超时未处理查看各节点执行时间加超时控制优化慢节点token 消耗异常高context 未压缩或循环重试统计各层 token 占比优化摘要策略限制重试次数输出格式错误提示词约束不够强检查系统指令层内容强化格式约束加输出校验6.5 几个我踩过的坑和对应的解法第一个坑是检查点保存太频繁导致性能下降。我早期做的一个 Agent 每步都保存检查点结果保存操作占了总执行时间的 30%。后来改成每 3 步保存一次性能恢复正常而且恢复时最多丢失 2 步的进度完全可以接受。第二个坑是摘要模型和主模型用同一个导致成本失控。摘要操作调用频率很高如果用大模型做摘要成本会迅速累积。换成小模型后成本降到原来的十分之一质量差异几乎看不出来。第三个坑是图结构的边没有条件判断导致逻辑僵化。我早期设计的图是纯线性的A 完成后必须执行 BB 完成后必须执行 C。后来遇到需要根据中间结果动态选择下游节点的场景不得不重构整个图。现在我在设计图时每条边都会考虑“是否需要条件判断”需要的话就加上条件表达式。第四个坑是错误处理策略没有显式声明导致默认行为不符合预期。不同图调度器的默认错误处理行为不一样有的默认停止整个图有的默认跳过出错节点。如果不显式声明换一个调度器就可能出问题。我现在要求团队在设计图时必须为每个节点声明错误处理策略不允许留空。7. 一些关于 Agent 工程的个人体会做 Agent 项目这两年多我最大的体会是Agent 工程的难点不在 AI 部分而在工程部分。模型能力固然重要但决定一个 Agent 项目能不能上生产、能不能稳定运行的是那些看起来“不 AI”的工程细节——状态管理、错误处理、并发控制、可观测性。我见过太多团队把 80% 的精力花在调提示词上结果上线后各种工程问题频发最后项目不了了之。也见过一些团队提示词写得一般但工程架构扎实Agent 跑得稳稳当当业务价值反而更大。如果你正在从单次调用向长任务 Agent 转型我的建议是先把状态机和检查点机制搭好再把循环检测和超时控制加上最后再优化提示词和上下文策略。这个顺序不能反反了就会陷入“提示词调好了但工程撑不住”的困境。另外不要追求一步到位。我现在的这套架构也是迭代了五六个版本才稳定下来的。每个版本都是在上一个版本暴露问题后针对性改进的。先跑起来再优化比一开始就追求完美架构要务实得多。最后分享一个我最近在用的调试技巧给 Agent 的每一步执行都打上详细的 trace 日志包括输入 context、模型输出、工具调用参数、执行结果、耗时。这些日志在排查问题时极其有用比任何调试工具都管用。我通常会把 trace 日志存到独立的存储里保留最近 30 天的记录方便回溯分析。
返回列表