Agent 开发入门(六):从手写到框架 — 框架帮我们解决了什么
手写 Agent 让你理解原理,框架让你提升效率。看看框架到底帮我们做了什么。
上一篇我们手写了一个完整的 Agent:接收用户输入、调用 LLM、解析 tool_call、执行工具、把结果塞回上下文、再次调用 LLM……整个循环跑通了。
能跑,但写的过程中你一定有过这种感觉:这些代码怎么这么”脏”?
不是说逻辑错了,而是有太多地方在做重复的、容易出错的体力活。这篇我们就从这些痛点出发,聊聊框架到底帮我们解决了什么,以及 Java 开发者该怎么选。
手写版的痛点,你遇到了几个
1. JSON 拼接容易出错
手写版里,工具定义是一段 JSON 字符串,或者你用 Map 手动拼出来的:
Map<String, Object> tool = new HashMap<>();
tool.put("type", "function");
Map<String, Object> function = new HashMap<>();
function.put("name", "get_weather");
function.put("description", "获取天气信息");
// ... 还有 parameters,还有 properties,还有 required
写一个工具还好,写三个你就开始复制粘贴了。复制粘贴就会漏改,漏改就会在运行时报错,而且报错信息往往不直接——LLM 返回了一个奇怪的 tool_call,你要反过来排查是不是工具定义哪里写错了。
2. 工具注册和调度逻辑重复
每次新增一个工具,你要做三件事:定义 JSON schema、在工具列表里注册、在 dispatch 逻辑里加一个 if/else。
if ("get_weather".equals(toolName)) {
result = getWeather(args);
} else if ("search_web".equals(toolName)) {
result = searchWeb(args);
} else if ("send_email".equals(toolName)) {
result = sendEmail(args);
}
// 工具越多,这里越长
这段代码没有任何业务价值,纯粹是胶水。但你不得不写,而且每次加工具都要改这里,很容易忘。
3. 上下文管理要自己维护
多轮对话的上下文是一个 List<Message>,你要自己决定什么时候加、加什么、加多少。
工具调用的结果要以 role: tool 的格式塞回去,格式不对 LLM 就不认。上下文太长了要截断,截断策略要自己写。如果有多个 Agent 协作,上下文怎么传递、怎么隔离,全靠你自己设计。
这些不是难题,但每个项目都要重新写一遍,很烦。
4. 多 Agent 协作几乎无法手写
单个 Agent 的循环还好管,一旦涉及多个 Agent——比如一个 Planner 负责拆任务、多个 Worker 负责执行、一个 Reviewer 负责检查结果——手写版就开始失控了。
消息怎么路由?Agent 之间怎么通信?任务状态怎么跟踪?这些问题手写版根本没有答案,你只能硬编码一套临时方案,换个场景就得重写。
5. 生产级需求几乎没有
手写版里,LLM 调用失败了怎么办?直接抛异常。超时了怎么办?等着。流式输出怎么做?没做。
这些在 demo 里无所谓,真正上线就是问题。重试逻辑、超时控制、流式响应、错误降级……每一个都要额外写代码,而且写好不容易。
框架做了什么
说白了,框架就是把上面这些重复的、容易出错的部分封装好了。
你不用手拼 JSON schema,框架提供注解或 DSL,你描述工具的意图,框架生成 schema。你不用写 dispatch 逻辑,框架自动根据 tool_call 找到对应的方法并执行。上下文管理框架帮你维护,多轮对话、工具结果回填、长度截断都有默认实现。
更重要的是,框架提供了一套抽象——Agent、Tool、Memory、Chain——让你在更高的层次上思考问题,而不是盯着 HTTP 请求和 JSON 格式。
当然,框架不是银弹。它帮你省掉了体力活,但也带来了学习成本和抽象层的复杂度。所以先手写一遍是对的,你现在理解了底层,用框架才不会迷失。
主流框架概览
Agent 框架很多,Java 生态里真正能用的就那么几个,我们快速过一遍。
AgentScope(推荐)
阿里开源的 Agent 框架,Python 和 Java 双语言支持。Java 1.0 已正式发布,原生为 Agent 范式设计——ReActAgent、Toolkit、Memory、Plan、多 Agent 协作,一整套开箱即用。
AgentScope 的核心理念是「开发者透明」:不搞黑盒封装,从提示词、API 调用到工作流编排,所有细节都对开发者敞开。这和我们系列的思路很一致——先理解底层,再用框架提效。
它的优势在几个方面:
- Agent 原生:核心抽象就是 Agent,不是 Chain 也不是 Graph,你的代码直接表达 Agent 的行为
- 白盒可控:支持实时中断、Hook 机制、每一步都可调试
- 多 Agent 协作:MsgHub 消息广播、Pipeline 编排,手写版做不到的事情它帮你搞定
- 生产就绪:超时重试、安全沙箱、A2A 协议、Nacos 服务注册,企业级特性齐全
Spring AI / Spring AI Alibaba
Spring AI 是 Spring 官方出品的 AI 集成框架,定位是把 AI 能力接入 Spring 生态——模型调用、Tool Calling、ChatClient、向量数据库集成这些。如果你只是想在 Spring Boot 项目里加一个 AI 对话功能,Spring AI 上手很快。
但它更像一个 AI 集成层,不是 Agent 框架。对 Agent 范式(自主推理、多轮工具调用循环、多 Agent 协作)的支持还比较初级。而且发展节奏偏慢,2.0 GA 预计 2026 年中才发布,API 一直在变,路线也不太清晰。
Spring AI Alibaba 是阿里基于 Spring AI 扩展的落地框架,面向通义系列模型和阿里云服务。它在 Spring AI 的基础上加了 Graph 工作流编排等能力,更偏 Workflow 方向。但阿里自己也意识到 Workflow 和 Agent 是两回事——所以他们已经把 Spring AI Alibaba 的 Agent 内核升级为 AgentScope,两个项目现在是互补关系:Spring AI Alibaba 管 Workflow,AgentScope 管 Agent。
LangChain4j
LangChain 的 Java 版本,社区维护,API 设计比较 Java 风格,文档完整。如果你习惯 LangChain 的概念体系(Chain、Agent、Memory、Retriever),LangChain4j 上手很快。
缺点是过度封装。LangChain 在 Python 社区已经被广泛吐槽”抽象太多、调试困难”,Java 版本也继承了这个问题。框架迭代快,模型能力增强后很多中间层反而成了负担。
CrewAI、AutoGen 等
都是 Python 生态,Java 开发者暂时不用太关注。
用 AgentScope Java 重写同一个 Agent
我们用上一篇手写的”智能助手”来对比。手写版大概需要:定义工具 JSON、维护消息列表、写 dispatch 逻辑、处理循环……加起来 150 行左右。
用 AgentScope Java,核心代码是这样的:
第一步:定义工具
public class WeatherTools {
@Tool(name = "get_weather", description = "获取指定城市的天气信息")
public String getWeather(
@ToolParam(name = "city", description = "城市名称,如北京、上海") String city) {
// 实际调用天气 API
return city + "今天晴,气温 22°C";
}
@Tool(name = "search_web", description = "搜索网络获取最新信息")
public String searchWeb(
@ToolParam(name = "query", description = "搜索关键词") String query) {
// 实际调用搜索 API
return "搜索结果:...";
}
}
@Tool 和 @ToolParam 注解替代了手拼 JSON。方法签名就是工具的 schema,框架自动生成——和手写版那一堆 Map 嵌套彻底说再见。
第二步:注册工具、创建 Agent
// 注册工具
Toolkit toolkit = new Toolkit();
toolkit.registerTool(new WeatherTools());
// 创建 Agent
ReActAgent agent = ReActAgent.builder()
.name("Assistant")
.sysPrompt("你是一个智能助手,可以查天气、搜索信息。请用中文回答。")
.model(DashScopeChatModel.builder()
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
.modelName("qwen3-max")
.build())
.toolkit(toolkit)
.build();
工具注册变成了 toolkit.registerTool(),Agent 创建用 Builder 模式一气呵成。注意这里直接出现了 ReActAgent——框架的核心抽象就是 Agent,不是 Chain 也不是 Client。
第三步:调用
Msg response = agent.call(
Msg.builder().textContent("北京今天天气怎么样?").build()
).block();
System.out.println(response.getTextContent());
一行调用,ReAct 循环(推理→工具调用→观察→再推理)、上下文管理、结果回填——全部由框架处理。你看不到这些细节,但它们都在运行——正是我们前五篇手写过的那些逻辑。
生产级配置也很直观:
ReActAgent agent = ReActAgent.builder()
.name("Assistant")
.sysPrompt("你是一个智能助手")
.model(model)
.toolkit(toolkit)
.maxIters(10) // 最大迭代次数
.modelExecutionConfig(ExecutionConfig.builder()
.timeout(Duration.ofMinutes(2)) // 模型调用超时
.maxAttempts(3) // 自动重试
.build())
.toolExecutionConfig(ExecutionConfig.builder()
.timeout(Duration.ofSeconds(30)) // 工具调用超时
.build())
.build();
手写版里缺失的超时、重试、迭代控制,框架都内置了。
对比手写版,代码量从 150 行降到了 30 行左右,而且每一行都在表达业务意图,没有胶水代码。
多 Agent 协作:框架的真正杀手锏
前面的例子是单个 Agent,框架的优势还没完全展开。一旦涉及多 Agent 协作——比如一个 Planner 拆任务、多个 Worker 执行、一个 Reviewer 检查结果——手写版几乎无法管理,但这正是 AgentScope 的强项。
MsgHub:让 Agent 像在群里聊天一样协作
// 创建多个 Agent
ReActAgent planner = ReActAgent.builder()
.name("Planner")
.sysPrompt("你负责分析需求并拆分任务。")
.model(model).build();
ReActAgent coder = ReActAgent.builder()
.name("Coder")
.sysPrompt("你负责编写代码。")
.model(model).toolkit(codingTools).build();
ReActAgent reviewer = ReActAgent.builder()
.name("Reviewer")
.sysPrompt("你负责审查代码质量。")
.model(model).build();
AgentScope 的 MsgHub 机制让多个 Agent 像在一个群聊里一样通信——消息自动广播,每个 Agent 根据自己的角色决定是否响应。Pipeline 则让你定义执行顺序:串行、并行、条件分支,框架负责消息传递和状态同步。
这是手写版几乎不可能做到的事情。你在手写版里要自己管理消息路由、状态同步、并发控制——每换一个场景就得重写一遍。
框架选型建议
选框架不用纠结太久,按场景来:
你想认真做 Agent 开发(推荐) 用 AgentScope Java。它是真正为 Agent 范式设计的框架,ReActAgent 开箱即用,工具系统、记忆管理、多 Agent 协作一整套齐活。而且它对开发者透明,你在前五篇学到的底层知识不会浪费——框架里的每一步你都知道它在干什么。
你只是想在 Spring Boot 项目里加个 AI 对话 可以用 Spring AI。它更像一个 AI 集成层,ChatClient 接口用起来很简单。但如果你后续想做复杂的 Agent 逻辑(自主规划、多 Agent 协作),Spring AI 会力不从心,到时候还是要切到 AgentScope。
你只是做个简单的 demo 或内部工具 手写就够了。引入框架有学习成本,简单场景反而增加复杂度。
一个原则:不要为了用框架而用框架。框架是工具,解决的是规模化和复用的问题。如果你的场景还没到那个规模,手写版更直接、更好调试。但如果你想深入 Agent 开发这个方向,AgentScope 是目前 Java 生态里最值得投入的选择。
系列回顾:从一次 API 调用到框架级 Agent
我们用六篇文章走完了一条路:
第一篇:搞清楚 Agent 是什么,不是什么。打破”AI 自主意识”的幻觉,建立”LLM + 工具 + 循环”的基本认知。
第二篇:发出第一次 API 调用。用 Java 直接调 OpenAI 接口,看到请求和响应的原始格式,理解 role、content、message 这些基础概念。
第三篇:实现多轮对话。理解上下文是怎么维护的,为什么 LLM 能”记住”之前说的话。
第四篇:接入工具。理解 Tool Calling 的完整流程——LLM 不执行工具,它只是告诉你该调哪个工具、传什么参数。
第五篇:手写一个完整 Agent。把前四篇的知识串起来,实现一个能自主决策、调用工具、多轮对话的 Agent。
第六篇:引入框架。从手写版的痛点出发,理解框架的价值,知道怎么选。
这条路走完,你对 Agent 的理解已经不是”听说过”的层次了。你知道它的底层是什么,知道框架帮你省掉了什么,也知道什么时候该用框架、什么时候手写就够了。
接下来能做什么?可以选一个框架深入,做一个真实的项目;可以研究 RAG,给 Agent 接上知识库;可以研究多 Agent 编排,让多个 Agent 协作完成复杂任务。方向很多,但基础已经有了。
这是「Agent 开发入门」系列的最后一篇。关注粒方Lab,后续会有更多 Agent 开发实战内容。