一个常见的失败现场是这样的:业务主管在对话框里输入“帮我分析一下 Q2 项目的风险”,Agent 随即读取全量项目文档,交出一篇 2000 字的通用风险综述。
主管看完只补了一句:“我要的是供应链延迟会不会影响交付日期,不是这种泛泛的报告。”
系统在任务起点就填错了空白。Q2 给了时间范围,“项目”给了对象;“分析”要看什么、“风险”指哪一类、结论是否要落到交付日期,都没有写清。Agent 没有追问,直接按常见报告格式完成了一次生成。
有实操文章把办公自动化描述为从“人操作软件”转向“人下达指令,AI 操作流程”来源。难点恰好藏在“下达指令”四个字里。另一份2026 年 AI Agent 技术进展梳理把关注点从工具调用延伸到自主决策。自主性越强,方向判断越要谨慎。
万亿参数、端侧 3B 模型的“慢思考”都属于底层能力讨论;企业里的“风险”采用什么口径,仍要在任务层说明。
先把一句业务话拆成任务单
开发者遇到模糊指令时,常见反应是继续加长 Super Prompt,把角色、格式、规则和异常处理都塞进去。超级 Prompt 能补规则,无法补齐用户从未提供的信息。指令过长后,约束还可能在执行中被忽略,这也是《财务审计别再堆超级 Prompt,拆成三类 Agent 更好查错》讨论过的问题。
一些技术路线图把这类故障称为“一次性生成”问题。更稳的处理链路可以写成:
指令 → 意图卡 → 执行计划 → 工具调用 → 结果校验 → 交付或回退
用户原话先作为待确认的任务草稿,不能直接视为最终规格。实现时可以分成意图解构、执行验证、反思对齐三层。每次回退都要携带具体失败原因,避免原样重跑同一句提示词。
按主管后续补充,意图卡可以写成:
| 字段 | 此例中的内容 |
|---|---|
| 业务目标 | 找出影响 Q2 项目交付的风险 |
| 风险范围 | 供应链、人力资源或综合分析,待确认 |
| 时间范围 | Q2;当前日期可作为上下文,例如 2026-07-19 |
| 证据要求 | 项目文档、Jira 风险项,以及与交付日期直接相关的记录 |
| 交付形式 | 风险项、证据、对交付日期的影响 |
意图解构节点可以直接使用下面这段模板:
只做意图解构,不调用工具。
提取:目标、对象、时间范围、风险维度、证据要求、输出形式。
标记会改变数据源、权限范围或结论口径的缺失字段。
若存在此类缺失,返回 ASK_USER;
否则基于用户角色、历史项目和当前日期生成 2—3 条候选执行路径。
如果“供应链”和“人力资源”会调用不同数据源,Agent 应先问清楚:
我理解您需要分析 Q2 项目风险。目前可见的主要维度包括供应链和人力资源。您希望只看其中一项,还是做综合分析?
这次追问能拦住后面一串无效工具调用。
工具有返回,不等于任务有进展
另一个常见捷径,是把工具返回值直接塞给 LLM,让它自行总结。数据能否回答问题,没有经过检查。
假设 Agent 调用 Jira API 查询风险项,返回了 50 条 Bug 记录,却没有一条提到交付日期。此时强行总结,只会得到一份格式完整、证据错位的“项目风险报告”。
工具调用后需要增加一个 Check 步骤,至少检查四件事:
- 返回记录是否属于 Q2 项目和指定风险维度;
- 数字、日期和风险判断能否定位到原始记录;
- 结果是否回答了“对交付日期有什么影响”;
- 重新查询是否仍在当前用户的权限范围内。
如果 50 条记录都与交付日期无关,状态应设为 RETRY,由 Planner 调整查询词或更换数据源。数据源本身没有相关证据时,返回 ASK_USER,请用户提供文档编号或缩小范围。无关数据不能靠一段流畅文字变成有效证据。
交付前放一个独立审稿节点
最终答案生成后,再启动一个独立的 Reflector。它可以使用同一个模型,但输入、任务和输出格式要与写作节点分开。先给出审核结论,再决定是否改写。
角色:交付前审核节点
输入:original_query、deconstructed_intent、tool_outputs、draft_answer
检查:
- 用户的显性要求是否全部覆盖
- 数字、日期和结论是否能在 tool_outputs 中定位
- 回答是否解决具体问题,是否只是一篇通用风险综述
只返回:
status: PASS / RETRY / ASK_USER
missing_requirements:
unsupported_claims:
next_action:
PASS 进入交付,RETRY 返回 Planner,ASK_USER 则暂停执行并向用户追问。审核意见也要具体,例如“缺少供应链维度”“没有交付日期证据”,而不是笼统地写“答案质量不足”。
LangGraph 状态机不用写得很重
用 LangGraph 或类似编排框架时,可以先从一个小状态机开始:
max_iterations = 3
State = {
'original_query': '帮我分析项目风险',
'deconstructed_intent': None,
'execution_plan': [],
'tool_outputs': [],
'draft_answer': None,
'reflection_feedback': None,
'iteration_count': 0
}
def route_after_reflection(state):
result = state['reflection_feedback']['status']
if result == 'PASS':
return 'deliver'
if result == 'ASK_USER':
return 'ask_user'
if state['iteration_count'] >= max_iterations:
return 'ask_user'
return 'planner'
落到流程里通常是 4 个节点:
Intent_Deconstructor:整理目标、约束、关键指标和缺失字段;Planner:生成“工具 A → 工具 B → 汇总”的执行顺序;Executor:调用工具并保存原始输出,Check可放在这里作为后置检查;Reflector:对照原始指令、意图卡和工具证据,决定交付或回退。
状态机的重点不在节点数量。每一次重试为什么发生、使用了哪些证据、是否触碰权限边界,都应留在 State 中,方便审计和排错。
别让循环失控
Token 和时延要设预算。 如果意图解构、执行检查和反思都调用一次模型,单次请求的 Token 消耗可能达到原来的 2—3 倍,具体取决于上下文长度和重试次数。高频、低价值且字段完整的请求,可以由轻量级 Router 直接分流;只有复杂或模糊指令进入完整循环。类似的取舍也可参考《3B模型跑强化学习:为什么端侧慢思考比无脑堆参数更省电》:把额外计算留给确实需要推理的任务。
权限检查必须放在工具层。 Agent 在修正计划时,可能会更换查询词、扩大检索范围。不要只在 Prompt 里提醒它“遵守权限”,工具调用层应执行运行时沙箱审计。企业内网场景还可以参考《AI Agent 接入企业内网后,权限隔离不能只靠 RBAC》,避免一次正常的重试变成越权探测。
重试次数必须封顶。 max_iterations = 3 是一道硬刹车。三次循环后仍找不到证据,就停止自动尝试,并明确说明:
我已经尝试了三种路径寻找“供应链风险”,但内网文档中暂无相关记录。建议您提供更具体的文档编号。
减少手动编排,省掉的是人工盯住每一步的成本,同时要保留清楚的证据门槛和停机条件。Agent 可以在权限范围内更换查询词、调整工具顺序;它不能扩大权限,也不能把 50 条无关 Bug 包装成项目风险。
模糊指令很难彻底消失。可靠的工作流自动化,应当阻止这些歧义一路传到最终答案。