Black-box uncertainty quantification for LLM workflows running on commercial APIs (OpenAI, DeepSeek, Gemini). Measures whether failure-prediction signals — verbalized confidence, token entropies, chain-of-thought entropy — survive contact with tool-calling agents on closed APIs, and turns them into a usable selective-coverage policy.
Companion to D'Urso, "Hidden-Uncertainty Assessment via Non-Verbalized Signatures for LLM Medical QA", IEEE Access 2026 — same Trust-Abstain framing, now on closed agent workflows instead of open-weight single-turn QA.
- Agent workflow in Pydantic AI with structured output (
NativeOutput/PromptedOutput) and client-side tool dispatch — so token logprobs stay attached to the JSON value tokens that encode the model's decision. Nativetool_callswould drop them. - Signal panel computed per step: verbalized confidence, token-level entropies over
tool/args/confidence/rationalespans, and — where exposed (DeepSeek) — entropies over the chain-of-thought. - Selective-coverage evaluation: rank tasks by uncertainty score, gate post-execution, measure conditional accuracy and cost-per-valid-task.
BFCL multi_turn_base — 200 tasks, 8 environment classes, 162 tool functions, state-based ground truth (vendored under src/agent_uncertainty_bench/bfcl_vendor/ to avoid dep conflicts).
| Provider | Model | Logprobs | CoT logprobs |
|---|---|---|---|
| OpenAI | GPT-4.1 | ✅ | — |
| DeepSeek | V4 Pro / V4 Flash | ✅ | ✅ (both, via patch) |
| Vertex AI | Gemini 2.5 Pro / Flash | ✅ | — (thinking tokens leak; see code) |
Anthropic, GPT-5, Grok-4, Mistral excluded — APIs return no logprobs.
- No universal signal. Best signal differs per model:
entropy_confidence(GPT-4.1),verbalized(DS-Pro),entropy_reasoning(DS-Flash),entropy_tool(Gemini). Best AUC range: 0.61 – 0.74. - Selective coverage at 30%, ranking by per-model best signal: +10 to +22 percentage points of accuracy on the kept tasks, -3% to -38% on cost-per-valid-task. Same rule across the panel.
- Verbalized confidence alone collapses on GPT-4.1 and Gemini 2.5 Pro (mean 98 regardless of outcome). Works surprisingly well on DeepSeek V4 Pro (AUC 0.74).
src/agent_uncertainty_bench/
agent_loop.py # Pydantic AI workflow, per-step signal logging
schema.py # dynamic StepDecision (discriminated union per task)
signals.py # token-entropy aggregators, span alignment
eval_run.py # cost + BFCL state-based checker
reasoning_logprobs_hook.py # patches Pydantic AI to expose DeepSeek CoT logprobs
bfcl_vendor/ # vendored BFCL env classes + checker + data
scripts/
batch_run.py # run N tasks against a model, JSONL per task
run_all.sh # full 5-model panel
recompute_signals.py # re-derive signals from raw logprobs without re-calling APIs
midrun_analysis.py # aggregate + AUC + cost summary
experiments/notebooks/
01_first_results.ipynb # all figures and tables
tests/ # pytest, no API calls
uv sync
cp .env.example .env # fill API keys + AGENTS_UQ_OUTPUT_DIR
uv run scripts/batch_run.py --model gpt-4.1 --n 10 # smoke
uv run scripts/run_all.sh 200 # full panel
uv run jupyter lab experiments/notebooks/01_first_results.ipynbPython 3.12, uv, Pydantic AI (provider wrapper), OpenAI SDK (also for DeepSeek via base_url), google-genai (Vertex AI), scikit-learn (AUC), seaborn (plots).
MIT.