实例化Tool
Tool分为StaticTool(静态工具)和DynamicTool(动态工具)两类。静态工具需要开发者事先定义好,即在编译期定义与实例化。对于动态工具,开发者可以在系统运行时动态构建,即在运行态定义与实例化。
StaticTool(静态工具)
静态工具可以通过注解的方式新增,在run接口中实现工具的功能,例如:
import com.huaweicloud.pangu.dev.sdk.api.annotation.AgentTool; import com.huaweicloud.pangu.dev.sdk.api.annotation.AgentToolParam; import com.huaweicloud.pangu.dev.sdk.api.tool.StaticTool; import lombok.Data; @AgentTool(toolId = "reserve_meeting_room", toolDesc = "预订会议室", toolPrinciple = "请在需要预订会议室时调用此工具", inputDesc = "会议开始结束时间,会议室", outPutDesc = "预订会议室的结果") public class ReserveMeetingRoom extends StaticTool<ReserveMeetingRoom.InputParam, String> { @Override public String run(InputParam input) { return String.format("%s到%s的%s已预订成功", input.start, input.end, input.meetingRoom); } @Data public static class InputParam { @AgentToolParam(description = "会议开始时间,格式为HH:mm") private String start; @AgentToolParam(description = "会议结束时间,格式为HH:mm") private String end; @AgentToolParam(description = "会议室") private String meetingRoom; } }
@AgentTool注解说明:
- toolId。表示工具的标识,建议为英文且与实际工具含义匹配,在同一个Agent中唯一。
- toolDesc。工具的描述,为重要参数,尽可能的准确简短描述工具的用途。
- toolPrinciple。表示何时使用该工具,为重要参数。该描述直接影响LLM对工具使用的判断,尽量描述清楚。如果Agent实际执行效果不符合预期,可以调整。
- inputDesc。工具的入参描述,为重要参数。该描述直接影响LLM对入参的提取,尽量描述清楚。如果Agent实际执行效果不符合预期,可以调整。
- outputDesc。工具的出参描述,当前对Agent的表现无重要影响。
如果输入输出参数为复杂类型,则需要通过AgentToolParam注解定义复杂类型的参数描述,此时inputDesc、outputDesc可以填空字符串,但仍然建议给出简要的描述。当前版本不支持复杂类型中再嵌套复杂类型,只支持基本类型:String、Number、Boolean,建议参数数量不超过5个。
@AgentToolParam注解说明:
- description。参数的描述,为重要参数。该描述直接影响LLM对入参的提取,尽量描述清楚,如果Agent实际执行效果不符合预期,可以调整。
- required。是否为可选参数。
注意:字段的命名需要以小写字母开头,否则在转换成标准的Json schema时会出现问题,导致模型精度受到影响。
上例中的InputParam为一个复杂的入参,如果工具的入参为基本类型,则不需要再额外定一个结构体,例如:
import com.huaweicloud.pangu.dev.sdk.api.annotation.AgentTool; import com.huaweicloud.pangu.dev.sdk.api.tool.StaticTool; @AgentTool(toolId = "capital", toolDesc = "资产注册查询", toolPrinciple = "请在需要查询各个公司的资产注册情况时调用此工具", inputDesc = "需要查询的公司名称,一次只支持查询一家公司", outPutDesc = "公司的资产注册规模") public class CapitalQuery extends StaticTool<String, String> { @Override public String run(String input) { switch (input) { case "x公司": return "x亿人民币"; case "y公司": return "y亿人民币"; case "z公司": return "z亿人民币"; default: return "未知"; } } }
DynamicTool(动态工具)
- 动态工具可以在业务运行态动态新增或修改,例如:
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.huaweicloud.pangu.dev.sdk.api.tool.DynamicTool; private static DynamicTool buildAddTool() { final DynamicTool addTool = new DynamicTool(); addTool.setToolId("add"); addTool.setToolDesc("加法运算"); addTool.setToolPrinciple("请在需要做两个整型的加法运算时调用此工具"); addTool.setInputDesc("加法输入"); addTool.setOutputDesc("加法运算的结果"); addTool.setInputSchema( "{\"type\":\"object\",\"properties\":{\"a\":{\"type\":\"integer\",\"description\":\"加法运算的数字\"},\"b\":{\"type\":\"integer\",\"description\":\"加法运算的数字\"}},\"required\":[\"a\",\"b\"]}"); addTool.setOutputSchema("{\"type\":\"integer\"}"); addTool.setFunction(s -> { final JSONObject jsonObject = JSON.parseObject(s); final Integer a = jsonObject.getInteger("a"); final Integer b = jsonObject.getInteger("b"); return a + b; }); return addTool; }
其中,toolId、toolDesc、toolPrinciple、inputDesc、outputDesc的定义与说明与静态工具相同。
inputSchema:工具入参的JsonSchema。
outputSchema:工具出参的JsonSchema。
- 复杂对象JsonSchema示例:
{ "type": "object", "properties": { "a": { "description": "加法运算的数字", "type": "integer" }, "b": { "description": "加法运算的数字", "type": "integer" } }, "required": ["a","b"] }
- 简单对象JsonSchema示例:
{ "type": "integer" }
- 枚举对象JsonSchema示例:
{ "type": "object", "properties": { "chargeType": { "type": "string", "enum": ["Alipay", "Wechat", "Bankcard"], "description": "充值类型" }, "amount": { "type": "integer", "description": "充值金额" } }, "required": ["chargeType", "amount"] }