Solon v3.3.1

chat - 工具的输入输出架构

</> markdown

1、工具输出给 llm 的描述形态

这个形态下 parameters 属性是一个 jsonSchema 规范的结构。也就是工具的“输入架构”(mcp 里的叫法)

{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "获取指定城市的天气情况",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "根据用户提到的地点推测城市"
                }
            },
            "required": [
                "location"
            ],
            "additionalProperties": False
        },
        "strict": True
    }
}

2、工具注册给 mcp 的描述形态

这个形态下多了 outputSchema (符合 jsonSchema 规范的输出架构)属性,且 parameters 属性变成了 inputSchema(可以与 outputSchema 呼应上)。

{
    "name": "get_weather",
    "description": "获取指定城市的天气情况",
    "inputSchema": {
        "type": "object",
        "properties": {
            "location": {
                "type": "string",
                "description": "根据用户提到的地点推测城市"
            }
        },
        "required": [
            "location"
        ],
        "additionalProperties": False
    },
    "outputSchema": {
        "type": "string"
    }
}

3、构建工具的 outputSchema(输出架构)定义

(v3.2.2 后支持)

使用 FunctionToolDesc 描述工具时(即手动构建),通过 returnType 申明

import org.noear.solon.ai.chat.tool.FunctionToolDesc;

FunctionToolDesc toolDesc = new FunctionToolDesc("get_weather")
    .description("获取指定城市的天气情况")
    .stringParamAdd("location", "根据用户提到的地点推测城市")
    .returnType(String.class)
    .doHandle(args -> {
        return "晴,24度"; // + weatherService.get(location);
    })

使用 MethodFunctionTool 描述工具时(即 @ToolMapping 注解函数构建),通过方法返回类型自动申明

import org.noear.solon.annotation.Param;
import org.noear.solon.ai.annotation.ToolMapping;
import org.noear.solon.ai.mcp.server.annotation.McpServerEndpoint;

@McpServerEndpoint(sseEndpoint = "/mcp/sse")
public class Tools {
    @ToolMapping(description = "获取指定城市的天气情况")
    public String get_weather(@Param(name = "location", description = "根据用户提到的地点推测城市") String location) {
        return "晴,24度"; // + weatherService.get(location);
    }
}

如果返回的是实体结果时,还可以通过 @Param 注解增加描述

import org.noear.solon.annotation.Param;
import org.noear.solon.ai.annotation.ToolMapping;
import org.noear.solon.ai.mcp.server.annotation.McpServerEndpoint;

public class UserInfo {
    @Param(description = "用户名")
    private String name;

    @Param(description = "年龄")
    private Integer age;

    @Param(description = "性别。0表示女,1表示男")
    private Integer gender;
}

@McpServerEndpoint(sseEndpoint = "/mcp/sse")
public class Tools {
    @Inject
    UserService userService;

    @ToolMapping(description = "获取用户信息")
    public UserInfo getUserInfo(@Param(description = "用户ID") Long userId) {
        return userService.getUser(userId);
    }
}