当前位置: 首页 > ai >正文

Langchain4j Function Calling (5)

Langchain4j Function Calling(函数调用)

Function Calling 函数调用 也叫 Tools 工具.

不用函数调用存在的问题

测试计算问题

  • 提供agent

    @AiService(wiringMode = AiServiceWiringMode.EXPLICIT,chatModel = "qwenChatModel",chatMemory = "chatMemory",chatMemoryProvider = "chatMemoryProvider"
    )
    public interface SeparateChatAssistant {@SystemMessage(fromResource = "systemMessage.txt")String chat(@MemoryId int memoryId, @UserMessage String userMessage);}
    
  • 进行数学计算测试

    @Resource
    private SeparateChatAssistant separateChatAssistant;@Test
    public void testCalculatorTools() {String answer = separateChatAssistant.chat(1, "1+2等于几,322233222345的平方根是多少?");//答案:567,655.901System.out.println(answer);
    }
    

    image-20250530135936523

    根据模型回复,发现简单计算,模型是可以正常处理的,但是对于复杂计算就无能为力了。

函数调用

创建函数调用tools
@Component
public class CalculatorTools {@Tooldouble sum(double a, double b) {System.out.println("调用加法运算");return a + b;}@Tooldouble squareRoot(double x) {System.out.println("调用平方根运算");return Math.sqrt(x);}}
agent 使用tools
@AiService(wiringMode = AiServiceWiringMode.EXPLICIT,chatModel = "qwenChatModel",chatMemory = "chatMemory",chatMemoryProvider = "chatMemoryProvider",tools = "calculatorTools"
)
public interface SeparateChatAssistant {@SystemMessage(fromResource = "systemMessage.txt")String chat(@MemoryId int memoryId, @UserMessage String userMessage);}
进行数学计算测试

同样使用上面 出问题的测试用例,来对tools进行测试。

    @Resourceprivate SeparateChatAssistant separateChatAssistant;@Testpublic void testCalculatorTools() {String answer = separateChatAssistant.chat(1, "1+2等于几,322233222345的平方根是多少?");//答案:567,655.901System.out.println(answer);}

image-20250530140438445

根据模型输出,我们看到了在Tools工具中输出的日志,发现模型的确调用了我们的工具,同时也看到了数据开方也返回了正确的结果。

函数调用流程

查看存储的记录信息

image-20250530141015904

我们可以明显的看到type=AI的记录信息,在toolExecutionRequests中记录着我们的tools中的函数信息。

分析调用流程
Request:\- messages:\- SystemMessage:\- text: 系统定义AI的角色\- UserMessage:\- text: 用户提问\- AiMessage:\- toolExecutionRequests:\- ai获取提问信息组织参数调用工具方法\- ToolExecutionResultMessage:\- text: 工具方法执行
Response :\- AiMessage:\- text: 根据工具方法的执行ai再次组织结果返回

注解信息

  • @Tool注解

    @Tool 注解有两个可选字段:

    name:工具的名称。如果未提供该字段,方法名会作为工具的名称。

    value:工具的描述信息。

    根据工具的不同,即使没有任何描述,大语言模型可能也能很好地理解它(例如, add(a, b) 就很直观),但通常最好提供清晰且有意义的名称和描述。这样,大语言模型就能获得更多信息,以决定是否调用给定的工具以及如何调用。

    @Tool(name = "sum", value = "sum(a,b)计算a和b的和")
    double sum(double a, double b) {System.out.println("调用加法运算");return a + b;
    }@Tool(name = "squareRoot", value = "squareRoot(x)计算x的平方根")
    double squareRoot(double x) {System.out.println("调用平方根运算");return Math.sqrt(x);
    }
    
  • @P 注解

    方法参数可以选择使用 @P 注解进行标注。

    @P 注解有两个字段:

    value:参数的描述信息,这是必填字段。

    required:表示该参数是否为必需项,默认值为 true ,此为可选字段。

    @Tool(name = "sum", value = "sum(a,b)计算a和b的和")
    double sum(@P(value = "加数1",required = true) double a,@P(value = "加数2",required = true)double b) {System.out.println("调用加法运算");return a + b;
    }@Tool(name = "squareRoot", value = "squareRoot(x)计算x的平方根")
    double squareRoot(@P(value = "平方根数",required = true) double x) {System.out.println("调用平方根运算");return Math.sqrt(x);
    }
    
  • @ToolMemoryId 注解

    如果你的AIService方法中有一个参数使用 @MemoryId 注解,那么你也可以使用 @ToolMemoryId 注解@Tool 方法中的一个参数。提供给AIService方法的值将自动传递给 @Tool 方法。如果你有多个用户,或每个用户有多个聊天记忆,并且希望在 @Tool 方法中对它们进行区分,那么这个功能会很有用。

    @Tool(name = "sum", value = "sum(a,b)计算a和b的和")
    double sum(@ToolMemoryId int memoryId,@P(value = "加数1",required = true) double a,@P(value = "加数2",required = true)double b) {System.out.println("调用加法运算,memoryId: " +   memoryId);return a + b;
    }@Tool(name = "squareRoot", value = "squareRoot(x)计算x的平方根")
    double squareRoot(@ToolMemoryId int memoryId,@P(value = "平方根数",required = true) double x) {System.out.println("调用平方根运算,memoryId: " +   memoryId);return Math.sqrt(x);
    }
    

    image-20250530142718248

    可以明显的看到 @ToolMemoryId标记的字段,成功的拿到了请求的memoryId.

http://www.xdnf.cn/news/9979.html

相关文章:

  • 关于ffplay在macos上运行奔溃的问题
  • 嵌入式开发学习日志(linux系统编程--进程(4)——线程锁)Day30
  • Google car key:安全、便捷的汽车解锁新选择
  • day40打卡
  • Netty 实战篇:为 Netty RPC 框架引入调用链追踪,实现链路透明化
  • 特伦斯 S75 电钢琴:奏响音乐新时代的华章
  • mongodb集群之分片集群
  • Ubuntu 22.04 系统下 Docker 安装与配置全指南
  • Android JNI开发
  • 大语言模型的技术原理与应用前景:从Transformer到ChatGPT
  • 技术原理简析:卫星遥感如何感知水体环境?
  • 基于Matlab实现卫星轨道模拟仿真
  • 云计算Linux Rocky day02(安装Linux系统、设备表示方式、Linux基本操作)
  • vue2 + webpack 老项目升级 node v22 + vite + vue2 实战全记录
  • 【OpenSearch】高性能 OpenSearch 数据导入
  • OpenTelemetry × Elastic Observability 系列(一):整体架构介绍
  • rm删除到回收站
  • 【设计模式】策略模式
  • 【软件】在 macOS 上安装 MySQL
  • Python学习(5) ----- Python的JSON处理
  • 分布式存储技术全景解析:从架构演进到场景实践
  • 私有云大数据部署:从开发到生产(Docker、K8s、HDFS/Flink on K8s)
  • docker部署ELK,ES开启安全认证
  • 基于RK3568/RK3588/全志H3/飞腾芯片/音视频通话程序/语音对讲/视频对讲/实时性好/极低延迟
  • 深入链表剖析:从原理到 C 语言实现,涵盖单向、双向及循环链表全解析
  • vue3 项目配置多语言支持,如何从服务端拿多语言配置
  • 智能柜I立控信息I产品介绍
  • ArcGIS Pro 3.4 二次开发 - 布局
  • Spring Boot 应用中实现配置文件敏感信息加密解密方案
  • 通义灵码2.5——基于编程智能体开发Wiki多功能搜索引擎