Replies: 1 comment
-
|
This is a known challenge with LLM-based agents. Here's what works: 1. State-Based ValidationTrack computed values in state and validate final_answer against it: state = {
"computed_values": {},
"print_history": []
}
def capture_print(value, key=None):
state["print_history"].append(str(value))
if key:
state["computed_values"][key] = value
print(value)
return value
# In final_answer validation
def validate_final_answer(answer):
# Check if values in answer were actually computed
for value in extract_values(answer):
if str(value) not in str(state["computed_values"].values()):
raise ValidationError(f"Value {value} was not computed")2. Two-Phase Approach# Phase 1: Compute only (no final_answer allowed)
agent_compute = CodeAgent(
tools=[...],
system_prompt="Compute all values. DO NOT call final_answer. Store results in variables."
)
result = agent_compute.run(task)
# Phase 2: Format only (read from state)
final = format_results(state["computed_values"])3. Constrained final_answer Tool@tool
def final_answer(answer: str, computed_values: dict) -> str:
# Require agent to explicitly pass what it computed
# Validate against print history
for key, value in computed_values.items():
if str(value) not in state["print_history"]:
return f"ERROR: {key}={value} was not printed. Recompute."
return answerRoot CauseLLMs pattern-match to produce plausible outputs. Without explicit grounding in computed state, they'll hallucinate "reasonable" numbers. The fix is architectural: separate computation from output formatting, and validate against recorded state. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Description:
The
CodeAgentsometimes generates content for thefinal_answertool call directly within a code block, without strictly adhering to the intended workflow of calculating results, printing them, and then assembling the final answer based only on the resultingObservationhistory from previous steps. This leads to hallucinated or unverified final results, even when strong prompt rules are in place.Scenario:
CodeAgentthat requires multi-step data loading, calculation, or analysis.final_answer.CodeAgent's system prompt has been customized with rules explicitly requiring (see "Attempts Made" below):print()for all intermediate results needed for subsequent steps or the final answer (Rule 11/13).final_answercode block from calculation blocks (Rule 12/14).final_answerblock only assembles results using data explicitly printed in previous steps and available inObservationhistory (Rule 14).print()complex final structures first, then callfinal_answerin a subsequent step (Rule 15).final_answer(Rule 16).planning_intervalis set).Observed Behavior:
Instead of following the strict cycle, the agent might:
final_answercall containing a fully formed, complex result structure with numerical values that were never calculated/printed in precedingCodeblocks.Expected Behavior:
The agent should strictly adhere to the cycle:
print()any results/structures needed later.print().final_answerusing only variables/structures that were present in the precedingObservation.Attempts Made:
CodeAgentsystem prompt (viaprompt_templates) emphasizing the use ofprint(), separation offinal_answer, reliance onObservationhistory, printing complex structures first, and pre-final answer validation.planning_interval.Question:
Is this a known limitation or behavior pattern? Are there further prompt engineering strategies, agent configurations, or alternative approaches within
smolagentsrecommended to more reliably prevent the agent from bypassing the observation cycle and hallucinating thefinal_answercontent, especially for complex outputs? Could explicit validation steps be made more robust?Environment:
CodeAgentLocalPythonExecutorBeta Was this translation helpful? Give feedback.
All reactions