Java 程序员第 20 阶段:Agent 工具调用开发,对接第三方接口自动任务

Java 程序员第 20 阶段:Agent 工具调用开发,对接第三方接口自动任务 作者洛水石标签Java大模型Agent工具调用时间2026-05-19概述在大模型Agent架构中工具调用Tool Use是实现自主任务执行的核心能力。通过定义标准化的Tool接口Agent能够调用各类外部工具——从简单的计算器到复杂的第三方REST API——完成单靠大模型无法胜任的任务。本篇文章聚焦Java后端视角讲解Tool接口设计、第三方API对接、工具注册与调用机制的完整实现。一、Tool接口核心设计1.1 为什么要定义Tool接口大模型本身具备强大的推理能力但无法直接与外部系统交互。通过Tool接口我们将外部能力封装为Agent可调用的技能。当用户提出需要实时数据或外部操作的需求时Agent通过Function Calling机制选择合适的工具并执行。一个设计良好的Tool接口需要包含以下元信息-name工具唯一标识符供Agent识别和选择-description工具功能描述帮助LLM理解何时该调用此工具-parameters参数schema定义LLM需要传递哪些参数-invoke()核心执行方法执行业务逻辑并返回结果1.2 Tool接口定义__INLINE_javapublic interface Tool {String getName();String getDescription();String getParameters(); // JSON SchemaToolResult invoke(MapString, Object params);}____INLINE_ToolResult为执行结果的封装类____INLINE_javapublic class ToolResult {private boolean success;private String output;private String error;public ToolResult(boolean success, String output) {this.success success;this.output output;}// getters...}____INLINE_1.3 工具分类根据实现复杂度工具可分为三类-轻量工具计算器、日期查询、字符串处理等纯本地逻辑-API工具调用第三方REST API获取数据-编排工具组合多个工具完成复杂任务图1Tool 接口核心架构二、第三方API对接实战2.1 API工具设计模式第三方API工具需要处理认证、请求构建、响应解析等环节。建议采用模板方法模式将通用逻辑抽取到抽象基类____INLINE_javapublic abstract class ApiTool implements Tool {protected abstract String getBaseUrl();protected abstract MapString, String getHeaders();protected abstract String buildPath(MapString, Object params);protected abstract ToolResult parseResponse(String response);Overridepublic ToolResult invoke(MapString, Object params) {try {String url getBaseUrl() buildPath(params);HttpRequest request HttpRequest.newBuilder().uri(URI.create(url)).headers(getHeaders().entrySet().stream().flatMap(e - Stream.of(e.getKey(), e.getValue())).toArray(String[]::new)).GET().build();HttpResponseString response httpClient.send(request,HttpResponse.BodyHandlers.ofString());return parseResponse(response.body());} catch (Exception e) {return new ToolResult(false, null, e.getMessage());}}}____INLINE_2.2 认证机制处理不同第三方API的认证方式各异常见的有-API Key认证在请求头或参数中携带key-OAuth 2.0获取access_token后携带在Authorization头-JWT认证使用预生成的token____INLINE_javapublic class OAuthTool extends ApiTool {private String clientId;private String clientSecret;private String accessToken;Overrideprotected MapString, String getHeaders() {MapString, String headers new HashMap();headers.put(Authorization, Bearer accessToken);headers.put(Content-Type, application/json);return headers;}// token刷新逻辑public void refreshToken() {// 调用OAuth token接口刷新access_token}}____INLINE_2.3 天气预报工具实现以天气查询为例展示完整的API工具实现____INLINE_javapublic class WeatherTool extends ApiTool {private static final String BASE_URL https://api.weather.example.com/v1;private final String apiKey;public WeatherTool(String apiKey) {this.apiKey apiKey;}Overridepublic String getName() {return weather;}Overridepublic String getDescription() {return 查询指定城市的实时天气信息返回温度、湿度、风力等数据;}Overridepublic String getParameters() {return {type: object,properties: {city: {type: string, description: 城市名称如北京、上海}},required: [city]};}Overrideprotected String buildPath(MapString, Object params) {String city (String) params.get(city);return /weather?city URLEncoder.encode(city, StandardCharsets.UTF_8) apikey apiKey;}Overrideprotected ToolResult parseResponse(String response) {try {JSONObject json new JSONObject(response);String temp json.getJSONObject(data).getString(temperature);String humidity json.getJSONObject(data).getString(humidity);String result String.format(温度%s湿度%s, temp, humidity);return new ToolResult(true, result);} catch (JSONException e) {return new ToolResult(false, null, 解析天气数据失败 e.getMessage());}}}____INLINE_图2第三方 API 对接流程三、工具注册与调用机制3.1 工具注册中心工具注册中心负责管理所有可用工具的元信息供Agent在决策时查询____INLINE_javapublic class ToolRegistry {private final MapString, Tool tools new ConcurrentHashMap();public void register(Tool tool) {tools.put(tool.getName(), tool);}public void unregister(String name) {tools.remove(name);}public Tool get(String name) {return tools.get(name);}public ListTool getAll() {return new ArrayList(tools.values());}// 获取所有工具的schema用于LLM理解可用工具public String getToolSchemas() {return getAll().stream().map(tool - String.format({name: %s,description: %s,parameters: %s}, tool.getName(), tool.getDescription(), tool.getParameters())).collect(Collectors.joining(,, [, ]));}}____INLINE_3.2 工具选择策略当Agent需要执行任务时根据LLM的Function Calling结果选择对应工具。常见的策略有-精确匹配LLM直接指定工具名-语义匹配通过embedding相似度匹配最相关的工具-意图分类先做意图分类再匹配对应类别的工具____INLINE_javapublic class ToolSelector {private final ToolRegistry registry;private final LlmClient llmClient;public ToolSelection select(String userQuery) {String schemas registry.getToolSchemas();// 构建Prompt让LLM选择工具String prompt String.format(用户需求%s可用工具%s请选择最合适的工具并提取参数。, userQuery, schemas);String llmResponse llmClient.chat(prompt);// 解析LLM返回的工具调用指令return parseToolCall(llmResponse);}}____INLINE_3.3 工具执行器执行器负责调用被选中的工具并处理执行过程中的异常____INLINE_javapublic class ToolExecutor {private final ToolRegistry registry;private final MapString, Object context new ConcurrentHashMap();public ToolResult execute(String toolName, MapString, Object params) {Tool tool registry.get(toolName);if (tool null) {return new ToolResult(false, null, 未找到工具 toolName);}try {// 执行前拦截preInvoke(toolName, params);// 调用工具ToolResult result tool.invoke(params);// 执行后拦截postInvoke(toolName, result);return result;} catch (Exception e) {return new ToolResult(false, null, 执行异常 e.getMessage());}}private void preInvoke(String toolName, MapString, Object params) {// 日志记录、参数校验等log.info(执行工具{}参数{}, toolName, params);}private void postInvoke(String toolName, ToolResult result) {// 结果缓存、监控埋点等if (result.isSuccess()) {log.info(工具执行成功{}结果{}, toolName, result.getOutput());} else {log.error(工具执行失败{}错误{}, toolName, result.getError());}}}____INLINE_图3工具注册与调用机制四、自动任务执行集成4.1 ReAct模式下的工具调用ReActReasoning Acting模式将推理和执行交替进行1.Thought分析当前情况决定下一步行动2.Action选择并执行工具3.Observation获取工具返回结果4.重复直到任务完成____INLINE_javapublic class ReActAgent {private final LlmClient llmClient;private final ToolExecutor toolExecutor;public String run(String task) {String history ;String currentInput task;for (int i 0; i maxIterations; i) {// 构建ReAct PromptString prompt buildReActPrompt(task, history);// LLM推理下一步行动LlmResponse response llmClient.chat(prompt);if (response.isFinalAnswer()) {return response.getAnswer();}// 解析并执行工具ToolCall toolCall response.getToolCall();ToolResult result toolExecutor.execute(toolCall.getToolName(),toolCall.getParameters());// 更新历史history response.getThought() \n;history Action: toolCall.getToolName() \n;history Observation: result.getOutput() \n;}return 任务执行超时;}}____INLINE_4.2 异步任务处理对于耗时的API调用建议采用异步处理避免阻塞____INLINE_javapublic class AsyncToolExecutor {private final ToolRegistry registry;private final ExecutorService executor Executors.newCachedThreadPool();public CompletableFutureToolResult executeAsync(String toolName, MapString, Object params) {return CompletableFuture.supplyAsync(() - {Tool tool registry.get(toolName);if (tool null) {return new ToolResult(false, null, 未找到工具);}return tool.invoke(params);}, executor);}}____INLINE_4.3 任务队列集成生产环境中工具调用通常接入消息队列实现削峰填谷____INLINE_javapublic class QueuedToolExecutor {private final BlockingQueueToolTask taskQueue;private final ToolExecutor executor;PostConstructpublic void start() {IntStream.range(0, 10).forEach(i - {Executors.newSingleThreadExecutor().submit(() - {while (true) {try {ToolTask task taskQueue.take();ToolResult result executor.execute(task.getToolName(), task.getParams());task.getCallback().accept(result);} catch (InterruptedException e) {Thread.currentThread().interrupt();break;}}});});}public void submit(ToolTask task) {taskQueue.offer(task);}}__五、最佳实践与注意事项5.1 工具设计原则-单一职责每个工具只做一件事保持功能内聚-幂等性相同参数多次调用应返回一致结果-超时控制API调用必须设置合理的超时时间-错误处理区分可重试错误和不可重试错误5.2 安全考虑-敏感信息API密钥等敏感信息不要硬编码使用配置中心或密钥管理服务-参数校验严格校验LLM传来的参数防止注入攻击-调用限流对第三方API调用进行限流保护下游服务5.3 性能优化-结果缓存对于相同参数的请求缓存结果避免重复调用-连接复用使用HTTP连接池复用TCP连接-批量接口如第三方API支持批量查询优先使用批量接口图4Java Tool 接口实现示例六、总结本文详细讲解了Agent工具调用开发的核心组件Tool接口设计、第三方API对接方案、工具注册与调用机制。通过Java实现示例展示了从接口定义到生产环境部署的完整链路。掌握这些内容后开发者能够构建出可对接任意外部系统的智能Agent实现复杂的自动化任务。工具调用能力是大模型Agent与现实世界交互的桥梁合理的设计能让Agent的能力得到充分发挥。希望本文能为你的Agent开发提供有价值的参考。作者洛水石作者洛水石