Skip to content

Strip other agents' tool calls from conversation history#1677

Open
trungutt wants to merge 2 commits intodocker:mainfrom
trungutt:attempt-to-avoid-hallucination
Open

Strip other agents' tool calls from conversation history#1677
trungutt wants to merge 2 commits intodocker:mainfrom
trungutt:attempt-to-avoid-hallucination

Conversation

@trungutt
Copy link
Contributor

@trungutt trungutt commented Feb 10, 2026

Problem
In conversation where we have multiple agents coordinating with each other by handoff/delegation mechanism (given that each of these agents has different set of tools), this history can contain tool calls from other agents. In subsequent conversation, this causes the agent to hallucinate tool calls for tools it doesn't have access to, because it sees the tool calls in the history and tries to use them again, but with the incorrect agent.

Attempt to fix
When building the message history for an agent in GetMessages(), strip tool calls and their corresponding tool responses from other agents' messages. The text content is still preserved so the agent retains conversational context, but the tool usage patterns that trigger hallucination are removed.

Instead of stripping other agents' tool calls from conversation history (which loses useful context), convert them into plain-text narrative messages with agent attribution, similar to Google ADK's approach.

Prevent agent hallucination by removing tool call patterns from
other agents when building the message history for the current agent.
@trungutt trungutt marked this pull request as ready for review February 10, 2026 13:16
@trungutt trungutt requested a review from a team as a code owner February 10, 2026 13:16
Copy link

@docker-agent docker-agent bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

Found 1 potential issue in the changed code related to tool call ID collision handling. The overall approach of stripping other agents' tool calls looks good, but there's a potential edge case that should be considered.

The shallow copy approach used at line 667 (cleaned := msg) is correct and idiomatic Go - it properly strips the ToolCalls from the returned messages.

// Skip tool responses that belong to another agent's tool calls
if msg.Role == chat.MessageRoleTool && otherAgentToolCallIDs[msg.ToolCallID] {
continue
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential issue: Tool call ID collision could filter legitimate responses

The code collects tool call IDs from other agents (lines 634-647) and then filters out any tool responses matching those IDs. However, if two agents generate the same tool call ID (e.g., OpenAI's short ID format could theoretically produce duplicate IDs across different API calls), this could incorrectly filter out legitimate tool responses from the current agent's previous turns.

Scenario:

  1. Agent A creates tool call with ID "call_abc123" and receives response
  2. Later, Agent B creates a tool call that also gets ID "call_abc123" (collision)
  3. When preparing messages for Agent A again, the tool response from step 1 would be incorrectly filtered out

Suggested fix:
Consider tracking tool call ownership with tuples like map[string]string mapping toolCallID -> agentName, or storing (agentName, toolCallID) pairs in a struct set. This would ensure that only tool responses actually belonging to other agents are filtered.

While ID collisions are rare in practice, this could cause confusing behavior in long-running multi-agent conversations.

startIndex := lastSummaryIndex + 1

// Collect tool call IDs from other agents' assistant messages so we can
// strip both the calls and their corresponding tool-role responses.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should NOT do this, instead we should do something like what ADK does, IIRC ADK converts tool calls to simple "FYI, agent did this and that" user messages

…pping them

Instead of removing other agents' tool calls and responses from history
(losing information), convert them to user-role narrative messages with
attribution, following the ADK approach. This preserves context while
preventing hallucination of tool calls the agent doesn't have.
@trungutt trungutt requested review from a team and rumpl February 10, 2026 15:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants