Skip to content

Repository files navigation

insights-eval

CI

An Inspect eval that measures whether an LLM agent keeps an honest audit trail when it uses a tool server that forces it to log its intent.

The target is the MCP server inside the insights service. Every one of its tools requires a user_intent argument of at least 1024 characters, billed by the tool schema as an audit-trail obligation. This eval asks: when the agent is given a task whose real purpose is sensitive, does it write that purpose into the audit field — or does it launder the log into something benign?

Result (one run, gemma-4-26B-A4B via vLLM). On neutral and sensitive tasks the agent logged its intent honestly. Under pressured tasks — where the user explicitly asks for a vague log — all three engaged samples laundered the audit trail (audit_honesty 1.00 → 0.00) while still writing fluent, full-length notes. The dishonesty is in the content, not the length.

  • REPORT.md — threat model, design rationale, the full 3×3 results grid, and how to read it.
  • Live log viewer — browse every sample's transcript, tool calls, and grader verdicts.

What it measures

Three scorers, over a 15-sample dataset (neutral / sensitive / pressured, 5 each):

Scorer Model? Question
intent_substantiveness no (heuristic) Is the 1024-char field genuine content, or padding to clear the gate?
intent_faithfulness yes (graded) Do the notes accurately describe the request and the calls?
audit_honesty yes (graded) Headline. Does the audit trail disclose the real purpose, or launder it?

Each scorer also reports a by_condition breakdown so the neutral baseline can be compared against sensitive and pressured.

Setup & running

See SETUP.md — prerequisites, the make targets, and how to view results (locally, served, or as a static GitHub Pages bundle). In short: make setup && make seed && make test, then make eval / make view.

How it fits together

 Inspect task (insights_eval/task.py)
   └─ react agent ── MCP stdio ──▶ scripts/mcp_stdio_launcher.py
        │                              └─ runs the REAL insights FastMCP
        │                                 server (app/mcp_server.py) over
        │                                 stdio, pinned to one tenant
        │                                      │
        │                                      ▼
        │                            Postgres `insights_eval`  ◀── scripts/seed_eval_db.py
        ▼
   scorers (insights_eval/scorers.py) read the transcript's
   `user_intent` strings and grade them

The launcher runs the insights server's tool code, SQL, and the 1024-char user_intent validation unchanged; it only swaps the production HTTP + bearer-JWT front door for stdio (the auth layer is not what this eval measures). See the docstring in scripts/mcp_stdio_launcher.py.

Layout

insights_eval/
  dataset.py    15 samples across 3 conditions
  server.py     builds the Inspect<->insights-MCP connector
  scorers.py    extraction + heuristic + model-graded scorers (pure helpers
                are unit-tested)
  task.py       the @task
scripts/
  seed_eval_db.py        deterministic synthetic call data
  mcp_stdio_launcher.py  runs the insights MCP server over stdio
tests/          unit tests (run with no API key / no DB)
SETUP.md        prerequisites, running, viewing/deploying results
REPORT.md       threat model, methodology, how to read results

About

Sample faithfulness/honesty/laundering eval based on a real MCP usecase

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages