curated_feed.claude¶
The Anthropic-backed scorer: the one place that talks to a model.
Everything the API needs is decided here — the cache split, the token ceiling, what counts as a failed response — so that score.py stays a protocol, a retry loop and a failure policy, and the rest of the pipeline never learns that a provider exists.
Three choices are worth knowing about.
The policy documents are the system prompt, the candidates are the user turn. That is the boundary policy.py already draws: the documents are byte-identical every run and are most of the tokens, so they carry the cache breakpoint and are read back at a tenth of the price. Interpolating anything volatile above them would silently cost full price on every run.
Responses stream. max_tokens is deliberately generous — truncation is a hard failure rather than a short day — and the SDK refuses a non-streaming request it estimates will outrun the HTTP timeout.
No `thinking` parameter is sent. Models differ in how thinking is configured and which values they accept; the default is the portable choice, and effort (when the configured model supports it) is the knob that matters.
Attributes¶
Classes¶
What a day of scoring cost, in tokens. |
|
Scores a day of candidates with Claude. |
Functions¶
|
A client with credentials resolved by the SDK. |
Module Contents¶
- curated_feed.claude.CACHE_CONTROL¶
- curated_feed.claude.TRUNCATED = 'max_tokens'¶
- curated_feed.claude.REFUSED = 'refusal'¶
- curated_feed.claude.RETRY_INSTRUCTION = Multiline-String¶
Show Value
"""Your previous response did not validate: {feedback} Return the whole response again as valid JSON, corrected."""
- class curated_feed.claude.TokenUsage[source]¶
What a day of scoring cost, in tokens.
Accumulated across attempts, so a day that needed a retry reports what the retry actually cost rather than what the successful call did.
- class curated_feed.claude.AnthropicScorer(*, model: str, max_tokens: int, effort: str = '', timeout_seconds: float | None = None, client: anthropic.Anthropic | None = None)[source]¶
Scores a day of candidates with Claude.
- name = 'anthropic'¶
- model¶
- max_tokens¶
- effort = ''¶
- usage¶
- generate(candidates: collections.abc.Sequence[curated_feed.models.Candidate], prompt: curated_feed.policy.Prompt, *, feedback: str | None = None) str[source]¶
One call: the day’s prompt in, the raw response text out.
- curated_feed.claude.build_client(timeout_seconds: float | None) anthropic.Anthropic[source]¶
A client with credentials resolved by the SDK.
No key is read here on purpose: the SDK also accepts an ant auth login profile and workload identity, so an unset ANTHROPIC_API_KEY does not mean there are no credentials. An actual failure surfaces on the first call.
Public because it is the seam. A scorer built by hand takes its client directly, but the one the pipeline builds cannot: score.make_scorer reads configuration, and a client is not something configuration should hold. This factory is therefore what a test substitutes to run the whole chain against a fake, and a default nobody can substitute is the thing deploy.py already learned to avoid.