ARTICLE DETAIL

资讯详情

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

AI Agent稳定交付的核心:任务拆解与计划-执行-验证工作流设计

AI Agent稳定交付的核心:任务拆解与计划-执行-验证工作流设计 一个现象在真实业务里越来越常见大模型 Agent 在演示环境里跑得行云流水一旦接入真实数据、真实工具和真实约束就开始频繁“翻车”。任务执行到一半报错、调用了错误的工具参数、搜索结果与回答内容对不上、甚至在一个节点上循环重试直到超时。Agent 能不能从“能用”变成“稳定可交付”关键往往不是换一个更强的模型而是先解决任务拆解这个基础问题。这篇文章围绕一个核心观点展开复杂任务不能直接丢给大模型单次推理去完成而是要先拆成多个可验证、可重试、可追踪的任务单元再通过计划、执行、验证、日志和错误处理把它们编排成稳定工作流。文章会覆盖 Agent 翻车的常见根因、任务拆解到多细才算合理、计划-执行-验证模式怎么落地、工具调用怎么兜底、记忆和状态怎么管理以及从 Demo 到生产环境需要补齐的检查项。适合正在开发 AI Agent、想把原型变成生产级应用的工程师阅读。1. 先认清 Agent“翻车”的根本原因单次推理扛不住复杂任务1.1 复杂任务直接丢给大模型为什么会失败一个真实任务通常是这样的“收集近一周与 AI 监管相关的政策新闻按影响力排序输出中文摘要表格。”表面看这是一个自然语言问题但实际上它包含多个隐含子任务搜索、过滤、去重、排序、摘要、格式化。如果把这些全部塞进一次模型调用模型需要同时完成推理、记忆、工具调用和格式输出。这种做法的失败点是系统性的。第一上下文窗口有限搜索回来的内容一多就会被截断模型只能基于不完整信息回答。第二多步推理的错误会累积第一步判断错了后面每一步都会跟着错。第三模型在单次输出里很难同时保证内容准确和格式稳定经常会自行创造不存在的来源或数据。第四一旦某一步外部工具超时或返回异常整次调用直接失败没有恢复路径。更隐蔽的问题是结果不可复现。直接调用大模型生成复杂报告成功与否很像掷骰子。今天同样的输入可能输出 A明天可能输出 B。对于真实业务不可复现意味着不可测试不可测试就意味着无法稳定交付。所以“翻车”不是模型的某个单点能力问题而是任务设计与模型能力极限不匹配。1.2 常见“翻车”现象与根因对照在开源 Agent 项目和自研框架中很多报错看起来五花八门根源却高度集中。下面这张表列的是最常见的几类现象以及对应的根因和拆解后的改进方向。现象典型根因拆解后怎么改agent terminated due to error子步骤抛异常执行器没有捕获或恢复策略每个步骤独立捕获异常把异常转为该步骤的结果agent execution terminated due to error计划无法继续模型生成步骤和执行器能力不匹配增加计划校验失败时重新生成计划任务在一个节点上反复重试直到超时缺少重试次数上限或错误分类不准确区分可重试与不可重试使用指数退避并设上限回答引用不存在的搜索结果工具结果与后续推理被放在同一次调用中结果未经校验搜索作为独立步骤结果先校验再进入下一步输出格式每次都不一样提示词没有对输出结构做约束定义 output_schema并用 JSON Schema 校验上下文越来越长token 成本和延迟飙升每步中间结果全部追加进提示词按字段选择性读取中间结果不塞全量历史1.3 核心判断把复杂度从模型能力转移到流程设计任务拆解的本质是把“让模型一次性想清楚做完”变成“让系统逐步控制每一小步”。复杂度并没有消失而是从模型推理过程中转移到了流程、校验和错误处理上。模型只负责决策和生成不再负责记住所有历史、担心中途失败。一个简单的判断标准是如果某一步失败后你能明确说出这一小步的输入应该是谁、输出应该是什么、失败原因可能有三四种那么这一步粒度就拆得差不多了。如果失败后你只能说“模型没做好”那说明这一步还是太大需要继续拆。2. 任务拆解的基本框架从目标到可执行步骤2.1 拆解的产物是任务单元不是自然语言清单任务拆解的产物不能只是一段“第一步做什么第二步做什么”的提示词而是结构化的任务单元。一个任务单元至少包含 id、描述、输入输出约束、执行工具、依赖关系、超时和重试策略。用 JSON 描述如下{ id: search_policy_news, name: 搜索政策新闻, description: 获取近一周与AI监管相关的政策新闻标题和链接, input_schema: { type: object, properties: { keywords: { type: array, items: {type: string} }, time_range_days: { type: integer, default: 7 } }, required: [keywords] }, output_schema: { type: array, items: { type: object, properties: { title: {type: string}, url: {type: string}, source: {type: string} }, required: [title, url] } }, tool: news_search, depends_on: [], timeout: 30, max_retry: 2, verify: schema_and_non_empty }这段配置说明几个关键设计description是给模型看的让它知道这个单元在做什么。input_schema和output_schema分别约束输入和输出保证每一步都是可校验的。depends_on表达步骤之间的依赖关系执行器按这个字段编排。timeout、max_retry、verify是稳定性三件套缺一个都不完整。2.2 拆到什么粒度原子任务任务拆解的粒度没有绝对标准但有四个可操作判断条件一步里模型只做一件事。这一步的输入能由上一步输出或用户输入明确给出。这一步的成败可以由规则、Schema 或人工明确判断。一个模型调用或一个工具调用能完成。举例说明。错误做法是让news_analysis一个单元同时做搜索、过滤、打分、摘要。正确做法是拆成五个单元news_search用关键词搜索。news_dedupe去重过滤。news_rerank按相关性或影响力排序。news_summary对前 N 条生成摘要。format_report输出最终表格。拆得太粗失败根因难定位拆得太细调度和上下文开销大。每多一个步骤就多一次模型调用和一次工具调用的延迟同时也多一个潜在的失败点。实践中不要一开始追求完美粒度先用 5 步左右跑通一个最小版本再根据失败场景逐步调整。2.3 任务依赖与编排顺序、并行、条件、循环大部分 Agent 需求不是简单直线而是有分支和依赖的 DAG。一个简单的 Python 数据结构表示如下tasks { search: {depends_on: [], run: search_news}, dedupe: {depends_on: [search], run: dedupe_news}, rerank: {depends_on: [dedupe], run: rerank_news}, summary: {depends_on: [rerank], run: summarize_news}, report: {depends_on: [summary], run: format_report}, }条件分支可以这样设计当dedupe输出的数量小于阈值时跳过rerank直接走summary。循环则必须设置上限不能让模型无限重试。这部分也是理解harness 和 agent 区别的好场景harness 是外层调度和控制框架负责执行 DAG、超时、重试、日志agent 是内部用大模型做决策的部分。任务拆解设计好后真正的稳定性由 harness 保障。2.4 一个可落地的拆解案例政策新闻摘要用 YAML 配置来定义一个可执行的最小任务链方便后续章节用它演示执行、验证和错误处理goal: 生成近一周有参考价值的AI监管政策摘要 steps: - id: search tool: news_search input: keywords: [AI监管, 人工智能治理, 模型备案] window_days: 7 output_schema: NEWS_LIST - id: dedupe tool: text_processor input: from: search rules: [URL去重, 标题相似度0.9去重] - id: rerank tool: llm_rerank input: from: dedupe criteria: 按政策影响范围排序取前10条 - id: summary tool: llm_summarize input: from: rerank format: 每条包含 政策名称、发布机构、核心内容、对行业影响 - id: report tool: formatter input: from: summary format: markdown_table这个案例会贯穿全文。后续每一章讲到的执行器、验证、日志、重试都以这个任务链为例。3. 用“计划-执行-验证”模式改造 Agent3.1 为什么需要计划层如果拆解只停留在概念层面Agent 还是没有真正稳定。关键是要把拆解结果变成循环计划层负责拆解目标执行层负责按步骤调用工具和模型验证层在每一步结束后判断是否通过。三者对应三类框架职责决策、执行、质控。一个常见误区是让模型在一条 prompt 里既生成计划又执行动作。这在简单 demo 里可行但真实业务一旦涉及外部工具就会因为计划不可校验、执行不可中断而失败。要把“计划”和“执行”从代码层面分离计划单独生成执行器独立调度。3.2 计划生成与校验计划层接收一个目标输出结构化计划。示例{ goal: 生成近一周AI监管政策摘要, steps: [ {step_id: search, tool: news_search, input: {keywords: [AI监管], window_days: 7}}, {step_id: dedupe, tool: text_processor, input: {from: search}}, {step_id: summary, tool: llm_summarize, input: {from: dedupe}} ], max_iterations: 10 }计划校验至少做三件事是否存在循环依赖或重复步骤。每个步骤的输入是否引用了已有步骤输出。是否设置了max_iterations和timeout。如果校验不通过应该把错误反馈给模型让它重新生成计划而不是直接执行。这里有一个取舍让模型重新生成计划最多两三次超过就终止避免模型在计划阶段陷入死循环。3.3 执行层步骤间上下文传递执行器逐步骤运行每步从上下文取输入调用工具或模型再把输出写回上下文。核心代码如下class TaskExecutor: def __init__(self, context: TaskContext, runner: StepRunner): self.context context self.runner runner def execute(self, plan: dict) - bool: for step in plan[steps]: step_id step[step_id] self.context.set_step_status(step_id, running) try: step_input self._resolve_input(step) result self.runner.run(step, step_input) if not self._validate_output(step, result): raise ValueError(fstep {step_id} validation failed) self.context.set_step_output(step_id, result) self.context.set_step_status(step_id, succeeded) except Exception as exc: self.context.set_step_status(step_id, failed, errorexc) return False return True这里最关键的点是每个步骤的状态都写入TaskContext由执行器统一管理而不是让模型直接管理全局状态。这样即使失败也能明确知道“卡在哪一个步骤”。代码中的StepRunner负责区分该步是调用工具还是调用模型可按实际情况实现。3.4 验证层单步验收不通过就重试或终止验证不只发生在最终结果上每一步执行完都要验证。验证方式按优先级排列规则校验字段非空、长度范围、URL 格式。Schema 校验用 JSON Schema 约束输出结构。LLM 判断对难以规则化的输出用另一个模型判断是否符合验收标准。验证失败的处理策略可重试错误例如超时和网络抖动按退避策略重试。输入不合法修正输入后重试一次。多次失败步骤标记为 failed不再继续执行依赖它的下游步骤。3.5 循环限制和超时防止“跑飞”长期运行且没有上限的 Agent 几乎必然翻车。至少要设置四个参数。参数作用建议max_iterations整个任务最大步骤数根据任务复杂度设置默认 10 到 20step_timeout单步执行超时工具调用一般 10 到 60 秒deadline任务整体截止时间防止多步骤累计耗时过长
返回列表