Java Function Calling 案例详解
Function Calling(函数调用)是AI模型与外部系统交互的重要机制,下面我将通过几个典型案例,展示如何在Java中实现和使用Function Calling。

基础函数调用案例
1 定义函数接口
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
import java.util.function.Function;
// 定义函数接口
@FunctionalInterface
public interface ToolFunction<R> {
R apply(String arguments);
}
// 天气查询函数
public class WeatherFunction implements Function<String, String> {
@Override
public String apply(String city) {
// 模拟天气查询
return String.format("城市:%s,当前温度:25°C,天气:晴", city);
}
}
// 计算器函数
public class CalculatorFunction implements Function<String, String> {
@Override
public String apply(String expression) {
try {
// 简单表达式计算
String[] parts = expression.split(" ");
double num1 = Double.parseDouble(parts[0]);
String operator = parts[1];
double num2 = Double.parseDouble(parts[2]);
double result = switch (operator) {
case "+" -> num1 + num2;
case "-" -> num1 - num2;
case "*" -> num1 * num2;
case "/" -> num2 != 0 ? num1 / num2 : Double.NaN;
default -> throw new IllegalArgumentException("不支持的运算符");
};
return String.format("计算结果:%.2f", result);
} catch (Exception e) {
return "计算错误:" + e.getMessage();
}
}
}
2 函数注册中心
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
public class FunctionRegistry {
private final Map<String, Function<String, String>> functions = new HashMap<>();
public void registerFunction(String name, Function<String, String> function) {
functions.put(name, function);
}
public String executeFunction(String name, String arguments) {
Function<String, String> function = functions.get(name);
if (function == null) {
return "函数未找到: " + name;
}
return function.apply(arguments);
}
public boolean hasFunction(String name) {
return functions.containsKey(name);
}
public Map<String, Function<String, String>> getAllFunctions() {
return new HashMap<>(functions);
}
}
集成OpenAI Function Calling
1 函数定义注解
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AITool {
String name();
String description();
}
2 工具类实现
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
public class AIToolExecutor {
private final Map<String, Method> tools = new HashMap<>();
private final ObjectMapper mapper = new ObjectMapper();
public AIToolExecutor(Object service) {
registerTools(service);
}
private void registerTools(Object service) {
for (Method method : service.getClass().getDeclaredMethods()) {
if (method.isAnnotationPresent(AITool.class)) {
AITool annotation = method.getAnnotation(AITool.class);
tools.put(annotation.name(), method);
}
}
}
public ObjectNode getToolsDefinition() {
ObjectNode toolsNode = mapper.createObjectNode();
ArrayNode toolsArray = toolsNode.putArray("tools");
for (Map.Entry<String, Method> entry : tools.entrySet()) {
ObjectNode toolNode = toolsArray.addObject();
toolNode.put("type", "function");
ObjectNode functionNode = toolNode.putObject("function");
AITool annotation = entry.getValue().getAnnotation(AITool.class);
functionNode.put("name", annotation.name());
functionNode.put("description", annotation.description());
// 生成参数schema
ObjectNode parametersNode = generateParameterSchema(entry.getValue());
functionNode.set("parameters", parametersNode);
}
return toolsNode;
}
public String executeTool(String toolName, String arguments) {
Method method = tools.get(toolName);
if (method == null) {
return "Tool not found: " + toolName;
}
try {
// 解析参数并执行
JsonNode argsNode = mapper.readTree(arguments);
Object[] args = parseArguments(method, argsNode);
Object result = method.invoke(serviceInstance, args);
return mapper.writeValueAsString(result);
} catch (Exception e) {
return "Error executing tool: " + e.getMessage();
}
}
}
完整的使用案例
1 配置OpenAI客户端
<!-- Maven依赖 -->
<dependency>
<groupId>com.theokanning.openai-gpt3-java</groupId>
<artifactId>service</artifactId>
<version>0.18.2</version>
</dependency>
import com.theokanning.openai.OpenAiService;
import com.theokanning.openai.completion.chat.*;
import com.theokanning.openai.function.FunctionDefinition;
public class OpenAIClient {
private final OpenAiService service;
private final FunctionRegistry functionRegistry;
public OpenAIClient(String apiKey, FunctionRegistry functionRegistry) {
this.service = new OpenAiService(apiKey);
this.functionRegistry = functionRegistry;
}
public String chatWithFunctions(String userMessage) {
// 构建函数定义
List<FunctionDefinition> functions = new ArrayList<>();
functions.add(createWeatherFunction());
functions.add(createCalculatorFunction());
// 构建请求
ChatCompletionRequest request = ChatCompletionRequest.builder()
.model("gpt-3.5-turbo")
.messages(Arrays.asList(
new ChatMessage(ChatMessageRole.SYSTEM.value(), "你是一个有用的助手,可以使用工具来回答问题。"),
new ChatMessage(ChatMessageRole.USER.value(), userMessage)
))
.functions(functions)
.functionCall("auto")
.build();
// 发送请求并处理响应
ChatCompletionResult result = service.createChatCompletion(request);
ChatMessage response = result.getChoices().get(0).getMessage();
// 处理函数调用
if (response.getFunctionCall() != null) {
return handleFunctionCall(response);
}
return response.getContent();
}
private String handleFunctionCall(ChatMessage message) {
ChatFunctionCall functionCall = message.getFunctionCall();
String functionName = functionCall.getName();
String arguments = functionCall.getArguments();
// 执行函数
String functionResult = functionRegistry.executeFunction(functionName, arguments);
// 将结果返回给AI
ChatMessage functionMessage = ChatMessage.builder()
.role(ChatMessageRole.FUNCTION.value())
.name(functionName)
.content(functionResult)
.build();
// 再次调用AI获取最终回答
ChatCompletionRequest request = ChatCompletionRequest.builder()
.model("gpt-3.5-turbo")
.messages(Arrays.asList(
new ChatMessage(ChatMessageRole.SYSTEM.value(), "你是一个有用的助手"),
message,
functionMessage
))
.build();
ChatCompletionResult result = service.createChatCompletion(request);
return result.getChoices().get(0).getMessage().getContent();
}
}
2 实际应用示例
public class CustomerServiceAgent {
private final AIToolExecutor toolExecutor;
private final OpenAIClient aiClient;
public CustomerServiceAgent(String apiKey) {
this.toolExecutor = new AIToolExecutor(new CustomerServiceTools());
this.aiClient = new OpenAIClient(apiKey,
createFunctionRegistry());
}
public String handleCustomerRequest(String request) {
return aiClient.chatWithFunctions(request);
}
private static class CustomerServiceTools {
@AITool(name = "get_order_status",
description = "获取订单状态")
public String getOrderStatus(@JsonProperty("order_id") String orderId) {
// 查询订单状态
return String.format("订单 %s 当前状态: 已发货", orderId);
}
@AITool(name = "check_inventory",
description = "检查商品库存")
public String checkInventory(@JsonProperty("product_id") String productId) {
// 检查库存
return String.format("商品 %s 库存: 100件", productId);
}
@AITool(name = "calculate_refund",
description = "计算退款金额")
public String calculateRefund(
@JsonProperty("order_amount") double orderAmount,
@JsonProperty("days_used") int daysUsed) {
double refundAmount = orderAmount * (1 - daysUsed * 0.1);
return String.format("退款金额: ¥%.2f", Math.max(refundAmount, 0));
}
}
}
高级用法
1 异步函数调用
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class AsyncFunctionExecutor {
private final ExecutorService executor = Executors.newFixedThreadPool(10);
public CompletableFuture<String> executeAsync(String functionName, String arguments) {
return CompletableFuture.supplyAsync(() -> {
return executeFunction(functionName, arguments);
}, executor);
}
public CompletableFuture<Map<String, String>> executeParallel(
Map<String, String> functionCalls) {
List<CompletableFuture<Map.Entry<String, String>>> futures =
new ArrayList<>();
for (Map.Entry<String, String> call : functionCalls.entrySet()) {
CompletableFuture<Map.Entry<String, String>> future =
executeAsync(call.getKey(), call.getValue())
.thenApply(result -> Map.entry(call.getKey(), result));
futures.add(future);
}
return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.thenApply(v -> futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));
}
}
2 带缓存的函数调用
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
public class CachedFunctionExecutor {
private final Cache<String, String> cache;
private final FunctionRegistry functionRegistry;
public CachedFunctionExecutor(FunctionRegistry functionRegistry) {
this.functionRegistry = functionRegistry;
this.cache = Caffeine.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTES)
.maximumSize(1000)
.build();
}
public String executeWithCache(String functionName, String arguments) {
String cacheKey = functionName + ":" + arguments;
String cachedResult = cache.getIfPresent(cacheKey);
if (cachedResult != null) {
return cachedResult;
}
String result = functionRegistry.executeFunction(functionName, arguments);
cache.put(cacheKey, result);
return result;
}
}
测试示例
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class FunctionCallingTest {
@Test
public void testWeatherFunction() {
FunctionRegistry registry = new FunctionRegistry();
registry.registerFunction("get_weather", new WeatherFunction());
String result = registry.executeFunction("get_weather", "北京");
assertTrue(result.contains("北京"));
assertTrue(result.contains("25°C"));
}
@Test
public void testCalculatorFunction() {
FunctionRegistry registry = new FunctionRegistry();
registry.registerFunction("calculate", new CalculatorFunction());
String result = registry.executeFunction("calculate", "10 + 20");
assertEquals("计算结果:30.00", result);
result = registry.executeFunction("calculate", "100 / 4");
assertEquals("计算结果:25.00", result);
}
@Test
public void testUnknownFunction() {
FunctionRegistry registry = new FunctionRegistry();
String result = registry.executeFunction("unknown_func", "test");
assertTrue(result.contains("函数未找到"));
}
}
Function Calling 是AI应用开发中的核心模式,它实现了:
- 功能扩展:让AI能够访问外部系统和数据
- 准确性提升:通过真实数据而非模型猜测
- 可维护性:功能模块化,易于更新和扩展
- 安全性:可以控制AI能访问哪些功能
在实际项目中,建议:
- 明确定义函数接口和参数
- 实现错误处理和超时机制
- 合理使用缓存提高性能
- 做好安全验证和权限控制
通过这些案例,你可以构建强大且可靠的Java Function Calling系统。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播