Solon v3.10.0

chat - 工具 @ToolMapping 开发详解

</> markdown
2026年4月1日 下午10:01:33

在 Solon AI 中,函数工具(Function Tools)共有四种定制方式。其中 @ToolMapping 是最便捷的开发方式,它通过注解自动将普通的 Java 方法映射为大模型的 Tool 定义。虽然在极致的灵活性上略逊于手动构建,但足以覆盖 90% 的业务场景。

1、工具定义示例:

通过在类方法上添加 @ToolMapping,你可以快速定义可供 LLM 调用的功能。支持 Solon 原生的组件注解(如 @Component),从而支持依赖注入和 AOP 拦截。

import org.noear.solon.ai.annotation.ToolMapping;
import org.noear.solon.annotation.Param;
import org.noear.solon.annotation.Body;
import org.noear.snack.annotation.ONodeAttr;

//可以加组件注解(支持注入和拦截)
public class Tools {
    //天气查询
    @ToolMapping(description = "获取指定城市的天气情况")
    public String get_weather(@Param(name = "location", description = "根据用户提到的地点推测城市") String location) {
        return "晴,24度"; //可使用 “数据库” 或 “网络” 接口根据 location 查询合适数据;
    }
    
    
    //订单查询
    @ToolMapping(description = "联网查询")
    public String web_search(@Body QueryDo queryDo) {
        return "..."; 
    }
    
    public static class QueryDo {
        @Param(name = "query", description = "查询关键字,多个词用空格隔开") 
        String query;
        
        @ONodeAttr(name = "limit", description = "返回的最大结果条数")
        int limit = 10;
    } 
}

2、 应用集成示例

使用 ChatModel 发起对话时,可以通过 options 将工具类动态添加(也可以要构建 ChatModel 作为默认工具添加)。

public void testToolCall() throws IOException {
    chatModel.prompt("今天杭州的天气情况?")
             .options(o -> o
                 // 方式 A:显式通过 MethodToolProvider 包装
                 .toolAdd(new MethodToolProvider(new Tools()))
                 // 方式 B:直接传入实例(内部会自动识别注解并转换)
                 .toolAdd(new OtherTools()) 
             )
             .call();
}

3、@ToolMapping 属性说明

@ToolMapping 负责将 Java 方法元数据转换为 FunctionTool 接口属性。它会自动根据方法参数生成 inputSchema,根据返回类型生成 outputSchema

属性类型描述备注
nameString工具标识名称缺省时默认使用方法名
titleString工具显示标题常用于 MCP Tool 管理界面展示
descriptionString核心描述告知 LLM 何时该调用此工具(极其重要)
metaString元数据JSON 格式,用于扩展自定义属性
returnDirectboolean是否直接返回(默认为 false)若为 true,LLM 执行完工具后不进行思考,直接返回结果给用户
resultConverterClass结果转换器用于对工具执行结果进行二次加工

4、参数注解说明:@Param、@Body

Solon AI 沿用了 Solon MVC 的通用注解,降低了学习成本。

a) @Param 属性描述:

可用于修饰方法参数或实体字段。

属性名默认值描述
value / name/参数名称(若缺省,自动取参数变量名)
description/参数语义描述,帮助 LLM 理解参数含义
requiredtrue是否必填。若为 true,LLM 必须提取出该参数
defaultValue/默认值
format/类型格式描述(建议符合 json-schema 规范,有些 llm 会比较严格)

b) 参数提取逻辑

方法参数层面:

  • 只有带 @Param@Body 的参数才会进入 inputSchema。
  • 不带注解的参数将被忽略(通常用于注入 “工具上下文” 对象)。

实体类(POJO)对象层面:

  • 实体内的字段默认全部进入 inputSchema
  • 字段没有注解时,默认为“非必填”。
  • 支持使用 @ONodeAttr(Snack4 注解)或自定义注解来定义字段描述。