chat - 工具的输入输出架构
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);
}
}