从 Chatbot 到 Agent——什么时候应该升级架构
从 Chatbot 到 Agent——什么时候应该升级架构
前段时间有个同学找我咨询,他在做一个内部工具,想加 AI 能力。他上来就说:
"老张,我想做个 Agent,用 LangChain4j,带工具调用、有规划能力,能自主执行多步任务那种。"
我问他要做什么功能。
"就是让用户问一些关于公司政策的问题,比如报销规定、假期政策、福利细则这些。"
我沉默了大约三秒。
"你为什么要做 Agent?"
他愣了一下:"现在不都流行做 Agent 吗?"
这就是问题所在。
很多人看到 "Agent = 高级" 这个错误等式,然后把一个本来该用简单 RAG + Chatbot 解决的问题,用 Agent 架构硬做了一遍——代码复杂度翻了三倍,延迟增加了两倍,而且引入了一堆根本用不到的错误风险。
这篇文章想讲清楚一件事:什么时候用 Chatbot 就够了,什么时候才真正需要 Agent。 这个判断比选择哪个框架、用哪个模型,对你的项目成功更重要。
一、Chatbot 是什么,能做什么
先把 Chatbot 的能力边界讲清楚。
Chatbot = 输入 → LLM → 输出(可选 RAG 增强)
核心特征:
- 单轮或多轮对话:能维护对话历史,但不会主动规划
- 被动响应:用户问什么,它回什么
- 知识驱动:依赖 LLM 自身知识或 RAG 检索到的知识来回答
- 无工具执行能力:不能主动调用外部系统
- 无自主决策:不会自己决定下一步做什么
Chatbot 擅长的场景:
- 回答知识性问题(FAQ、政策查询、产品介绍)
- 对话式信息检索(RAG + 对话)
- 文本处理(总结、翻译、改写)
- 辅助决策(提供建议,但不执行)
二、Agent 是什么,能做什么
Agent = 规划 + 工具调用 + 执行 + 反馈循环
核心特征:
- 主动规划:收到任务后,自己分解步骤、制定计划
- 工具调用:能调用外部系统(API、数据库、代码执行)
- 状态维护:在执行过程中保持上下文,根据中间结果调整计划
- 自主决策:能根据工具返回结果决定下一步怎么做
- 目标导向:持续执行,直到达成目标或判断无法达成
Agent 擅长的场景:
- 需要查多个数据源、整合信息的复杂任务
- 需要调用外部系统执行操作(下单、发邮件、更新数据库)
- 流程自动化(多步骤的业务流程)
- 开放式问题(不知道需要哪些信息,需要探索)
三、判断标准:该升级的信号
如何判断你的场景需不需要 Agent?我总结了四个关键信号:
信号一:任务需要多步规划
问题:用户的请求能不能用一次 LLM 调用(加上检索)回答?
- "公司的年假政策是什么?" → 一次 RAG 检索就够了,用 Chatbot
- "帮我分析这季度哪些产品的销售额最低,找出原因,并给出优化建议" → 需要分析多个数据源,规划多步骤,用 Agent
信号二:任务需要工具调用
问题:回答用户的问题,需不需要访问 LLM 训练数据之外的实时信息或执行具体操作?
- "什么是 JWT 鉴权?" → LLM 自身知识够用,用 Chatbot
- "帮我查一下今天还有哪些航班从上海到北京,价格在 1000 以内的" → 需要调用实时数据 API,用 Agent
信号三:任务需要自主决策
问题:执行过程中,需不需要根据中间结果决定下一步怎么做?
- 固定格式的报告生成 → 流程固定,用 Chatbot(或简单的 Workflow)
- "帮我找出这个系统的 Bug 并修复它" → 需要查代码、分析错误、尝试修复、验证结果,每一步都依赖上一步结果,用 Agent
信号四:任务需要记忆和状态
问题:任务执行过程中,需不需要维护超出一次对话的状态?
- 一次性问答 → Chatbot
- "每天帮我监控竞争对手的价格,如果有变化超过 5%,自动给我发报告" → 需要长期运行、维护状态、定时执行,用 Agent
如果这四个信号你一个都满足不了,就不需要 Agent。
四、反例:把简单问答硬做成 Agent
让我用具体代码演示这个反面教材。
需求:查询员工的请假余额
错误做法(Agent 过度工程化):
// 错误:为了一个简单查询,搭了整套 Agent 架构
@Service
public class LeaveBalanceAgent {
@Autowired
private AiServices leaveAssistant;
// 注册了一堆工具
@Tool("获取员工的年假余额")
public int getAnnualLeaveBalance(String employeeId) { ... }
@Tool("获取员工的病假余额")
public int getSickLeaveBalance(String employeeId) { ... }
@Tool("获取员工的事假余额")
public int getPersonalLeaveBalance(String employeeId) { ... }
@Tool("获取员工的调休余额")
public int getCompensatoryLeaveBalance(String employeeId) { ... }
@Tool("获取所有假期政策说明")
public String getLeavePolicies() { ... }
public String queryLeaveBalance(String employeeId, String question) {
// Agent 会经历:理解问题 → 规划 → 选择工具 → 调用 → 总结
// 对于简单查询,这个过程需要 2-3 次 LLM 调用
return leaveAssistant.chat(question);
}
}这个设计的问题:
- 用户问"我还有多少年假",Agent 需要 2-3 次 LLM 调用才能回答(先理解问题,再决定调哪个工具,再总结结果)
- 延迟:1-2 秒 → 4-6 秒
- 成本:增加 2-3 倍
- 不确定性:Agent 可能选错工具(比如不知道该调年假还是调休)
正确做法(Chatbot + 简单 RAG):
// 正确:直接查询 + RAG 回答,一次搞定
@Service
public class LeaveBalanceChatbot {
@Autowired
private LeaveService leaveService;
@Autowired
private ChatLanguageModel model;
public String queryLeaveBalance(String employeeId, String question) {
// 1. 直接查询所有假期余额(一次数据库查询)
LeaveBalance balance = leaveService.getBalance(employeeId);
// 2. 构造上下文,让 LLM 基于数据回答问题
String context = String.format("""
员工ID:%s
假期余额信息:
- 年假余额:%d 天
- 病假余额:%d 天
- 事假余额:%d 天
- 调休余额:%d 小时
""",
employeeId,
balance.getAnnualLeave(),
balance.getSickLeave(),
balance.getPersonalLeave(),
balance.getCompensatoryHours()
);
// 3. 一次 LLM 调用,直接回答
return model.generate(String.format(
"根据以下员工假期信息,回答用户的问题。\n\n%s\n\n用户问题:%s",
context, question
)).content().text();
}
}对比:
- 延迟:Chatbot 版本 1-2 秒 vs Agent 版本 4-6 秒
- LLM 调用次数:1 次 vs 2-3 次
- 代码复杂度:30 行 vs 100+ 行
- 正确率:更高(因为数据是直接查的,不经过 Agent 工具选择环节)
五、Chatbot vs Agent 的能力边界
六、混合架构:Chatbot 负责简单查询,Agent 处理复杂任务
大多数真实产品都是混合的:大部分请求是简单查询(Chatbot 搞定),少数请求需要 Agent。
/**
* 智能路由:根据任务复杂度决定走 Chatbot 还是 Agent
*/
@Service
@Slf4j
public class IntelligentRouter {
@Autowired
private SimpleChatbot chatbot;
@Autowired
private FullAgent agent;
@Autowired
private ChatLanguageModel classifierModel;
public String handle(String userId, String userMessage) {
// 快速判断任务类型(用轻量模型,加速分类)
TaskType taskType = classifyTask(userMessage);
log.info("任务分类:{},消息:{}", taskType,
userMessage.substring(0, Math.min(30, userMessage.length())));
switch (taskType) {
case SIMPLE_QUERY:
// 简单查询:走 Chatbot,快速返回
return chatbot.chat(userId, userMessage);
case COMPLEX_ANALYSIS:
case TOOL_REQUIRED:
case MULTI_STEP:
// 复杂任务:走 Agent
return agent.execute(userId, userMessage);
default:
// 不确定时,先用 Chatbot 试试,能回答就不升级
return chatbot.chatWithFallback(userId, userMessage,
() -> agent.execute(userId, userMessage));
}
}
private TaskType classifyTask(String message) {
// 基于规则的快速分类(不用 LLM,减少延迟)
if (isSimpleQuery(message)) return TaskType.SIMPLE_QUERY;
if (requiresTools(message)) return TaskType.TOOL_REQUIRED;
if (isMultiStep(message)) return TaskType.MULTI_STEP;
return TaskType.UNKNOWN;
}
private boolean isSimpleQuery(String message) {
// 关键词规则:问"是什么"、"如何"、"介绍" → 可能是简单查询
return message.matches(".*(是什么|什么是|怎么理解|介绍一下|解释一下).*");
}
private boolean requiresTools(String message) {
// 关键词:查询实时数据、执行操作 → 需要工具
return message.matches(".*(帮我查|当前|最新|实时|帮我发|帮我创建|帮我删除).*");
}
private boolean isMultiStep(String message) {
// 关键词:分析、对比、综合、计划 → 可能需要多步
return message.matches(".*(分析|对比|综合报告|制定计划|深入研究).*") &&
message.length() > 30; // 简短的问题通常不需要多步
}
enum TaskType {
SIMPLE_QUERY, COMPLEX_ANALYSIS, TOOL_REQUIRED, MULTI_STEP, UNKNOWN
}
}七、升级的成本
做升级决策时,要把代价算进去:
| 维度 | Chatbot | Agent |
|---|---|---|
| 开发复杂度 | 低 | 高(2-5x) |
| 调试难度 | 简单(线性) | 困难(非确定性) |
| 延迟 | 1-3s | 5-30s |
| Token 成本 | 1x | 3-10x |
| 错误风险 | 回答不准 | 执行错误操作 |
| 可观测性 | 容易 | 需要专门设计 |
| 测试难度 | 标准化测试 | 难以穷举场景 |
Agent 的成本不只是钱,还有开发时间、维护成本、调试难度。 如果你的场景用 Chatbot 能 80% 满足,就不值得为了那 20% 的"高级感"把架构复杂化。
八、总结:做决策的流程
下次遇到"该不该用 Agent"的问题,走这个流程:
- 描述任务:把用户要做什么写清楚
- 问四个问题:
- 需要多步规划吗?
- 需要调用外部工具吗?
- 需要根据中间结果自主决策吗?
- 需要维护长期状态吗?
- 如果四个都是否:用 Chatbot + RAG,别搞复杂了
- 如果有一两个是:可能是 Workflow(固定步骤的自动化),而不是 Agent
- 如果三四个是:才考虑 Agent
那个问公司政策的内部工具同学,最后用了 RAG + Chatbot,两周上线,用户反馈很好。如果他真的做了 Agent,可能要多花一个月时间,而且最终效果不一定更好。
架构的选择,不是看哪个更"高级",而是看哪个更适合你的问题。 这是一个工程师最核心的判断力。
