
1. 为什么 Java 工程师转 AI Agent 有天然优势1.1 从 CRUD 到智能体一次能力栈的平移做了五六年 Java 后端的人心里多少都有点焦虑。Spring Boot 写熟了MyBatis 写腻了微服务那一套拆分、限流、熔断、链路追踪也玩得差不多了突然发现招聘 JD 上开始频繁出现“有大模型应用经验优先”“熟悉 AI Agent 架构”这类字眼。很多人第一反应是我是不是得从头学 Python把 PyTorch 啃一遍我的判断是不需要。Java 工程师转 AI Agent本质上不是转行而是能力栈的一次平移。你过去积累的东西——面向对象设计、依赖注入、接口抽象、状态机、并发控制、可观测性——在 Agent 开发里几乎全部用得上而且用得非常狠。Agent 是什么说白了就是一个能“思考—行动—观察—再思考”的循环体。它需要调用工具、维护上下文、处理异常、控制超时、记录日志、做权限校验。这些东西哪一样不是后端工程师天天在干的事LangChain4j 和 Spring AI 之所以能在 Java 圈快速铺开就是因为它们把 Agent 的编排逻辑做成了 Java 工程师熟悉的样子注解、接口、Builder、配置类。所以这篇文章我不打算讲“大模型原理入门”那种东西而是站在一个写了多年 Java 的人的角度把 Agent 的核心原理、主流框架选型、落地步骤、踩坑经验一次讲透。适合谁看适合已经会 Spring Boot、想用 Java 技术栈把 Agent 真正跑起来的人。你要是连依赖注入都还没搞明白建议先把 Spring 基础补一补再回来。1.2 先搞清楚 Agent 和普通调 API 的区别很多人以为“调个大模型接口”就叫 AI 应用了这跟 Agent 差得远。普通调用是一问一答你发 prompt模型返回文本结束。Agent 是多轮自主决策模型自己判断要不要调工具、调哪个工具、拿到结果后要不要继续、什么时候停下来给最终答案。这个区别决定了架构复杂度完全不是一个量级。一问一答你只需要一个 HTTP 客户端Agent 你需要工具注册中心、执行循环、上下文管理、失败重试、最大步数限制、中间状态持久化。这些恰好是 Java 工程师的舒适区。我见过不少团队用 Python 快速搭了个 demo一到生产就崩并发上不去、状态丢了、工具调用超时没人管、日志查不到。最后发现还是得用工程化的方式重写。这时候 Java 生态的成熟度就体现出来了——Spring 的事务、线程池、Actuator、Micrometer直接拿来就能用。2. Agent 的核心原理ReAct 到底在干什么2.1 ReAct 模式拆解思考与行动的交替ReAct 这个词是 Reasoning Acting 的缩写是目前绝大多数 Agent 框架的底层范式。它的核心循环长这样Thought思考模型根据当前上下文推理下一步该做什么。Action行动模型决定调用某个工具并给出参数。Observation观察工具执行返回结果塞回上下文。重复 1-3直到模型认为可以给出 Final Answer。举个具体例子。你问 Agent“帮我查一下北京今天天气如果下雨就提醒我带伞。”Thought我需要先查天气。Action调用getWeather(city北京)Observation{weather: 小雨, temp: 18℃}Thought下雨了需要提醒带伞。Final Answer北京今天小雨18℃记得带伞。整个过程模型不是一次性输出答案而是分步决策。这就是 Agent 和普通问答的本质差异。2.2 工具调用是怎么实现的工具调用Tool Calling / Function Calling是 Agent 的手脚。原理上你把每个工具用 JSON Schema 描述出来连同用户问题一起发给模型模型如果决定调用就返回一个结构化的调用请求而不是自然语言。一个工具描述大概长这样{ name: getWeather, description: 查询指定城市的实时天气, parameters: { type: object, properties: { city: { type: string, description: 城市名称 } }, required: [city] } }模型看到这个描述就知道有这么个能力可用。关键在于description 写得越清楚模型调用越准。我踩过的坑是description 写得太模糊模型要么不调要么传错参数。后来我养成习惯description 里把“什么时候用、什么时候不用、参数格式”都写清楚调用准确率明显提升。2.3 上下文管理与 Token 预算Agent 每轮循环都会往上下文里塞东西系统提示、历史对话、工具描述、工具返回结果。Token 消耗是线性增长的多轮之后很容易爆。这里必须理解Token 是什么它是模型处理文本的最小单位中文大概 1 个字 1-2 个 token英文一个单词 1-2 个 token。上下文窗口是有上限的超了就报错或者被截断。Java 工程师处理这个的思路应该很熟悉——这不就是内存管理吗我的做法是工具返回结果做裁剪只保留关键字段别把整个 JSON 塞回去。历史对话做摘要超过 N 轮后用模型把前面的对话压缩成一段摘要。系统提示精简别写小作文能一句话说清就别写三句。LangChain4j 里有ChatMemory抽象Spring AI 里有ChatMemory接口都支持滑动窗口和摘要策略别自己造轮子。3. 框架选型LangChain4j 还是 Spring AI3.1 两个框架的定位差异这是 Java 圈问得最多的问题。我的结论先给出来新项目优先 Spring AI存量 Spring 项目集成也优先 Spring AI需要复杂 Agent 编排和丰富集成时看 LangChain4j。维度Spring AILangChain4j出身Spring 官方社区驱动与 Spring Boot 集成原生自动配置需要手动配置Agent 编排能力逐步完善更成熟ReAct 开箱即用模型支持主流模型齐全更广长尾模型多学习曲线低Spring 开发者友好中等版本节奏跟随 Spring 发布迭代快Spring AI 2.0 之后工具调用、结构化输出、RAG 这些能力都补齐了配合 Spring Boot 的自动配置写起来非常顺手。LangChain4j 的优势在于它的AiServices抽象把接口和 Agent 绑定得非常优雅多路召回、复杂 RAG 场景支持更好。3.2 我的实际选型逻辑我自己的项目里是这么分的企业内部的问答助手、工单分类、文档检索Spring AI。因为要跟现有的 Spring Boot 服务打通用它的ChatClient和Tool注解几行代码就能接上。需要多步推理、多工具协作的复杂 AgentLangChain4j。它的AiServices配合Tool注解能把一个 Java 接口直接变成 Agent。顺便说一句网上老有人问“Spring AI Alibaba 停更了吗”这个我没法给确定答案但我的建议是别把宝押在某个特定厂商的封装上。核心能力用 Spring AI 或 LangChain4j 的原生抽象厂商适配层只是可替换的插件。这样即使某个适配层不维护了你换一个就行业务代码不用动。3.3 一个最小可跑的 Spring AI 示例先看依赖dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-openai-spring-boot-starter/artifactId /dependency配置spring: ai: openai: api-key: ${API_KEY} base-url: ${BASE_URL} chat: options: model: qwen-plus temperature: 0.7一个带工具的 AgentService public class WeatherAgent { private final ChatClient chatClient; public WeatherAgent(ChatClient.Builder builder) { this.chatClient builder .defaultSystem(你是一个天气助手需要查天气时调用工具) .defaultTools(new WeatherTools()) .build(); } public String ask(String question) { return chatClient.prompt() .user(question) .call() .content(); } } Component class WeatherTools { Tool(description 查询指定城市的实时天气参数为城市中文名) public String getWeather(String city) { // 实际调用天气 API return city 今天小雨18℃; } }这段代码里Tool注解就是工具注册Spring AI 会自动把方法签名转成 JSON Schema 发给模型。模型决定调用时框架自动执行方法并把结果塞回上下文。整个过程你不需要手写 ReAct 循环框架帮你做了。4. 从零搭建一个可落地的 Agent4.1 需求定义先想清楚 Agent 干什么别一上来就写代码。我见过太多人上来就搭框架结果做出来的东西没人用。先回答三个问题它解决什么具体问题比如“自动回复客户咨询”“从合同里抽取关键条款”“根据日志定位故障”。它需要哪些工具每个工具对应一个明确的动作比如查数据库、调 API、读文件。它的边界在哪哪些事它不能做哪些操作需要人工确认。以“客服工单自动分类”为例输入是工单文本输出是分类标签和优先级。工具可能只需要一个“查询历史相似工单”的检索工具。边界是不能自动关闭工单只能打标签。4.2 工具设计的三条铁律工具设计是 Agent 成败的关键。我的三条经验第一工具粒度要适中。太粗模型不知道怎么用太细模型要调很多次。一个工具最好对应一个完整的业务动作比如createOrder而不是insertOrderRow。第二参数要少而明确。参数越多模型传错的概率越大。能用枚举就别用自由文本能给默认值就给默认值。第三返回值要结构化且精简。返回一大坨 JSON既浪费 token 又干扰模型判断。只返回模型决策需要的信息。Tool(description 根据工单内容查询相似历史工单返回最多3条用于辅助分类) public ListSimilarTicket findSimilar( ToolParam(description 工单正文不超过500字) String content) { // 向量检索逻辑 }4.3 提示词工程系统提示怎么写系统提示System Prompt是 Agent 的“岗位说明书”。我一般按这个结构写角色你是谁。任务你要完成什么。工具使用规则什么时候调工具什么时候不调。输出格式最终答案长什么样。约束不能做什么。一个实际例子你是一个工单分类助手。 任务根据工单内容输出分类标签和优先级。 工具需要参考历史工单时调用 findSimilar。 输出格式JSON包含 category 和 priority 两个字段。 约束不确定时输出 category其他不要编造分类。注意最后那条约束非常关键。模型有“幻觉”倾向不给约束它就会瞎编。我踩过的坑就是没写约束模型给工单编了个不存在的分类下游系统直接报错。4.4 完整执行流程与状态管理一个生产级 Agent 的执行流程我通常这么设计接收请求做参数校验和权限检查。加载上下文从数据库或缓存取历史对话。进入 Agent 循环设置最大步数比如 10 步和超时比如 30 秒。每步记录日志Thought、Action、Observation 全部落库方便排查。循环结束解析最终答案做格式校验。持久化结果更新上下文。状态管理这块Java 工程师有天然优势。我用一个AgentContext对象贯穿全程用 ThreadLocal 或者显式传递都行。关键是每一步都要可观测不然出了问题你根本不知道模型在哪一步跑偏了。public class AgentContext { private String sessionId; private ListMessage history; private int stepCount; private long startTime; private ListToolCallRecord toolCalls; // getter/setter 省略 }5. 常见问题与排查技巧实录5.1 模型不调工具怎么办这是最高频的问题。排查顺序工具描述是否清晰description 太模糊模型不知道啥时候用。系统提示是否引导明确告诉模型“需要 X 时调用 Y 工具”。模型是否支持工具调用不是所有模型都支持 Function Calling选型时要确认。参数 schema 是否有问题required 字段缺失、类型不匹配都会导致调用失败。我的经验是90% 的不调工具问题出在 description 上。把 description 当成写给新同事看的文档来写基本就能解决。5.2 循环停不下来怎么破模型有时候会陷入死循环反复调同一个工具。解决办法设置最大步数硬性限制比如 10 步超了强制返回。检测重复调用同样的工具同样的参数连续出现两次直接中断。在系统提示里加约束“如果工具返回结果已经足够回答立即给出最终答案不要重复调用。”5.3 Token 超限的排查思路现象可能原因解决方向报 context length 错误历史对话太长加滑动窗口或摘要响应变慢上下文过大裁剪工具返回值成本飙升每轮都带全量历史只带最近 N 轮模型答非所问关键信息被截断调整截断策略保留系统提示5.4 工具执行超时与异常处理工具调用是外部依赖一定会失败。我的处理原则每个工具设置独立超时别让一个慢工具拖垮整个 Agent。异常要转成模型能理解的信息比如返回{error: 天气服务暂时不可用}让模型决定是重试还是换方案。关键操作加人工确认比如涉及资金、删除数据的工具不能让模型自主执行。Tool(description 删除指定工单需要人工确认后执行) public String deleteTicket(String ticketId) { // 实际项目中这里应该走审批流 throw new UnsupportedOperationException(需人工确认); }6. 学习路线与进阶方向6.1 分阶段的学习路径我给 Java 工程师的路线是这样的第一阶段1-2 周搞懂 ReAct 原理跑通一个 Spring AI 或 LangChain4j 的 demo能调通模型、注册工具、完成一次多步推理。第二阶段2-4 周做一个真实的小项目比如文档问答或工单分类。重点练工具设计、提示词工程、上下文管理。第三阶段1-2 月上生产要考虑的东西——并发、限流、可观测性、成本控制、评测体系。这块是 Java 工程师的强项别浪费。第四阶段进阶方向比如多 Agent 协作、RAG 多路召回、Agent 评测与回归测试。6.2 别被“新概念”带偏这个领域新词特别多什么 Agentic RAG、Reflection、Plan-and-Execute听着唬人。我的建议是先把 ReAct 这一个模式吃透其他模式都是在它基础上的变体。你把 ReAct 的工具调用、上下文管理、循环控制搞明白了看其他模式就是换个编排方式而已。至于那些“基于 Rust 的 Agent”“某平台工作流转 Spring AI 代码”之类的工具会变原理不变。抓住原理工具随便换。6.3 我个人的一点体会转 Agent 这一年多我最大的感受是Java 工程师的工程能力在这个领域是稀缺的。Python 圈做 demo 快但一到生产就露怯。而 Agent 恰恰是个工程问题——它要处理并发、要保证可靠性、要做可观测性、要控制成本。这些全是后端工程师的基本功。所以别焦虑也别盲目追新。把 Spring AI 或 LangChain4j 用熟把 ReAct 循环理解透把工具设计和提示词工程练扎实你就能把 Agent 真正落地。剩下的交给时间。