# Advanced Agents From First Principles 18: What Should Your Agent Observe Next? Use Expected Value of Information # Book: Advanced Agents From First Principles # Chapter URL: https://programmer.ie/books/advanced-agents-from-first-principles/18-chapter/ # Prose fingerprint (sha256, normalized): 3509c0a012e7cdfd159cff4c39dfe13b640cf301c3e72a80047f0a708713f4d3 # Snapshot generated at build time by Hugo. This is the complete rendered prose # of the chapter; it is not a transcript of the source file. What Should Your Agent Observe Next? Your agent is uncertain. That does not tell you what to do. In the previous post we split uncertainty into operational categories: interpretation uncertainty, evidence uncertainty, route uncertainty, state uncertainty, tool uncertainty, candidate uncertainty, verification uncertainty. That is already better than one generic confidence score. But it still leaves a harder question: Which piece of information is worth buying next? Suppose a coding agent is trying to fix a failing test. It could: inspect git diff, rerun the failing test, run the full test suite, inspect a stack trace, search the repository, read a dependency’s source, ask a stronger model, generate three alternative patches, run static analysis, inspect runtime state, or stop and report that it does not know. All of those actions can produce information. They are not equally useful. They do not cost the same amount. And, crucially, many of them may produce information that cannot change the agent’s next decision. That leads to the central rule of this post: Do not buy information because it is available. Buy information when it has a reasonable chance of changing a decision enough to justify its cost. This is the practical role of Expected Value of Information. Not as an academic ornament. As a runtime control mechanism. 1. Information Is Not Automatically Valuable Agents often confuse activity with progress. A research agent can retrieve twenty more documents. A coding agent can inspect ten more files. A browser agent can click through six more pages. A DevOps agent can request five more dashboards. Yet none of that means the decision became better. Consider this situation: current decision: choose patch A possible observation: inspect README formatting conventions If the bug concerns a race condition in a database transaction, that observation may have almost no chance of changing the patch decision. Its information value is near zero. Now compare: current decision: choose patch A possible observation: run the failing concurrency test under the candidate patch That observation can directly change whether patch A remains acceptable. Its information value may be high. The difference is not how much information the action returns. The difference is whether the result can change a consequential choice. 2. The Decision Comes Before the Observation A useful information-gathering policy starts by identifying the pending decision. Bad pattern: uncertain ↓ gather more information ↓ gather more information ↓ gather more information Better: pending decision ↓ what uncertainty blocks it? ↓ which observation could resolve that uncertainty? ↓ is that observation worth its cost? ↓ observe / decide / stop The runtime therefore needs to know more than: confidence = 0.61 It needs something closer to: DecisionState( decision="apply_patch_A_or_B", alternatives=["patch_A", "patch_B"], dominant_uncertainty="behavioral_evidence", current_preference="patch_A", decision_margin=0.08, ) Now candidate observations can be evaluated against the actual decision boundary. 3. A Minimal Expected-Value-of-Information Model You do not need a perfect Bayesian model to get value from this idea. A practical approximation is enough. For a possible observation o: EVI(o) ≈ probability observation changes the decision × expected improvement if it does − observation cost For software systems, cost is multi-dimensional: cost = model calls + tool calls + tokens + money + wall-clock latency + side-effect risk + opportunity cost You may represent these separately rather than forcing them into one scalar. The important principle is comparison. If observation A is cheap and frequently decisive while observation B is expensive and rarely decisive, A should normally happen first. 4. Decision Value, Not Information Volume A full repository index may contain more information than one failing test result. But if the pending decision is: Did this patch fix the bug? then one exact test result can be more valuable than thousands of repository embeddings. This matters because agent systems are naturally attracted to large information surfaces: vector stores, search engines, long contexts, multi-agent discussion, broad retrieval, huge traces. Yet information volume and decision value are different quantities. A tiny observation can dominate a giant context if it sits directly on the decision boundary. 5. Separate Information Actions From Transformation Actions This distinction is critical in production agents. An information action primarily reduces uncertainty: inspect state, run a read-only query, execute a test in a sandbox, retrieve documentation, measure a metric, compare candidate scores, check deployment health, ask a verifier. A transformation action changes the world: merge code, deploy, delete data, send an email, refund money, restart production infrastructure, modify permissions. Advanced agents should often prefer cheap information actions before irreversible transformation actions. uncertain state ↓ cheap observation ↓ reduced uncertainty ↓ commitment This is one reason diagnostics are so powerful. A diagnostic can prevent an expensive wrong action. 6. Information Gain Is Not Enough Suppose an observation greatly reduces uncertainty about something irrelevant. That does not make it useful. Imagine a research agent deciding whether claim X is supported. It can retrieve: another biography of the author, the primary dataset, a news article discussing the paper, the paper’s appendix, a social-media thread. The biography might reduce uncertainty about the author’s career. But if the decision is whether claim X follows from the data, that information has little decision value. Expected Value of Information is therefore decision-sensitive information gain. 7. Observation Candidates Should Be Explicit The runtime should generate or enumerate possible information-gathering actions. For example: from dataclasses import dataclass @dataclass(frozen=True) class ObservationCandidate: name: str uncertainty_type: str expected_decision_change: float expected_reliability: float estimated_cost: float side_effect_risk: float = 0.0 A simple heuristic value can be: def observation_value(o: ObservationCandidate) -> float: return ( o.expected_decision_change * o.expected_reliability - o.estimated_cost - o.side_effect_risk ) This is not mathematically complete. It is operationally useful. Most importantly, it makes the runtime’s assumptions visible. 8. Rank Observations Against the Current Decision A compact chooser might look like this: def choose_observation(candidates): scored = [ (observation_value(candidate), candidate) for candidate in candidates ] scored.sort(key=lambda item: item[0], reverse=True) best_value, best = scored[0] if best_value <= 0: return None return best The important return value is sometimes None. That means: no available observation is worth buying. At that point the system should: decide with current evidence, abstain, return UNKNOWN, or escalate because the consequence justifies it. But it should not keep gathering information merely because it can. 9. The Value of a Test Depends on the Decision Consider three coding-agent decisions. Decision A Does the file parse? Best observation: run parser / compiler Decision B Does the change fix the bug? Best observation: run the reproduction / failing test Decision C Is the patch safe to merge? Now the observation set changes: focused test full regression suite static analysis lint security checks review diff state verification The same action can have different information value under different decisions. That is why a runtime should not have one universal list called: things to inspect before finishing It should reason from the pending decision. 10. State Observations Often Have Extremely High Value When exact state is observable, direct inspection frequently dominates model inference. Examples: git status kubectl get pods SELECT ... HTTP GET filesystem stat browser DOM inspection queue depth transaction status CI job result If the question is: what state is the system currently in? then asking an LLM to infer that state from history is often irrational. The model may be strong. The source of truth is stronger. Step 17 called this state uncertainty. Expected Value of Information tells us why direct observation is often the correct next purchase. 11. Freshness Changes Information Value An observation is not permanently valuable. Suppose a deployment health check passed ten minutes ago. The system has since deployed a new version. The old observation should not retain full value. Useful metadata includes: state_id observation_time source freshness_window version scope A simple freshness factor could be: def freshness(age_seconds: float, ttl_seconds: float) -> float: if ttl_seconds <= 0: return 0.0 return max(0.0, 1.0 - age_seconds / ttl_seconds) Then: effective observation value = base value × freshness Again, the exact equation is less important than the architecture. Freshness is part of evidence quality. 12. Correlated Observations Can Waste Budget Suppose a research agent retrieves five articles that all summarize the same press release. That is not five independent pieces of evidence. Similarly: five model critiques may share the same base-model bias, five search results may repeat the same source, five tests may exercise the same path, five agents may have nearly identical prompts. The value of the fifth correlated observation can be much lower than the first. A production EVI layer should therefore track: source overlap model overlap prompt overlap data overlap failure-mode overlap Observation diversity matters when independent confirmation is what the decision needs. 13. Retrieval Should Be Treated as an Information Purchase Retrieval is often treated as an unconditional first step: query ↓ retrieve top-k ↓ LLM But retrieval also has cost: latency, context consumption, irrelevant evidence, stale evidence, anchoring risk. A better runtime asks: What decision is blocked? What evidence is missing? Can retrieval plausibly supply it? Which source is most authoritative? What is the cheapest retrieval likely to discriminate between alternatives? Sometimes top_k=20 is worse than top_k=2. More evidence can dilute better evidence. 14. Search Is Valuable Only When Future Branches Can Change the Decision Tree search, beam search and MCTS are all expensive information-generation mechanisms. They produce information about: what might happen if we continue down this branch? That can be valuable. But if one branch already has overwhelming verified evidence, continued search may have negative value. This yields a stopping rule: Stop search when plausible future observations are unlikely to change the selected branch enough to justify their cost. That is more principled than: for _ in range(20): expand_tree() 15. Candidate Search vs Evidence Gathering These are easy to confuse. Suppose the agent has two candidate patches. If the problem is: neither candidate seems promising then more candidate generation may help. But if the problem is: both candidates seem plausible and we lack evidence to choose then generating five more candidates may be wasteful. You need discriminating evidence. The distinction is: candidate uncertainty → generate/search alternatives evidence uncertainty → gather discriminating evidence Step 17 classified the uncertainty. Step 18 chooses the observation. 16. Verification Is an Information-Gathering Action Too Verification is not merely the final step. It is one of the most valuable information mechanisms in the system. A verifier answers questions like: Did the patch actually fix the bug? Did the browser action actually submit the form? Did the deployment actually become healthy? Does the source actually support the claim? Did the data pipeline actually preserve the invariant? The difference is that verification usually evaluates a concrete state against explicit criteria. That makes verifier calls particularly valuable near commitment boundaries. 17. Protect Verification From Speculative Consumption Step 16 introduced protected verification reserves. Expected Value of Information makes the reason even clearer. Suppose the system has enough budget for ten model/tool actions. If it spends all ten generating alternatives, then cannot afford the test that determines whether any alternative works, the allocation was irrational. A sensible budget might be: total budget: 100 units speculation ceiling: 70 verification reserve: 30 The actual numbers depend on the domain. The principle does not. Do not spend all your budget generating hypotheses and leave nothing to test them. 18. Expected Value Can Be Negative Some observations are actively harmful. Examples: stale memory that anchors the agent, low-quality web results, noisy model critiques, irrelevant logs, expensive tests with negligible coverage, speculative agents that flood the context with duplicate ideas. Information acquisition has downside. So: EVI < 0 is meaningful. The correct action is sometimes not to observe. 19. A Better Runtime Interface A useful information scheduler can expose explicit decisions: from dataclasses import dataclass from typing import Optional @dataclass(frozen=True) class InformationAction: name: str targets_uncertainty: str expected_decision_change: float expected_reliability: float expected_cost: float expected_latency_ms: float reversible: bool = True @dataclass(frozen=True) class InformationDecision: action: Optional[InformationAction] reason: str policy_version: str Then: def select_information_action(actions): best = None best_value = 0.0 for action in actions: value = ( action.expected_decision_change * action.expected_reliability - action.expected_cost ) if value > best_value: best = action best_value = value if best is None: return InformationDecision( action=None, reason="no_positive_value_observation", policy_version="voi-v1", ) return InformationDecision( action=best, reason=f"highest_expected_information_value={best_value:.3f}", policy_version="voi-v1", ) The important thing is not this formula. It is that the runtime can explain: why this observation was purchased what uncertainty it targeted what it was expected to change what it cost what it actually changed 20. Measure Expected vs Actual Information Value Every information action creates a calibration opportunity. Before: expected probability of decision change = 0.65 expected cost = 2 units After: decision changed = yes verified outcome improved = yes actual cost = 2.4 units Over many runs you can ask: Do state refreshes rescue tasks as often as expected? Do extra critiques actually change decisions? Does broad retrieval improve verified outcomes? Does full regression testing change merge decisions enough to justify latency? Does a stronger model add information or just paraphrase the same belief? That turns EVI from a hand-designed heuristic into an empirical control policy. 21. Distinguish Decision Change From Outcome Improvement An observation can change the decision and still make the result worse. That means we need two metrics: decision-change rate outcome-improvement rate For example: critic changed decision: 42% verified improvement: 9% verified regression: 13% That critic has high influence but poor net value. Likewise: extra retrieval changed answer: 51% verified improvement: 7% The information mechanism is active. It is not necessarily useful. 22. Measure Information Value by Failure Mode Averages can hide where observations help. Suppose run_full_tests has low average value. But stratification shows: simple syntax tasks → near-zero incremental value cross-module refactors → high value concurrency changes → very high value README edits → negative value after lint Then the scheduler should learn conditional value. Not: always run full suite and not: never run full suite but: run it when the decision boundary and task class justify it 23. Coding Agent Example Suppose the task is: Fix failing test test_retry_after_timeout The agent has a candidate patch. Current uncertainty: behavioral correctness: high repository state: low syntax correctness: low Possible actions: A. inspect another implementation file B. ask stronger model to review patch C. run focused failing test D. run full test suite E. generate three alternate patches A rough ranking might be: C: high decision value, low cost B: medium value, medium cost D: high value, high cost E: low value before focused evidence A: low value unless test points there The rational sequence is likely: run focused test ↓ if FAIL → inspect evidence / revise if PASS → run broader regression as merge decision approaches Not: generate more patches first 24. Research Agent Example Task: Determine whether paper P supports claim X. Current state: secondary sources agree primary paper not yet inspected Possible observations: A. retrieve five more summaries B. inspect paper abstract C. inspect methods/results section D. ask another model whether claim sounds plausible E. search social media discussion The primary methods/results section has the highest decision value. This is obvious to a human researcher. Agent runtimes need to encode the same discipline. 25. Browser Agent Example Task: Submit a form successfully. Current uncertainty: Did the final submission actually happen? Possible observations: A. inspect DOM confirmation message B. reload page C. inspect network response D. click submit again E. ask model whether screenshot looks successful The highest-value action may be: inspect deterministic page/network state Clicking submit again is not information gathering. It risks duplicate side effects. This is why information-vs-transformation matters. 26. Data Agent Example Task: Transform dataset while preserving row-level invariants. Possible observations: schema validation row counts null-rate comparison sample inspection full invariant query LLM review A good scheduler chooses observations based on the invariants that could change the accept/reject decision. If row-count preservation is mandatory, an exact count has enormous value and tiny cost. The LLM review may have nearly zero incremental value. 27. DevOps Agent Example Task: Recover a degraded service. Possible information actions: inspect health checks query error-rate metrics inspect recent deploy check dependency status fetch logs compare canary vs baseline Transformation actions: restart service rollback deploy scale replicas change configuration A strong agent should often buy targeted observations before transformation. For example: recent deploy + rising error rate ↓ compare canary and previous version ↓ if evidence discriminates strongly ↓ rollback That is a much safer loop than: service unhealthy ↓ restart everything 28. Multi-Agent Systems Need EVI Too Calling another agent is an information action. A critic is an information action. A debate round is an information action. A specialist is an information action until it causes a side effect. So the runtime should ask: Will another agent likely provide independent evidence? Will it change the decision? Is its error correlated with the existing agents? What does it cost? If three agents already agree for the same reason, a fourth clone is unlikely to have high information value. A differently instrumented verifier may be more valuable. 29. Stronger Models Are Information Purchases Too Escalating from a local or cheap model to a frontier model is often treated as a capability step. It is better viewed as an information purchase. Ask: What uncertainty would the stronger model reduce? How often has escalation changed this kind of decision? How often has that change improved verified outcomes? What is the incremental cost? This produces a measurable escalation EVI. That is more useful than: confidence < 0.7 → call expensive model 30. Stop When No Observation Can Change the Decision Suppose the system has: strong primary evidence, deterministic state confirmation, successful verification, low route uncertainty, no plausible alternative with meaningful advantage. At that point more information can become pure waste. A practical stopping condition is: max expected value of remaining observations <= 0 or, more conservatively: max plausible decision change < decision margin Then stop gathering information. This is one of the most important ways advanced agents avoid infinite analysis. 31. Some Decisions Need More Evidence Than Others Information value depends on consequence. For a low-risk formatting change: cheap validation may be enough For a database migration: rollback plan schema checks shadow execution backup confirmation invariant checks post-migration verification may all have high value. The more consequential the transformation, the greater the value of strong precondition and postcondition evidence. So risk belongs in the EVI policy. 32. EVI Is Not Permission to Learn Safety Boundaries Some observations are mandatory regardless of estimated value. Examples: authorization checks permission checks sandbox validation prohibited-action checks required compliance checks mandatory verification The runtime should not say: authorization check probably won't change decision, skip it Those are invariants. Expected Value of Information optimizes inside the permitted control space. It does not erase safety boundaries. 33. A Practical Action Taxonomy Information actions can be classified as: STATE_OBSERVATION EVIDENCE_RETRIEVAL DIAGNOSTIC EXPERIMENT SIMULATION CANDIDATE_EVALUATION VERIFICATION SPECIALIST_QUERY CRITIQUE COUNTERFACTUAL_REPLAY Each should expose: target uncertainty expected reliability estimated cost estimated latency source authority freshness scope side-effect risk That gives the scheduler enough structure to compare them. 34. Log the Counterfactual Alternatives If the system chooses one observation, record what it did not choose. Example: { "decision": "choose_next_information_action", "selected": "run_focused_test", "alternatives": [ "ask_stronger_model", "generate_more_candidates", "run_full_suite" ], "expected_values": { "run_focused_test": 0.72, "ask_stronger_model": 0.21, "generate_more_candidates": 0.09, "run_full_suite": 0.44 } } Later, offline replay can ask: Was the chosen observation actually the best one? Without logging alternatives, policy improvement is much harder. 35. Useful Metrics At minimum track: observation selection accuracy actual decision-change rate verified improvement after observation verified regression after observation cost per useful observation latency per useful observation information value calibration error redundant-observation rate correlated-evidence rate stale-observation rate misallocated-information budget verification starvation rate UNKNOWN rate And by action type: state refresh rescue rate retrieval rescue rate diagnostic rescue rate critic net value escalation net value verification net value 36. Compare Against Simple Baselines A sophisticated EVI scheduler should beat simple policies. Useful baselines: always inspect state first always retrieve top-k always run focused test always call critic always escalate below threshold fixed diagnostic sequence random information action And compare under the same maximum resource envelope. If a hand-written sequence performs just as well, keep the hand-written sequence. Do not build an EVI engine because the phrase sounds intelligent. 37. Ablate the EVI Features Suppose your information policy uses: uncertainty type decision margin source authority estimated cost freshness historical rescue rate risk class Ablate them. Maybe freshness matters enormously. Maybe source authority matters. Maybe decision margin adds nothing. Maybe the whole learned policy collapses to: if exact state is available: inspect it elif required evidence is missing: retrieve primary source elif verification is weak: verify else: stop That would be an excellent result. Simplification is success. 38. Avoid Fake Precision Do not pretend that: EVI = 0.7314 is meaningful unless the inputs are actually calibrated. Early systems should use coarse categories: high / medium / low expected decision impact high / medium / low reliability cheap / moderate / expensive cost Then gather data. Then calibrate. The architecture matters before the decimal places do. 39. Expected Value Should Be Empirical Over time you can estimate values from trajectories. For each action type and task class: how often did it change the decision? how often did that improve verified outcome? how much did it cost? how much latency did it add? what uncertainty did it actually reduce? Then: historical value(action | task_class, uncertainty_type) becomes a useful prior. This connects directly to Steps 13–16: trajectory observability ↓ verified outcomes ↓ policy learning ↓ budget scheduling ↓ information-action value estimates 40. But Keep the Policy Reversible The information policy should be: versioned, diffable, replayable, shadowable, canaried, reversible. Example: policy_version: voi-v3 rules: - when: state_uncertainty_high prefer: authoritative_state_read - when: evidence_uncertainty_high prefer: primary_source_retrieval - when: verification_uncertainty_high prefer: acceptance_check - when: candidate_uncertainty_high prefer: bounded_search This is a better first implementation than another LLM deciding what information to gather. 41. Shadow the Information Policy Before allowing a new policy to control production: production chooses action A candidate policy recommends action B Record both. Then evaluate: Would B have been cheaper? Would B have changed the decision? Would B have improved verified outcome? Only after sufficient evidence should the policy control real actions. 42. Failure Modes An EVI system can fail in several recognizable ways. Observation addiction The agent keeps buying evidence after the decision is already stable. Cheap-noise bias Low-cost but low-authority observations crowd out expensive decisive evidence. Expensive-probe bias The agent assumes expensive observations must be better. Correlated evidence accumulation The system buys the same evidence repeatedly through different wrappers. Verification starvation Speculative evidence gathering consumes the acceptance budget. Stale evidence reuse Old observations retain too much weight after state changes. Decision-detached retrieval The system retrieves broadly without identifying what decision the evidence should affect. Learned policy drift A policy calibrated under one model/tool set becomes wrong after the environment changes. These should be first-class diagnostic labels. 43. Failure Injection You can test the information policy deliberately. Inject: stale state conflicting sources missing primary evidence low-quality correlated search results misleading critic wrong route score partial verifier outage expensive but useless tool cheap decisive diagnostic Then ask: Did the scheduler choose the observation that should resolve the uncertainty? This is far more informative than asking only whether the final answer was correct. 44. The Full Runtime Loop We can now combine the previous stages: request ↓ interpret task ↓ identify current state ↓ decompose uncertainty ↓ identify pending decision ↓ enumerate candidate information actions ↓ estimate decision value / cost ↓ choose observation ↓ update state and uncertainty ↓ choose / search / act ↓ verify ↓ PASS / FAIL / UNKNOWN This is much more disciplined than: LLM thinks LLM thinks more LLM asks another LLM LLM decides 45. Why This Matters for Advanced Agents Advanced agents are fundamentally systems for allocating computation. They decide: which model to call, which branch to expand, which tool to use, which critic to invoke, which memory to retrieve, which evidence to gather, which verifier to run, when to stop. Expected Value of Information gives these choices a unifying principle: Buy the observation most likely to improve the pending decision per unit of cost, while preserving mandatory safety and verification constraints. That is a much stronger design rule than: more reasoning is better 46. The Most Important Optimization May Be Fewer Calls A good information scheduler may discover that many expensive mechanisms rarely change decisions. For example: second critic → almost never useful full retrieval → usually redundant frontier escalation → useful only in one task class MCTS → unnecessary when verifier is cheap broad search → inferior to one deterministic diagnostic Then the architecture should shrink. That is the recurring theme of this entire series: Advanced agents are not defined by how much machinery they contain. They are defined by how intelligently they allocate machinery to real failure modes. 47. A Practical Default Policy If you need a simple first version, use this order: 1. Is exact current state directly observable? → inspect it. 2. Is required external evidence missing? → retrieve or measure the most authoritative source. 3. Are there multiple plausible candidates with insufficient discrimination? → run the cheapest decisive test or verifier. 4. Are candidates genuinely weak? → search/generate alternatives. 5. Is model capability itself the bottleneck? → escalate. 6. Is verification still incomplete? → spend reserved verification budget. 7. Can no available observation materially change the decision? → decide, abstain, or return UNKNOWN. This alone will outperform a surprising number of complicated agent loops. 48. Final Rule The final rule is simple: Information is valuable only when it can change a decision or strengthen the evidence required to justify that decision. Your agent does not need to know everything. It needs to know what matters next. And then it needs to stop when learning more no longer changes what it should do. That is how an advanced agent becomes less like an endlessly talking model and more like an evidence-driven decision system. What Comes Next Once the runtime can choose information-gathering actions based on expected decision value, the next question is unavoidable: What happens when several observations, branches, models, or tools can run in parallel? The next stage is parallel speculative execution: launching independent low-risk branches concurrently, cancelling losers early, accounting for critical-path latency rather than total work, and ensuring speculative work cannot leak irreversible side effects into production.