LangChain4j MCP工具调用参数缺失问题排查
问题分析与解决方案
你的核心问题是LangChain4j Agent在多轮收集字段后,调用工具时仅传入最后一个字段,未携带之前收集的字段。结合代码来看,问题根源在于LLM未被明确要求使用所有已收集字段,且上下文传递方式不够直接,以下是具体修复步骤:
1. 强化System Message指令的明确性
原System Message仅模糊要求"考虑这些字段",未明确约束工具调用时必须传入所有已收集的必填参数。修改为更具强制性的指令,确保LLM明确知道要完整传递参数:
.systemMessageProvider(id -> "你是一个可以调用工具的助手。" + "以下是目前已收集到的所有字段:" + fieldsContext + "\n" + "当调用工具时,必须将所有已收集的必填字段(title、time、attendees)作为参数传入,确保参数完整,不能遗漏任何已收集的字段。" + "若仍有字段缺失,请向用户询问补充。")
2. 将已收集字段直接合并到用户输入中
仅依赖System Message传递上下文,LLM可能在多轮对话中忽略这部分信息。将已收集字段与当前用户输入合并后传入,让LLM更直观地关联所有信息:
// 替换原statefulChat调用 Result<String> replyResult = statefulAgent.statefulChat( "已收集字段:" + fieldsContext + "\n用户当前输入:" + userPrompt, conversationId );
3. 避免每次对话重建Agent实例
当前代码每次调用chat方法都会重新创建ChatAgentStatefulInterface实例,可能导致状态不一致。将Agent实例按会话ID缓存,保持会话状态的持续性:
// 在ChatAgent类中新增Agent缓存Map private final Map<String, ChatAgentStatefulInterface> agentMap = new ConcurrentHashMap<>(); // 在chat方法中替换Agent创建逻辑 ChatAgentStatefulInterface statefulAgent = agentMap.computeIfAbsent(conversationId, id -> AiServices.builder(ChatAgentStatefulInterface.class) .chatModel(chatModel) .toolProvider(mcpToolProvider) .chatMemoryProvider(memId -> memory) .systemMessageProvider(memId -> "你是一个可以调用工具的助手。" + "以下是目前已收集到的所有字段:" + fieldsContext + "\n" + "当调用工具时,必须将所有已收集的必填字段(title、time、attendees)作为参数传入,确保参数完整,不能遗漏任何已收集的字段。" + "若仍有字段缺失,请向用户询问补充。") .build() );
4. 验证字段提取与合并的正确性
在合并字段后添加日志,确认conversationFields确实包含所有已收集的字段,避免字段提取逻辑出错:
// 合并字段后添加日志 System.out.println("当前会话已收集字段:" + conversationFields);
5. 检查工具参数名称匹配性
确保MCP加载的工具方法参数名称(如title、time、attendees)与你收集的字段键名完全一致,否则LLM无法正确映射参数。
额外优化:清理字段缓存
当工具调用成功后,同步清理extractedFieldsMemory中对应会话的记录,避免后续会话混淆:
if (toolSuccessful) { memory.clear(); memoryMap.remove(conversationId); extractedFieldsMemory.remove(conversationId); // 新增这行 agentMap.remove(conversationId); // 同步清理Agent缓存 }
内容的提问来源于stack exchange,提问作者AlexandruJ
相关产品推荐
相关产品推荐

