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:
-
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.
-
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)
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, andthe mismatch causes sub-agents to score paraphrases instead of real data.
Root cause
AgentTool.run_asyncdoes not share the orchestrator's session. It constructs afresh
Runnerwith its ownInMemorySessionServiceand passes onlyargs["request"]— a string the orchestrator LLM composes itself.Verified in
google/adk/tools/agent_tool.py(2.6.2):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 toolresults, or anything else in the conversation, regardless of what the prompt
claims.
Relevant instruction text in
agent.pytoday:and
Both are inaccurate for every
AgentToolin this repo (RubricBuilder,ResumeReviewer,GitHubReviewer,VerdictSynthesizer).Observed impact
In a real run, structured repository data was reduced to prose before it reached
the scorer:
inspected repos had a README, 100% had CI.
GitHubReviewer: a ~550-character paraphrasestating the repositories had "significant stars and forks".
GitHubReviewerreported "Missing data" eight times and scoredRepository Quality 0/3 — despite the data existing.
VerdictSynthesizerwas similarly reduced to "resume score of 10/10 and GitHubscore 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:
Pass the data explicitly. Instruct the orchestrator to include the prior
tool's raw JSON verbatim in the
requeststring. Smallest change, but relieson the LLM complying — it is a prompt guarantee, not a structural one.
Give sub-agents an
input_schema. The framework already supports this andtakes a different path when it is set —
agent_tool.pyvalidates the wholeargsdict instead of reading onlyargs['request']: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-adk2.6.2AgentTool.run_asyncin that versionHappy to open a PR for either approach if you have a preference.
Reported by Shivanshu (@Shivanshu49)