首页
/ LangChain4j中Ollama工具调用重复执行问题解析

LangChain4j中Ollama工具调用重复执行问题解析

2025-05-31 01:29:01作者:邓越浪Henry

在LangChain4j项目与Ollama模型集成过程中,开发者发现了一个值得注意的问题:当使用工具调用功能时,工具方法可能会在循环中被多次执行。本文将从技术角度深入分析这一现象的原因,并提供解决方案。

问题现象

在使用LangChain4j的Ollama集成模块时,如果定义一个简单的加法工具方法:

@Tool
int add(int a, int b) {
    log.info("{} + {} is {}",a,b,a+b);
    return a + b;
}

当询问模型"3+4等于多少"时,日志显示该方法被调用了4次,而期望的行为是只调用1次。

根本原因分析

经过深入排查,发现问题出在消息历史记录的构建上。在原始实现中,当AI消息包含工具执行请求时,没有正确地将这些请求转换为Ollama API所需的tool_calls字段格式。

Ollama API规范中,工具调用涉及两个关键部分:

  1. 请求中的tools字段:定义模型可用的工具列表
  2. 消息中的tool_calls字段:记录模型想要调用的具体工具

原始实现缺失了第二个关键部分,导致模型无法正确识别已经执行过的工具调用,从而陷入重复调用的循环。

解决方案

修正方案主要针对OllamaMessagesUtils.otherMessages方法进行改造,当处理AI消息时,如果包含工具执行请求,需要将其转换为Ollama API期望的tool_calls格式:

private static Message otherMessages(ChatMessage chatMessage) {
    if(chatMessage instanceof AiMessage aiMessage){
        if(aiMessage.hasToolExecutionRequests()){
            List<ToolCall> toolCalls = aiMessage.toolExecutionRequests()
                    .stream().map(req->{
                        FunctionCall functionCall = FunctionCall.builder()
                                .name(req.name())
                                .arguments(Json.fromJson(req.arguments(), HashMap.class))
                                .build();
                        return ToolCall.builder()
                                .function(functionCall).build();
                    }).toList();
            return Message.builder()
                    .role(Role.ASSISTANT)
                    .toolCalls(toolCalls)
                    .build();
        }
    }
    return Message.builder()
            .role(toOllamaRole(chatMessage.type()))
            .content(chatMessage.text())
            .build();
}

技术实现细节

  1. 工具调用转换:将LangChain4j内部的ToolExecutionRequest转换为Ollama API所需的ToolCall结构
  2. 参数处理:使用Json工具将参数从字符串格式反序列化为Map结构
  3. 角色标识:保持消息角色(ASSISTANT)的一致性
  4. 兼容性处理:对非AI消息或非工具调用消息保持原有处理逻辑

最佳实践建议

  1. 在使用工具调用功能时,始终开启请求/响应日志记录,便于调试
  2. 对于关键工具方法,添加适当的日志记录和参数验证
  3. 定期检查LangChain4j的更新,获取最新的兼容性修复
  4. 针对不同模型可能需要微调工具调用的参数格式

总结

通过正确实现Ollama API规范中的工具调用消息格式,我们解决了工具方法被重复执行的问题。这一案例也提醒我们,在集成不同AI服务时,准确理解并实现其API规范至关重要。LangChain4j社区已采纳这一修复方案,确保了工具调用功能的稳定性和可靠性。

登录后查看全文
热门项目推荐
相关项目推荐

热门内容推荐

最新内容推荐

项目优选

收起
ohos_react_nativeohos_react_native
React Native鸿蒙化仓库
C++
176
261
RuoYi-Vue3RuoYi-Vue3
🎉 (RuoYi)官方仓库 基于SpringBoot,Spring Security,JWT,Vue3 & Vite、Element Plus 的前后端分离权限管理系统
Vue
860
511
openGauss-serveropenGauss-server
openGauss kernel ~ openGauss is an open source relational database management system
C++
129
182
openHiTLSopenHiTLS
旨在打造算法先进、性能卓越、高效敏捷、安全可靠的密码套件,通过轻量级、可剪裁的软件技术架构满足各行业不同场景的多样化要求,让密码技术应用更简单,同时探索后量子等先进算法创新实践,构建密码前沿技术底座!
C
259
300
ShopXO开源商城ShopXO开源商城
🔥🔥🔥ShopXO企业级免费开源商城系统,可视化DIY拖拽装修、包含PC、H5、多端小程序(微信+支付宝+百度+头条&抖音+QQ+快手)、APP、多仓库、多商户、多门店、IM客服、进销存,遵循MIT开源协议发布、基于ThinkPHP8框架研发
JavaScript
93
15
Cangjie-ExamplesCangjie-Examples
本仓将收集和展示高质量的仓颉示例代码,欢迎大家投稿,让全世界看到您的妙趣设计,也让更多人通过您的编码理解和喜爱仓颉语言。
Cangjie
332
1.08 K
HarmonyOS-ExamplesHarmonyOS-Examples
本仓将收集和展示仓颉鸿蒙应用示例代码,欢迎大家投稿,在仓颉鸿蒙社区展现你的妙趣设计!
Cangjie
398
371
note-gennote-gen
一款跨平台的 Markdown AI 笔记软件,致力于使用 AI 建立记录和写作的桥梁。
TSX
83
4
CangjieCommunityCangjieCommunity
为仓颉编程语言开发者打造活跃、开放、高质量的社区环境
Markdown
1.07 K
0
kernelkernel
deepin linux kernel
C
22
5