Repository navigation
Add web-search arms to the tool pilot (web only, and web plus the PolicyEngine tool) - #235
Merged
Merged
Conversation
…icyEngine tool) `run --arm web` offers the provider's own web search in place of calculate_household, and `--arm web+pe` offers both. The PE arm is unchanged: its notices hash to what the published runs recorded. - OpenAI: the Responses API's web_search tool. Anthropic: web_search_20260209 (dynamic filtering). Gemini: googleSearch with server-side tool invocations, plus a litellm 1.88.1 patch, since litellm otherwise drops search whenever function tools are present. - policybench.org and GitHub are blocked where the provider allows it. Gemini's API takes no domain list, so its queries are audited instead. - Each response's searches are logged and priced at list on top of their tokens. Gemini invocations are billed once per id. Anthropic server calls get no client result, and a paused search turn is sent back unchanged. - `score` writes searches.csv and audits any search that touches the benchmark or a blocked domain. Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
- Pause detection: a JSON reply is continued only when a server call has no result in the same response, as Anthropic documents. A finished search with no answer gets a nudge. A pause still unfinished after 3 continuations ends the household, because text after an unfinished call is a 400. - Deferred server results: when Claude calls a server tool beside a client tool, the next response carries the result without the call. litellm 1.88.1 drops it from later requests, and a live probe got the 400 on the third. The result now moves onto the message that made the call. Two live re-probes ran four requests clean. - No text follows an unfinished server call: the cap notice is withheld, and the refusal of any later calculation says the same. - A continuation goes back without a prompt-cache mark. Marking turns its text into a block list, which litellm rebuilds in another order. - Search-only turns count toward the turn cap in the web arms. - OpenAI: request each search's source URLs, so the audit sees results as well as opened pages. Count search actions apart from billed calls. - Audit: flag households whose searches name PolicyBench or reach a blocked domain, and report scores without them. Mark Gemini's results as not visible. score.json no longer writes NaN. - Bootstrap: better/worse/same now come from one difference, so every household lands in exactly one. A pinned example caught the old boundary case. Published counts are unchanged. Co-Authored-By: Claude Opus 5.5 <[email protected]>
A boolean filter built from an empty list selected no columns rather than no rows, so score failed on Claude's runs, which made no searches. The masks are now arrays, and a test covers the empty case. Co-Authored-By: Claude Opus 5.5 <[email protected]>
`run --prompt v2-pilot` sends the board's prompt with its four PolicyEngine-naming output definitions (Medicaid, CHIP, free and reduced-price school meals; d1705) rewritten in neutral terms. The same rewrite applies to the answer and repair tools. Each rewrite states the convention the reference follows where the law alone wouldn't settle it, read from policyengine-us 2.41.0: - everyone aged 5 to 17 is a K-12 student; - no meal support without one; - free meals include universal-free-meals states and state-paid copays; - someone eligible for Medicaid is not CHIP-eligible. A guard refuses any board text the model sees that still names PolicyEngine. Tests render all 100 households and check that only the four definitions change, and that the meal wording matches every reference. `--forbid-benchmark-search` tells a web arm not to search for PolicyBench or its published answers, and not to use any PolicyBench page, code or data (Max, 2026-10-21). Rows are labeled `@v2-pilot` and `+no-benchmark-search`. This is a pilot stand-in for v2, not the v2 board wording. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…ot wording The first neutral wording said 'in any eligibility group', and GPT-6 Sol counted QI, a limited-benefit Medicare Savings Program, as Medicaid in scenario_001 (both spouses) in the v2 trial. policyengine-us models the Medicare Savings Programs apart from is_medicaid_eligible. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…tion Max ruled in d1263 (2026-10-13) to keep the section 1 rate schedule and to state the convention in the v2 prompt. Web access finds the IRS Tax Table: in the v2 trial GPT-6 Sol answered scenario_000 from it, $1.45 off the schedule reference. Co-Authored-By: Claude Opus 5.5 <[email protected]>
MaxGhenis
marked this pull request as ready for review
October 21, 2026 12:29
Contributor
Author
|
Merging at b8231bf.
This is internal pilot tooling only. No board condition, published number or release changes. 🤖 Generated with Claude Code |
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is an internal pilot, not a board condition. The board's
no_toolscondition is unchanged.What
scripts/tool_pilot_argon.py run --arm {pe,web,web+pe}:webgives the provider's own web search in place ofcalculate_household.web+pegives both.peis unchanged. A test pins its notices to the sha256 the published runs recorded.Rows are labeled
<model>+weband<model>+web+pe-tool.Why
Max asked what web access would cost, and whether web plus the PolicyEngine tool is cheaper than web alone. This PR adds the arms and was used for a 5-household trial. A 100-household run waits on his call.
How each provider is wired
Checked 2026-10-20 against each provider's docs and with live probes.
OpenAI (GPT-6 Sol)
web_searchtool withfilters.blocked_domains.include=["web_search_call.action.sources"]so the audit sees each search's result URLs.web_search_callat $10 per 1,000. That is an upper bound: the pricing page doesn't say whetheropen_pageandfind_in_pageare billed.search_actionscounts searches alone.Anthropic (Opus 5.5)
web_search_20260209(dynamic filtering) withblocked_domains.usage.server_tool_use.web_search_requestsat $10 per 1,000.srvtoolu_*) get no client result.Gemini (Argon)
googleSearchwith server-side tool invocations.What the blocked domains actually cover
The list is policybench.org, github.com and githubusercontent.com:
excludeDomainsand returns no result URLs, so its reading can't be audited.*.github.io(PolicyEngine's generated docs) is not blocked.scorewritessearches.csv, flags any household whose searches name PolicyBench or reach a blocked domain, and reports scores without those households. For Gemini it marks results as not visible.Trial (households 000–004, list prices)
What the searches show. 44% of Sol's and 56% of Argon's web-only queries name PolicyEngine. The prompts name PolicyEngine in four output definitions (d1705). In 2 of the 5 households, Argon searched for PolicyBench itself, for example
"Inspect household #000" "policybench". That text is on policybench.org and not in the prompt.Full record:
~/reviews/policybench-tool-pilot-2026-10/web-arms/README.md.v2-pilot prompts and the no-answer-key rule (Max, 2026-10-21)
--prompt v2-pilot. There are no model-ready v2 prompts yet: #173 is an unactivated fact slice with no output request, and it names PolicyEngine throughout. So this option keeps the board's prompts and rewrites only what Max has ruled on:The rewrite also covers the answer and repair tools. A guard refuses any board text the model sees that still names PolicyEngine.
--forbid-benchmark-search. Tells a web arm not to search for PolicyBench or its answers.Tests.
Trial on v2-pilot with the rule. Households 000–004, commit b8231bf, $4.86, cost per household at list (v1 → v2-pilot):
Earlier wording, found in the first v2 run: "in any eligibility group" led Sol to count QI as Medicaid. It is fixed.
Invariants (property tests)
cost_usdequalstoken_cost_usdplus searches × list price / 1,000, and the spend counter matches. This holds for every provider and both web arms, including households with repair turns and a truncated-and-retried turn.paired_bootstrap's better/worse/same now come from one difference, so every household lands in exactly one. Hypothesis found a=0.125, b=a+1e-12 landing in none. The case is pinned as an example, and the published counts are unchanged.Tests and review
~/reviews/policybench-tool-pilot-2026-10/web-arms/review/review_r2_opus.md. Its low-severity findings go to a follow-up PR.🤖 Generated with Claude Code