Skip to content

AgentTool sub-agents cannot see conversation history, so they score paraphrases instead of real data #4

Description

@Shivanshu49

Summary

The agent instructions tell the model that "tools have access to the full
conversation history". For AgentTool-wrapped sub-agents this is not true, and
the mismatch causes sub-agents to score paraphrases instead of real data.

Root cause

AgentTool.run_async does not share the orchestrator's session. It constructs a
fresh Runner with its own InMemorySessionService and passes only
args["request"] — a string the orchestrator LLM composes itself.

Verified in google/adk/tools/agent_tool.py (2.6.2):

request_text = args['request']          # line 246 - the only payload forwarded
...
runner = Runner(                        # line 263 - a brand-new Runner
    ...
    session_service=InMemorySessionService(),   # line 267 - not the caller's session
    memory_service=InMemoryMemoryService(),     # line 268
)

So a sub-agent sees exactly one thing: whatever the orchestrator chose to type
into request. It cannot see the job description, the rubric, earlier tool
results, or anything else in the conversation, regardless of what the prompt
claims.

Relevant instruction text in agent.py today:

Most tools have access to the conversation history and can reference previous messages.

and

Tools have access to the full conversation history, so they can reference previous messages.

Both are inaccurate for every AgentTool in this repo (RubricBuilder,
ResumeReviewer, GitHubReviewer, VerdictSynthesizer).

Observed impact

In a real run, structured repository data was reduced to prose before it reached
the scorer:

  • Real data available at the orchestrator: 3006 stars, 611 forks, 100% of
    inspected repos had a README, 100% had CI.
  • What was actually passed to GitHubReviewer: a ~550-character paraphrase
    stating the repositories had "significant stars and forks".
  • Result: GitHubReviewer reported "Missing data" eight times and scored
    Repository Quality 0/3 — despite the data existing.

VerdictSynthesizer was similarly reduced to "resume score of 10/10 and GitHub
score of 6/10"
, with none of the underlying evidence.

This is quiet rather than loud: every agent returns well-formed output, so the
run looks successful. The only symptom is scores that are lower and vaguer than
the evidence supports.

Suggested fixes

Either would work; they trade off differently:

  1. Pass the data explicitly. Instruct the orchestrator to include the prior
    tool's raw JSON verbatim in the request string. Smallest change, but relies
    on the LLM complying — it is a prompt guarantee, not a structural one.

  2. Give sub-agents an input_schema. The framework already supports this and
    takes a different path when it is set — agent_tool.py validates the whole
    args dict instead of reading only args['request']:

    input_schema = _get_input_schema(self.agent)
    if input_schema:
        input_value = input_schema.model_validate(args)

    Defining a pydantic model per sub-agent means required fields must be supplied
    and cannot be silently dropped. Larger change, but it makes the failure
    structural rather than probabilistic.

Independently, the two instruction sentences quoted above should be corrected
regardless of which fix is chosen — they currently describe behaviour the
framework does not provide.

Environment

  • google-adk 2.6.2
  • Behaviour confirmed by reading AgentTool.run_async in that version

Happy to open a PR for either approach if you have a preference.

Reported by Shivanshu (@Shivanshu49)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions