Agent with Checkpointer Reusing Tool Results in Continuing Conversations

Hi, I’m using LangChain v1 (TypeScript) with createAgent and MongoDBSaver checkpointer for a RAG application. I’m experiencing behaviour where tool results seem to be reused across conversation turns instead of making fresh tool calls.

Setup:

  • LangChain v1.x (TypeScript)

  • createAgent with MongoDBSaver checkpointer

  • Custom retrieval tool with parameters captured in closure (e.g., groupIds)

  • Multi-turn conversations

Observed Behaviour:

  • Request 1 (new conversation):

    • question: “When was Company1 formed?”
    • groupIds: [“681…”, “684…”]
    • //Works - retrieval tool called, correct results
  • Request 2 (continuing conversation):

    • question: “What is Company2 fiscal year?”
    • conversationId: “69123…” // same conversation
    • groupIds: [“681…”, “684…”] // SAME groupIds

    // Returns wrong results - citations show Company1 docs from Request 1

What I Expected:

  • Agent loads conversation history (Q&A about Company1)

  • Agent sees NEW question about Company2

  • Agent calls the retrieval tool with a fresh query

  • Tool performs a new vector search (same groupIds, different semantic query)

  • Returns Company2 documents

What Actually Happens:

  • Agent returns “not found” or Company1 information

  • Citations show the SAME documents from Request 1

  • Tool is either not called or returns cached results

What I’ve Tried:

  1. Middleware to filter ToolMessages:

    export const filterToolMessagesMiddleware = createMiddleware({
    
        name: 'FilterToolMessages',
    
        beforeModel: async (state: { messages: BaseMessage[] }) => {
    
            const filtered = state.messages.filter(msg => 
    
                !(msg instanceof ToolMessage) && 
    
                !(msg instanceof AIMessage && msg.tool_calls?.length > 0)
    
            )
    
            return { messages: filtered }
    
        }
    
    })
    
    const agent = createAgent({
    
        model: llm,
    
        tools: [retrievalTool],
    
        checkpointer,
    
        middleware: [filterToolMessagesMiddleware]
    
    })
    
  • Result: Still reuses old results
  1. Manual checkpoint management (current workaround):

    // Load checkpoint manually
    
    const existingState = await checkpointer.get(threadConfig)
    
    const existingMessages = existingState?.channel_values?.messages || []
    
    // Filter out tool messages
    
    const conversationHistory = existingMessages.filter(msg => 
    
        !(msg instanceof ToolMessage) && 
    
        !(msg instanceof AIMessage && msg.tool_calls?.length > 0)
    
    )
    
    // Create agent WITHOUT checkpointer
    
    const agent = createAgent({
    
        model: llm,
    
        tools: [retrievalTool]
    
        // NO checkpointer
    
    })
    
    // Invoke with filtered history
    
    const result = await agent.invoke({
    
        messages: [...conversationHistory, new HumanMessage(question)]
    
    })
    
    // Save manually
    
    await checkpointer.put(threadConfig, {
    
        channel_values: { messages: result.messages }
    
    })
    

Result: Works - fresh tool calls every time

Questions:

  1. Is this expected behaviour when using createAgent with a checkpointer?

  2. Should middleware be sufficient to prevent tool result reuse?

  3. Is manual checkpoint management the recommended approach for this use case?

  4. Am I missing something in my implementation?

Any guidance would be greatly appreciated!

Environment:

  • LangChain: v1.x (TypeScript)

  • Node.js: v24

  • Checkpointer: MongoDBSaver

hi @juancarlos_la

this is actually very weird imho. I would expect that either the LLM calls the tool per unique query or the framework reuses the response for the same query.

What LLM model are you using?

I’m using anthropic.claude-3-sonnet-20240229-v1:0.

I’ve created a bug for it here, with more detailed information: Agent with Checkpointer Reuses Tool Results in Multi-Turn Conversations · Issue #9384 · langchain-ai/langchainjs · GitHub

great, thanks!
btw this is for python, not javascript, repo Agent with Checkpointer Reuses Tool Results in Multi-Turn Conversations · Issue #33936 · langchain-ai/langchain · GitHub - it should not be there