Agent 不是多角色聊天,而是让大模型在边界内完成任务

Agent 这个词现在被用得很乱。有人把它理解成“会自己思考的 AI”,有人把它理解成“多个角色互相讨论”,也有人认为只要给大模型接几个工具,就已经是在做 Agent。

但从工程角度看,Agent 最重要的不是“看起来多自主”,而是:

它能不能在明确边界内,稳定完成一个多步骤任务。

这才更接近真实 AI 应用开发。

image.png

一、普通大模型调用解决的是“回答”,Agent 解决的是“任务”

普通 LLM 调用一般是这样的:

用户输入一个问题,模型返回一段文本。

比如用户问:

帮我写一段求职信。

模型直接生成一段求职信。

这个过程没有问题,但它本质上还是一次文本生成。模型并不知道用户的真实简历细节有没有支撑这段求职信,也不知道目标 JD 的关键要求是什么,更不知道哪些内容不能夸大。

RAG 往前走了一步:它会先检索知识库、文档或数据库,再让模型基于材料回答。它主要解决的是“回答有没有依据”。

但 Agent 要解决的不是单次回答,而是任务推进。它不只是“查资料再回答”,而是要根据任务目标,在多个步骤之间做选择:

  • 它可能需要先判断用户意图,再决定要不要查询订单;
  • 它可能需要先检索售后政策,再判断是否能退款;
  • 它可能需要生成一个草稿,但不能直接提交;
  • 它可能需要发现证据不足,然后暂停,要求用户补充信息。

也就是说,Agent 面向的不是单次回答,而是一个可执行的任务过程。

所以我更愿意把 Agent 看成一个系统问题:

Agent 不是把 prompt 写得更像人,而是把模型放进一个可以行动、可以观察、可以被约束的系统里。

二、Agent 和 Workflow 的区别

我不太建议一上来就从“自主规划”理解 Agent。

Anthropic 在《Building effective agents》里把 agentic systems 分成 workflow 和 agent。Workflow 是 LLM 和工具按照预设代码路径被编排;Agent 则是 LLM 可以动态决定自己的流程和工具使用方式。它们都属于 agentic system,但工程含义不同。

这个区分很重要。

如果你的任务路径本来就很清楚,比如:

  1. 解析 JD
  2. 解析简历
  3. 匹配能力项
  4. 找出缺口
  5. 生成定制简历
  6. 做证据检查
  7. 输出风险提示

那它更适合先做成 workflow,而不是一上来就交给 Agent 自己规划。

Workflow 的好处是可控、可测、可复盘。

Agent 的价值在于处理那些路径不固定、步骤数量不确定、需要根据中间结果不断调整的任务。

比如客服场景里,用户可能问的是物流、退款、发票、商品参数、投诉、优惠券、售后政策,也可能把多个问题混在一起。系统很难提前写死所有路径,这时 Agent 才有更明确的价值。

换成代码视角,区别更明显:

Workflow 的下一步主要由开发者写死。
Agent 的下一步主要由模型根据当前状态决定。

这不是说 Agent 没有代码控制,而是说代码负责提供工具、状态和边界,模型负责在这些边界里选择下一步。

但这不代表 Agent 可以无限自由。恰恰相反,Agent 越能行动,越需要边界。

三、用代码理解 Agent

从代码角度看,Agent 不是一个神秘概念。

它可以先理解成:

Agent = 一个由 LLM 驱动下一步决策的任务循环。

这里的“循环”不是说所有框架源码都必须写成 while,而是说 Agent 的运行语义大致相同:模型决定下一步,应用执行工具,工具结果写回状态,模型再基于新状态继续判断。

java
复制代码
while (!state.isFinished()) { AgentDecision decision = llm.decideNextStep(state, availableTools); if (decision.isFinalAnswer()) { return decision.answer(); } if (decision.isToolCall()) { policyGate.check(user, decision.toolName(), decision.arguments()); ToolResult result = toolExecutor.execute( decision.toolName(), decision.arguments() ); state.addToolResult(result); traceLog.record(decision, result); } if (decision.needHumanApproval()) { return pauseForHumanReview(state); } }

这不是某个 Agent 框架的完整源码,而是 Agent 的核心运行语义。

普通 LLM 是:

java
复制代码
String answer = llm.chat(userQuestion); return answer;

RAG 是:

java
复制代码
List<Document> docs = retriever.search(userQuestion); String answer = llm.chat(userQuestion, docs); return answer;

Workflow 是:

java
复制代码
JdInfo jd = parseJd(input); ResumeInfo resume = parseResume(input); MatchResult match = matchResumeToJd(jd, resume); RewriteResult rewrite = rewriteResume(match); RiskReport risk = checkEvidence(rewrite); return result;

Agent 是:

java
复制代码
AgentState state = new AgentState(userGoal); while (state.canContinue()) { AgentDecision decision = model.decide(state, tools); switch (decision.type()) { case CALL_TOOL -> { ToolResult result = executeTool(decision); state.observe(result); } case ASK_USER -> { return askUserForMoreInfo(decision.question()); } case NEED_APPROVAL -> { return waitForHumanApproval(decision.action()); } case FINAL -> { return decision.finalAnswer(); } } }

区别就在这里:

Workflow 的下一步是代码写死的。
Agent 的下一步是模型根据当前状态决定的。

这也对应了 Anthropic 对 workflow 和 agent 的区分:前者按预设路径执行,后者由模型动态决定流程和工具使用。


代码上,一个 Agent 至少有 5 个对象

不要先想 LangGraph、CrewAI、AutoGen。先想这 5 个类。

(1)AgentState:任务状态

java
复制代码
public class AgentState { private String goal; private int step; private List<Message> messages; private List<ToolCallRecord> toolCalls; private Map<String, Object> facts; private boolean finished; private boolean needHumanApproval; }

它回答一个问题:

任务现在进行到哪一步了?

没有 AgentState,就不是连续任务,只是一次问答。


(2)AgentTool:工具

java
复制代码
public interface AgentTool { String name(); String description(); ToolResult execute(Map<String, Object> arguments); }

比如电商客服 Agent 里可以有:

java
复制代码
public class GetOrderTool implements AgentTool { public String name() { return "get_order"; } public String description() { return "根据 orderId 查询当前用户的订单状态"; } public ToolResult execute(Map<String, Object> args) { String orderId = (String) args.get("orderId"); // 查数据库 / 调接口 return orderService.getOrder(orderId); } }

Spring AI 的 Tool Calling 也是类似思想:模型提出工具调用请求,应用程序负责解析、执行工具、再把结果返回给模型。模型不是直接操作你的数据库。


(3)AgentDecision:模型决定下一步

java
复制代码
public sealed interface AgentDecision permits CallTool, FinalAnswer, NeedHumanApproval { } public record CallTool( String toolName, Map<String, Object> arguments ) implements AgentDecision { } public record FinalAnswer( String answer ) implements AgentDecision { } public record NeedHumanApproval( String action, String reason ) implements AgentDecision { }

这里就是 Agent 和普通程序最大的区别。

普通程序是你写:

text
复制代码
先查订单,再查政策,再生成回复。

Agent 是模型返回:

text
复制代码
{ "type": "CALL_TOOL", "toolName": "get_order", "arguments": { "orderId": "123456" } }

然后你的后端决定:

  • 这个工具存不存在?
  • 这个用户有没有权限?
  • 这个 orderId 是不是他的?
  • 这个动作需不需要人工确认?

(4)PolicyGate:权限边界

java
复制代码
public class PolicyGate { public void check(User user, String toolName, Map<String, Object> args) { if (toolName.equals("submit_refund")) { throw new NeedHumanApprovalException("退款提交必须人工确认"); } if (toolName.equals("get_order")) { String orderId = (String) args.get("orderId"); if (!orderService.belongsToUser(orderId, user.id())) { throw new AccessDeniedException("不能查询他人订单"); } } } }

边界不是 prompt 里写一句“不要越权”,而是代码里真的拦住。

OWASP 的 Excessive Agency 风险,本质就是 LLM 系统被授予过多功能、权限或自主性后,可能造成破坏性动作;所以工具权限、人工确认、最小授权必须在系统层实现。


(5)AgentRunner:核心循环

java
复制代码
public class AgentRunner { private final LlmClient llm; private final ToolRegistry toolRegistry; private final ToolExecutor toolExecutor; private final PolicyGate policyGate; private final TraceLog traceLog; public AgentResult run(User user, String goal) { AgentState state = new AgentState(goal); while (!state.isFinished() && state.getStep() < 10) { AgentDecision decision = llm.decideNextStep(state, toolRegistry.availableTools()); if (decision instanceof FinalAnswer finalAnswer) { state.finish(); return AgentResult.success(finalAnswer.answer()); } if (decision instanceof NeedHumanApproval approval) { return AgentResult.waitingForApproval(approval.action(), approval.reason()); } if (decision instanceof CallTool callTool) { policyGate.check(user, callTool.toolName(), callTool.arguments()); ToolResult result = toolExecutor.execute( callTool.toolName(), callTool.arguments() ); state.addToolCall(callTool, result); traceLog.record(state, callTool, result); state.nextStep(); } } return AgentResult.failed("Agent stopped: max steps reached."); } }

OpenAI Agents SDK 里所谓 agent loop,本质也是:处理工具调用,把结果送回 LLM,然后继续运行直到任务完成;同时配套 guardrails、sessions、tracing 等工程能力。


用电商客服理解一次完整执行

用户问:

我的订单签收三天了,商品破损,可以退吗?

Agent 第一次判断:

json
复制代码
{ "type": "CALL_TOOL", "toolName": "get_order", "arguments": { "orderId": "A1001" } }

后端执行:

java
复制代码
policyGate.check(user, "get_order", args); ToolResult order = getOrderTool.execute(args); state.addToolResult(order);

工具返回:

json
复制代码
{ "orderId": "A1001", "status": "SIGNED", "signedDaysAgo": 3, "productCategory": "electronics" }

Agent 第二次判断:

json
复制代码
{ "type": "CALL_TOOL", "toolName": "get_refund_policy", "arguments": { "category": "electronics" } }

工具返回:

json
复制代码
{ "category": "electronics", "returnWindowDays": 7, "needDamagePhoto": true, "autoRefundAllowed": false }

Agent 第三次判断:

json
复制代码
{ "type": "FINAL", "answer": "你的订单签收 3 天,仍在 7 天售后窗口内。但商品破损需要上传图片凭证,我可以先帮你生成退款申请说明,提交退款前需要你确认。" }

这就是一个最小 Agent 的运行过程。

它不是一次性回答,而是:

text
复制代码
看当前状态 → 决定查订单 → 得到订单结果 → 决定查政策 → 得到政策结果 → 判断不能直接退款 → 给出受边界约束的答案

所以,从代码视角看,Agent 不是让模型直接控制系统,而是让模型提出下一步动作,再由应用程序判断、执行、记录和约束。

四、Agent 的核心不是“自主”,而是工具、状态和边界

一个更工程化的 Agent 定义可以是:

Agent = LLM + Tools + State + Control Loop + Guardrails

拆开看:

  • LLM 负责理解任务和选择下一步。
  • Tools 负责连接数据库、订单系统、知识库、搜索服务等外部能力。
  • State 负责记录任务进展、工具调用历史和中间结果。
  • Control Loop 负责把模型决策、工具执行和结果反馈串起来。
  • Guardrails 负责限制模型不能越权、不能乱调用工具、不能直接执行高风险动作。

这里最容易被忽略的是工具调用的安全边界。

Spring AI 官方文档对 tool calling 的说明很清楚:虽然通常说 tool calling 是模型能力,但实际执行工具调用逻辑的是客户端应用。模型只能请求工具调用并提供参数,真正执行工具、返回结果的是应用程序本身;模型并不会直接获得工具背后的 API 权限。

这句话非常关键。

因为它说明 Agent 不是让模型直接控制系统,而是让模型提出行动意图,再由应用层判断是否执行。

比如电商客服 Agent 面对“我的订单能退吗?”这个问题时,它不应该直接回答“可以退”。

更合理的方式是:先查询订单,再查询售后政策,再结合订单状态、商品类目和平台规则生成回复。如果涉及退款提交,就只能生成草稿,不能直接执行。

这才是可上线的 Agent。

五、Agent 的真正风险:从“回答错误”变成“行动越界”

普通大模型回答错,风险主要在内容层。

Agent 一旦接入工具,风险就进入系统层。

它可能查错数据,调用错工具,传错参数,泄露敏感信息,执行不该执行的操作,或者在错误前提下连续行动。

OWASP LLM Top 10 里专门列出了 Prompt Injection、Insecure Plugin Design、Excessive Agency 等风险。其中 Excessive Agency 指的是给 LLM 过多、未受约束的行动自主权,可能破坏可靠性、隐私和信任。

这也是为什么我不赞成一开始就做“全自动 Agent”。Agent 安全不能只靠 prompt,而必须靠工具权限、参数校验、人工确认和审计日志这些系统层设计。

真正的工程顺序应该是:

  • 先让模型会读。
  • 再让模型会查。
  • 再让模型会生成草稿。
  • 再让模型在低风险场景自动执行。
  • 最后才考虑高风险动作的半自动化或自动化。

对于工具权限,我更倾向于分四层:

READ:只读查询,可以自动执行。
例如查询订单状态、查询物流、检索政策文档。

DRAFT:只生成草稿,不真正提交。
例如生成退款说明、工单回复、邮件草稿。

WRITE_REVIEW:会改变系统状态,必须人工确认。
例如提交退款申请、修改用户资料、发送正式邮件。

DANGEROUS:默认禁止。
例如删除数据、批量修改权限、执行任意命令。

如果一个 Agent 系统没有这个权限分层,那它本质上还不能算生产级 Agent,只是一个接了工具的聊天机器人。

六、一个更接近真实项目的 Agent 示例

假设我们要做一个跨境电商客服 Agent。

用户问:

我这个订单已经签收三天了,商品有破损,能不能退?

一个不可靠的 AI 可能会直接回答:

一般情况下,签收七天内可以退货。

这句话听起来合理,但它不一定正确。

因为真实判断至少需要几个条件:

  • 订单是否真实存在?
  • 订单是不是当前用户的?
  • 商品类目是什么?
  • 是否支持无理由退货?
  • 破损是否需要上传凭证?
  • 当前是否超过售后时间?
  • 平台政策和商家政策是否冲突?
  • 是否需要人工客服介入?

所以更合理的 Agent 流程应该是:

text
复制代码
用户问题 → 意图识别:售后 / 退款 / 商品破损 → 查询订单状态 → 检索售后政策(RAG 在这里是证据工具) → 检查商品类目 → 判断是否需要图片凭证 → 生成客服回复 → 标注证据来源 → 如果涉及退款提交,进入人工确认 → 记录整次 Agent Run

在这个流程里,模型不是凭常识回答,而是在工具和证据的约束下完成任务。

这就是 Agent 相比普通聊天机器人的真正区别:它不是凭常识直接回答,而是在工具、证据和权限边界内推进任务。

七、为什么不要一开始做多 Agent

很多 Agent 教程喜欢从多 Agent 开始:

一个产品经理 Agent,一个架构师 Agent,一个开发者 Agent,一个测试 Agent,大家互相讨论,最后输出结果。

这种演示很容易吸引眼球,但工程价值未必高。

多数真实业务问题,不是靠“多几个角色说话”解决的,而是靠更清楚的任务边界、更可靠的工具、更稳定的状态记录和更严格的输出校验解决的。

多 Agent 只有在这些场景下才更有必要:

  • 不同角色确实需要不同职责;
  • 不同 Agent 拥有不同工具权限;
  • 需要一个 Agent 审查另一个 Agent 的输出;
  • 任务路径复杂到单一 workflow 难以维护;
  • 系统需要长期运行和异步协作。

否则,多 Agent 很可能只是增加延迟、成本和调试难度。

所以第一篇不应该从多 Agent 开始,而应该先讲清楚单个 Agent 如何完成任务、如何调用工具、如何记录状态、如何控制边界。

八、我对 Agent 的第一性原则

如果让我用一句话定义 Agent,我不会说它是“自主智能体”。

我更愿意说:

Agent 是一个让大模型在工具、状态和权限边界内完成任务的工程系统。

这个定义不够炫,但更适合真实开发。

因为 Agent 的难点从来不只是“让模型更聪明”,而是:

  • 它能调用什么工具;
  • 它不能调用什么工具;
  • 它每一步是否有依据;
  • 它的工具调用是否可追踪;
  • 它在证据不足时能不能停下来;
  • 它在高风险动作前能不能交给人;
  • 它失败后能不能复盘。

所以 Agent 专题不应该从框架开始,不应该从多 Agent 开始,也不应该从“让 AI 自己干活”开始。

它应该先回答一个更基础的问题:

当我们说要做 Agent 时,我们到底是在做一个聊天机器人,还是在做一个可控的任务执行系统?

  • 如果只是聊天,普通 LLM 就够了。
  • 如果只是查资料,RAG 就够了。
  • 如果路径固定,Workflow 就够了。
  • 如果任务路径不确定,需要工具、状态、反馈和权限边界,才真正进入 Agent。

下一篇,我会解释 Agent 核心术语:ReAct、Tool Calling、State、Memory、Workflow 到底是什么?

参考资料

  • Anthropic:Building effective agents
  • OpenAI Agents SDK:Agent loop、Tools、Sessions、Tracing、Guardrails
  • Spring AI Reference:Tool Calling
  • OWASP LLM Top 10:Excessive Agency
  • ReAct:Synergizing Reasoning and Acting in Language Models
  • Toolformer:Language Models Can Teach Themselves to Use Tools

我是 Ryan,一个专注于可信 AI 应用工程的开发者,技术博客:yanxai.com,研究如何让 AI 生成从“看起来对”走向“有证据、可追溯、可验证”。

0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
Ryan
下载 APP