Java智能体从工具调用到AWS部署
AWS 教程介绍使用 Amazon Bedrock 与 Spring AI 构建自主智能体,覆盖工具调用、会话记忆、韧性设计和多智能体编排。部署环节采用 Amazon Bedrock AgentCore。
AI 深度解读
Java 团队做 AI Agent,难点往往出在模型调用之后:工具怎么执行、记忆怎么隔离、错误怎么恢复、业务结果由谁兜底。AWS 这篇文章给出的路线,是用 Spring AI 编写应用逻辑,再由 Amazon Bedrock AgentCore 承接运行、记忆和身份等基础设施。
作者用旅行助手和文档处理系统展示了这套组合。值得读的不是「多 Agent」这个标签,而是模型、规则、人工审核之间的分工。不过,示例实现、作者验证过的能力和可选扩展,需要分开看。
从聊天接口到 Agent,多出来的责任归谁
作者把 Agent 拆成三项能力:规划、工具调用、记忆。模型根据目标安排步骤,调用外部函数获取信息或执行操作,再利用上下文继续决策,直到完成任务或判断无法继续。
按文章的分类,普通 RAG 应用只有检索这一类有限工具使用,没有规划循环。这个区分适合理解示例,但不能据此判断所有 RAG 系统:检索也可以嵌入 Agent 的循环。
Spring AI 负责应用侧编排,沿用自动配置、依赖注入、ChatClient 和 advisor 等 Spring 写法。AgentCore 则提供托管运行时、记忆、浏览器自动化、代码执行和身份管理。平台提供这些能力,不等于示例全部接入了它们。
文章要求 JDK 21、Spring Boot 4.1、Spring AI 2.0、spring-ai-agentcore 2.0;React 前端需要 Node.js 18+,容器构建需要带 Buildx 的 Docker,AWS CLI 要求 v2 并配置凭证。这些是作者给出的运行前提,原文没有展开兼容性验证范围。
AgentCore runtime 要求两个接口:POST /invocations 接收调用,返回 JSON 或 Server-Sent Events(SSE);GET /ping 返回 Healthy 或 HealthyBusy。长任务必须正确报告忙碌状态,否则运行时可能缩容。@AgentCoreInvocation 可以自动配置接口、序列化、SSE 封装和健康报告,同一个 Spring Boot 应用还能为 React 提供 /api/chat。
这里有个影响前端体验的细节:简单聊天可以直接转发模型流,但多参数工具调用场景,作者建议先用阻塞的 call() 完成响应,再分块发送,以保证工具参数绑定可靠。
接口持续返回分块内容,不代表模型正在实时逐 token 输出。
先跑通一个助手,再决定是否拆成多个 Agent
作者推荐从旅行助手开始。天气查询、行程搜索、流式响应和会话记忆都放在同一个应用里,Spring AI 通过 Amazon Bedrock Converse API 调模型,并在本进程执行工具。
工具方法用 @Tool 标注,参数用 @ToolParam 描述,再通过 defaultTools 注册到 ChatClient。模型返回结构化工具调用,Spring AI 执行方法,把结果交回模型继续处理。工具定义进入上下文之后,模型才能判断何时调用、传什么参数。
文档处理系统进一步拆成 ClassifierAgent 和五个专家:Lawyer、Mortgage、Insurance、Tax、General。专家共用 AbstractDocumentAgent 模板,差别主要落在领域提示和处理规则上。这里的「多 Agent」更接近分类派单后的专业化处理,并没有展示专家之间自由讨论的过程。
下面这段代码解决「带附件提问,并把结果映射成 Java 类型」的问题:
ProcessedDocument review = chatClient.prompt()
.system(personaSystemPrompt)
.user(u -> u.text(question).media(mimeType, fileResource))
.call()
.entity(ProcessedDocument.class);
要留意最后一行:entity(ProcessedDocument.class) 会参与生成结构约束并解析回复,但文章明确说这是尽力而为。作者验证的是 Amazon Bedrock 上的 Anthropic Claude Sonnet 4.5;其他模型家族可能不同,严格场景需要原生 schema 强制约束,或验证与重试。
协作方式也要分清。基础方案实现了 Router 和 Evaluator:前者只负责派单,后者在抽取后执行规则。Parallel fan-out 是可选扩展,尚未实现;批量接口当前逐份顺序处理。作者关于并发耗时接近最慢单次调用的描述,是理想执行路径下的推导,没有给出实测数据。
模型负责抽取,规则和身份决定结果能否使用
文档抽取完成后,系统用进程内规则引擎执行 application.yml 中的 Spring Expression Language(SpEL)表达式。它不是 AWS Step Functions 那样的工作流编排服务。
下面的配置把人工审核门槛、签名检查、负债收入比和抽取置信度检查放到业务代码之外:
idp:
review:
enabled: ${REVIEW_ENABLED:true}
confidence-threshold: ${REVIEW_CONFIDENCE_THRESHOLD:0.7}
rules:
- id: legal-unsigned
agentType: LAWYER
condition: "field('signaturePresent') == 'false' || missing('signaturePresent')"
severity: ALERT
message: "Document appears unsigned; get all parties to sign before relying on it."
- id: mortgage-high-dti
agentType: MORTGAGE
condition: "field('dtiRatio') != '' && T(java.lang.Double).parseDouble(field('dtiRatio')) > 0.43"
severity: WARN
message: "Debt-to-income ratio exceeds 0.43; likely needs manual underwriting."
- id: low-confidence
agentType: ALL
condition: "confidence < 0.6"
severity: WARN
message: "Low extraction confidence; consider human verification."
要区分 confidence-threshold 的 0.7 和规则中的 confidence < 0.6:它们属于不同配置,原文没有充分解释两者的执行关系。INFO、WARN 只记录;ALERT 调用 AlertService,默认实现也只是日志和指标,需要自行接入 Amazon SNS、Slack 或邮件;BLOCK 才会扣留文档等待人工审核。
记忆同样有边界。SDK 通过 advisor 给提示补充上下文,使用 ChatMemory.CONVERSATION_ID 传入 actor:session 形式的标识。示例中的 "user:" + sessionId 不能直接承担真实用户隔离,面向用户部署时应从验证过的 OAuth 2.0(JWT)身份派生 actorId。
长期记忆支持 Semantic、User preference、Summary、Episodic 四种策略,分别保存事实、偏好、摘要和过往经验。提取是可选、异步的,不阻塞当前响应,也不能按同步存储的方式假定刚结束的对话已经进入长期记忆。
生产侧还有几处容易漏看:Resilience4j 提供指数退避重试、熔断和超时;配额超限可能返回 HTTP 429。默认 IAM 认证之外,用户应用还需要身份验证和最小权限。AgentCore Gateway 的限流默认 fail-open,因此不能单独承担访问控制。
示例里的 GuardrailService 只是演示预检查,可用 guardrailsEnabled 按请求切换。作者建议生产环境对每次请求执行 Amazon Bedrock Guardrails,通过 CallAdvisor、StreamAdvisor 调用 ApplyGuardrail,再用 defaultAdvisors 注册。
监控也只完成了一部分:指标经 /actuator/prometheus 暴露,JSON 日志进入 CloudWatch Logs;虽然包含 Micrometer OpenTelemetry bridge 和 OTLP exporter 依赖,部署没有配置 collector,也没有开启采样。接入 X-Ray 仍需设置非零 TRACING_SAMPLING、OTLP_TRACES_ENDPOINT 并配置转发。
我的判断
我认可这套分工:模型处理非结构化内容,明确的业务检查交给规则,需要承担后果的结果交给人工。它给 Java 团队提供了一条沿用现有工程体系的路线。
但「接上 AgentCore 就补齐生产能力」仍然说得偏满。文章没有给出准确率、吞吐、延迟、成本或故障恢复的对照数据;专家拆分比单 Agent 好多少,也没有证明。模型输出里的 confidence 是否可靠、0.7 和 0.6 如何选,都没有校准依据。
能解析成 Java record,不等于字段内容正确;规则能运行,也不等于判断依据可靠。
还有一个配置问题:作者称新增工作流只改配置、不需部署,但没有说明 application.yml 如何热更新。减少代码修改和免部署生效,是两件事。
相较于多 Agent,单 Agent 加工具和规则更适合先验证闭环;相较于进程内规则,跨服务、需要持久化恢复的流程则要另行评估编排方案。原文末尾的自动评估扩展段落被截断,只能确认作者明确承认示例没有实现自动评估与优化反馈循环。
能拿来做什么
- 做 React 聊天界面时,先确认后端返回的是实时模型流还是完成后的分块结果,并为工具执行阶段提供独立状态,避免用户把等待误判为卡死。
- 给现有 Java 服务接入 Agent 时,先用旅行助手这种单 Agent 结构验证工具调用、记忆隔离和失败处理,再决定是否需要专家路由。
- 做文档审核时,把字段抽取与业务判断分开配置,并用人工标注样本验证结果,不能直接把模型置信度当作正确概率。
- 上线前核对 AlertService、Guardrails、身份派生和追踪是否真正接通;示例中的默认日志、演示开关和依赖包,都需要落实为可验证的运行行为。