id, title, type, domain, stack, tags, level, prerequisites, est_hours, related, week
| id |
title |
type |
domain |
stack |
tags |
level |
prerequisites |
est_hours |
related |
week |
| backend.java-spring.scenario.call-java-service |
Python Agent 调用公司已有的 Java 业务系统:读接口、封装工具、错误映射和联调 |
scenario |
backend |
| java-spring |
| function-calling |
| fastapi |
|
| 系统对接 |
| 工具封装 |
| 错误码映射 |
| OpenAPI |
| 联调 |
| 幂等 |
|
intermediate |
| backend.java-spring.awareness |
| ai.function-calling.tool-loop |
|
2 |
| backend.java-spring.interview |
| ai.function-calling.scenario.safe-business-tools |
|
|
Python Agent 调用公司已有的 Java 业务系统:读接口、封装工具、错误映射和联调
业务背景与问题
公司的订单、售后系统是多年的 Spring Boot 服务。新做的 AI 客服 Agent(Python)需要“查订单、查物流、发起退款申请”。问题:
- 接口文档过期,字段含义要读代码才知道;
- Java 服务的错误码体系复杂,Agent 不知道哪些错误可以重试、哪些要告诉用户;
- 退款接口不是幂等的,Agent 重试导致重复申请;
- 联调时双方互相指责。
约束
- 不能大改 Java 服务,只能小范围加接口或参数。
- Agent 不能拥有超过用户本人的权限。
方案设计
- 读接口:从 Controller 和 DTO 读出真实的字段、校验规则、错误码;如果服务集成了 OpenAPI(springdoc 一类工具),导出规范生成 Python 客户端;否则自己写 Pydantic 模型。
- 封装工具:每个业务能力一个工具,入参严格校验;工具层负责鉴权透传(用户令牌或服务账号 + 用户 id)、超时、重试(只对查询类和幂等接口)。
- 错误映射:把 Java 错误码分为三类——可重试(超时、限流)、需要告诉用户(订单不存在、超过退款期限)、需要转人工(系统异常);返回给模型的是结构化的可读信息,而不是堆栈。
- 幂等:和 Java 团队约定退款接口增加
Idempotency-Key 请求头(服务端用唯一约束实现),Agent 在一次会话中对同一操作使用同一个 key。
- 联调:先写契约测试(请求 / 响应样例),双方各自对着样例开发;用 request id 串起两边日志。
关键代码
工具调用安全的完整讨论见安全的业务工具。
取舍
| 选择 |
优点 |
缺点 |
| Python 工具层直接调用 Java 接口(本方案) |
不改动 Java 服务主体 |
需要维护错误映射和模型定义 |
| Java 团队提供专门给 Agent 的聚合接口 |
语义更清晰 |
依赖对方排期 |
| 用 Spring AI 在 Java 侧实现 Agent |
技术栈统一 |
团队 AI 生态以 Python 为主 |
易错点
- Agent 使用高权限服务账号,绕过了用户级权限。
- 对非幂等接口自动重试。
- 把 Java 的异常堆栈直接交给模型,既泄露内部信息又让模型困惑。
- 金额字段在 JSON 中是字符串还是数字没有约定,精度丢失。
面试怎么讲
“我不是 Java 开发,但能读懂 Spring Boot 项目:从 Controller 和 DTO 读出真实的接口契约。对接时我在 Python 侧封装工具,鉴权透传用户身份;把 Java 的错误码分成可重试、告知用户、转人工三类,给模型结构化结果;和 Java 团队约定退款接口支持幂等键。联调前先写契约样例,用 request id 串联日志。”