Zum Inhalt

Overview

package wittgenstein_agent_guardrails

wittgenstein-agent-guardrails — reusable scope-guardrail middleware for pydantic-ai agents.

Classes

  • ScopeSource — Something that knows whether a question is answerable from its data.

  • GuardrailAgent — Wraps a pydantic-ai Agent with a scope pre-check.

Functions

  • make_grounding_validator — Build a pydantic-ai @agent.output_validator that rejects answers produced without retrieving any grounding facts this turn.

wittgenstein_agent_guardrails.ScopeSource

mkapi_definition_mkapi class ScopeSource()

Bases : Protocol

Something that knows whether a question is answerable from its data.

Deliberately decoupled from any specific data store (knowledge graph, vector index, fixture file, ...) so GuardrailAgent stays reusable — implement this against whatever backs a given agent's knowledge.

Methods

  • is_in_scope — Return True if question matches something this source knows about.

wittgenstein_agent_guardrails.ScopeSource.is_in_scope

mkapi_definition_mkapi method ScopeSource.is_in_scope(question: str) → bool

Return True if question matches something this source knows about.

wittgenstein_agent_guardrails.make_grounding_validator

mkapi_definition_mkapi make_grounding_validator(facts_accessor: Callable[[DepsT], list], ungrounded_message: str = DEFAULT_UNGROUNDED_MESSAGE) → Callable[[Any, str], Any]

Build a pydantic-ai @agent.output_validator that rejects answers produced without retrieving any grounding facts this turn.

facts_accessor(ctx.deps) should return whatever the agent's tools accumulated during the run (e.g. knowledge-graph triplets fetched by a query tool). This is a cheap circuit breaker for "answered without looking anything up" — it does not perform entailment/NLI between the answer text and the facts, mirroring the pragmatic, narrow checks already proven in production (e.g. an NLQ chat agent's check that only verifies that a query actually ran). Raising pydantic_ai.ModelRetry is pydantic-ai's retry signal — it tells the model to try again with corrected output instead of crashing the whole agent run.

Raises

  • ModelRetry

wittgenstein_agent_guardrails.GuardrailAgent

mkapi_definition_mkapi dataclass GuardrailAgent(inner_agent: Any, scope_source: ScopeSource, refusal_message: str = DEFAULT_REFUSAL_MESSAGE)

Bases : Generic[DepsT]

Wraps a pydantic-ai Agent with a scope pre-check.

Blocks a call before it reaches the inner agent — and therefore before any LLM call happens — when scope_source.is_in_scope(user_prompt) is False. Cheaper and safer than only validating the answer after generation, since an out-of-scope request never reaches the model.

Methods

wittgenstein_agent_guardrails.GuardrailAgent.run

mkapi_definition_mkapi async method GuardrailAgent.run(self, user_prompt: str, deps: DepsT, **kwargs: Any) → str