Projects
A project is one or more judgments in dependency order.load
base: where relative source paths in a dict spec resolve. Ignored for paths.
run
hunch run: asks what the store lacks, materializes each table, prints the same lines, returns the project.
results
Judging one row
judge
Per question it returns:
The shape depends on the project:
- One judgment, or
nodegiven:{question: answer}. - Several judgments:
{judgment: {question: answer}}. A judgment whosewhereexcluded this row isNone. Aunionjudgment is left out. - A
type: multiquestion appears as one yes/no answer per option, named<question>__<option>.
judge uses asyncio.run; inside a running loop use ajudge. With shadow, the candidate runs in a non-daemon thread after judge returns, so a script waits for it at exit.
ajudge
judge: same arguments and return. A shadow candidate runs as a background task in the current loop; its failures go to stderr, never raised.
Costs and errors
Both ask the engine for answers the store lacks, except:- A cost cap.
HUNCH_MAX_COST(read whenhunchis imported), orhunch.core.MAX_COST = 0.0at runtime. If one judgment’s missing answers would cost more, nothing is asked andSystemExitis raised with a message such asintent: would ask 1 answers in 1 requests (~$0.0001), above --max-cost $0.0; nothing asked. - A missing input column raises
KeyError, for example"command_guard: state needs ['command']".
SystemExit; catch it around judge in long-running code.
Pydantic classes as specs
Needs thepydantic extra. Each field becomes one question:
spec_from_model
cls may also be a bare output type such as Literal["spam", "ham"] or bool. That becomes one question named output, asked with description. judgment defaults to the class name in snake case. Any other spec key (tests, redact, where, …) can be passed through **spec.
spec_from_agent
deps if its instructions need them, and stops at its first request.
Question names are Pydantic AI’s with
. written as __: a list field topics becomes one yes/no question per option, topics__refund, topics__login. act, gold and escalate still go in Field(json_schema_extra={"hunch": {...}}) and apply to every question of that field; they are not sent. judgment defaults to the output class name in snake case (agent for a bare output type).
Raises ValueError when the agent asks a route question first (several output types, or tools), has a system_prompt, or has instructions that depend on the prompt (it is recorded twice, with different prompts, to tell), and TypeError when state is not a string. Works from async code: the recording runs on a thread of its own.
judge_model
spec_from_model and returns an instance of cls. For a bare output type it returns the value itself.
to_model
cls from answers shaped {question: {"label": ...}}, converting each label to the type the field declares: bool, the Literal or Enum value, a list for list[...], the IntEnum level, None for “none of these”.
Also exported
Everything else in
hunch.core is internal and not a stable API.