SpringAI之Tool Calling

一、概述

工具调用(也称为函数调用)是 AI 应用程序中的一种常见模式,允许模型与一组 API 或工具进行交互,从而增强其功能。

工具主要用于:

信息检索。此类别中的工具可用于从外部源(如数据库、Web 服务、文件系统或 Web 搜索引擎)检索信息。目标是增强模型的知识,使其能够回答其他方式无法回答的问题。因此,它们可用于检索增强生成 (RAG) 方案。例如,工具可用于检索给定位置的当前天气、检索最新的新闻文章或查询数据库以获取特定记录。

采取行动。此类别中的工具可用于在软件系统中执行作,例如发送电子邮件、在数据库中创建新记录、提交表单或触发工作流。目标是自动执行原本需要人工干预或显式编程的任务。例如,可以使用工具为与聊天机器人交互的客户预订航班,在网页上填写表单,或在代码生成场景中实现基于自动测试 (TDD) 的 Java 类。

二、FunctionCallback API (已弃用)

在SpringAI 1.0.0-M6版本中,Function Calling已被弃用,新的API已迁移到Tools Calling,具体可以到 SpringAI官网 查看具体文档。

三、Tool Calling API

变更概述

这些更改是改进和扩展 Spring AI 中的工具调用功能的更广泛努力的一部分。除其他外,新 API 从 “functions” 改为 “tools” 术语,以更好地与行业惯例保持一致。这涉及多项 API 更改,同时通过已弃用的方法保持向后兼容性。

主要变化

1、FunctionCallback→ToolCallback
2、FunctionCallback.builder().function()→FunctionToolCallback.builder()
3、FunctionCallback.builder().method()→MethodToolCallback.builder()
4、FunctionCallingOptions→ToolCallingChatOptions
5、ChatClient.builder().defaultFunctions()→ChatClient.builder().defaultTools()
6、ChatClient.functions()→ChatClient.tools()
7、FunctionCallingOptions.builder().functions()→ToolCallingChatOptions.builder().toolNames()
8、FunctionCallingOptions.builder().functionCallbacks()→ToolCallingChatOptions.builder().toolCallbacks()

迁移示例

1. 基本函数回调

以前:

FunctionCallback.builder()
    .function("getCurrentWeather", new MockWeatherService())
    .description("Get the weather in location")
    .inputType(MockWeatherService.Request.class)
    .build()

后:

FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
    .description("Get the weather in location")
    .inputType(MockWeatherService.Request.class)
    .build()

2. ChatClient 使用情况

以前:

String response = ChatClient.create(chatModel)
    .prompt()
    .user("What's the weather like in San Francisco?")
    .functions(FunctionCallback.builder()
        .function("getCurrentWeather", new MockWeatherService())
        .description("Get the weather in location")
        .inputType(MockWeatherService.Request.class)
        .build())
    .call()
    .content();

后:

String response = ChatClient.create(chatModel)
    .prompt()
    .user("What's the weather like in San Francisco?")
    .tools(FunctionToolCallback.builder("getCurrentWeather", new MockWeatherService())
        .description("Get the weather in location")
        .inputType(MockWeatherService.Request.class)
        .build())
    .call()
    .content();

3. 基于方法的函数回调

以前:

FunctionCallback.builder()
    .method("getWeatherInLocation", String.class, Unit.class)
    .description("Get the weather in location")
    .targetClass(TestFunctionClass.class)
    .build()

后:

var toolMethod = ReflectionUtils.findMethod(TestFunctionClass.class, "getWeatherInLocation");

MethodToolCallback.builder()
    .toolDefinition(ToolDefinition.builder(toolMethod)
        .description("Get the weather in location")
        .build())
    .toolMethod(toolMethod)
    .build()

或者使用声明式方法:

class WeatherTools {
   
    @Tool(description = "Get the weather in location")
    public void getWeatherInLocation(String location, Unit unit) {
   
        // ...
    }
}

您可以使用相同的 API 来注册基于方法的工具回调:ChatClient#tools()

String response = ChatClient.create(chatModel)
    .prompt()
    .user("What's the weather like in San Francisco?")
    .tools(MethodToolCallback.builder()
        .toolDefinition(ToolDefinition.builder(toolMethod)
            .description("Get the weather in location")
            .build())
        .toolMethod(toolMethod)
        .build()
<think>好的,用户遇到了调用工具时出现游标错误的问题,需要解决。首先,我需要了解“游标错误”具体指的是什么。游标通常与数据库操作相关,尤其是在使用SQL时,游标用于遍历和操作查询结果集。因此,用户可能在调用某个涉及数据库操作的工具时遇到了与游标相关的错误。 接下来,我需要考虑可能导致游标错误的常见原因。可能的原因包括:游标未正确打开或关闭,数据库连接问题,事务未提交导致锁定,资源未释放,或者查询语句错误等。此外,代码中的异常处理不当也可能导致游标状态异常。 然后,根据这些可能的原因,我需要一步步给出解决方案。例如,检查游标的声明和关闭是否正确,确保数据库连接正常,处理事务提交或回滚,释放资源,检查SQL语句是否有语法错误,以及添加适当的异常处理机制。 同时,用户提供的引用内容中提到错误号5166是调用在线帮助时的错误,这可能与数据库连接或外部工具调用有关。另一个引用提到计算k和k的幂次,可能与参数设置或数据处理有关,但暂时不确定是否直接相关,可能需要进一步分析。 最后,我需要生成相关的问题,帮助用户深入排查问题,比如询问数据库连接状态、事务处理方式、游标作用域等。这有助于用户更全面地检查和解决问题。</think>### 调用工具时游标错误的解决方案 #### 1. 检查游标声明与关闭状态 - **未正确关闭游标**可能导致资源泄漏或锁定冲突。确保每次`OPEN CURSOR`后都有对应的`CLOSE CURSOR`操作: ```sql DECLARE cur CURSOR FOR SELECT * FROM table; OPEN cur; -- 打开游标 FETCH NEXT FROM cur; CLOSE cur; -- 必须显式关闭[^2] ``` - **作用域问题**:在Python等语言中,推荐使用`with`语句自动管理游标生命周期: ```python with connection.cursor() as cur: # 自动关闭游标 cur.execute("SELECT * FROM table") ``` #### 2. 验证数据库连接状态 - **连接中断**会直接导致游标失效。通过心跳机制检测连接: ```python if not connection.is_connected(): connection.reconnect() ``` - **事务隔离级别**:检查是否因未提交事务导致游标阻塞。使用`COMMIT`或`ROLLBACK`明确事务边界。 #### 3. 排查查询语句问题 - **语法错误**会立即触发游标异常。建议先在数据库客户端工具中直接运行SQL语句验证: ```sql -- 测试语句是否可执行 EXPLAIN SELECT * FROM table WHERE id=1; ``` - **结果集过大**可能导致内存溢出。使用分页查询优化: ```sql SELECT * FROM table LIMIT 1000 OFFSET 0; ``` #### 4. 异常处理强化 - 在代码中添加多层异常捕获,特别关注游标操作段: ```python try: cursor.callproc("stored_procedure") except DatabaseError as e: if "cursor" in str(e).lower(): logger.error("游标状态异常: %s", e) connection.rollback() finally: cursor.close() ``` #### 5. 资源释放验证 - 检查是否在循环中重复创建游标而未释放: ```java while(condition) { try (Statement stmt = conn.createStatement()) { // 自动关闭 ResultSet rs = stmt.executeQuery(query); } // Java的try-with-resources自动释放 } ``` ### 典型错误场景示例 当使用Python连接MySQL时,未关闭游标会导致`OperationalError`: ```python # 错误示例:未关闭游标 cur = conn.cursor() cur.execute("SELECT SLEEP(10)") # 长时间操作 # 若此处无cur.close(),连接池可能耗尽 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

loser.with.m

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值