Skip to main content
Once you have a GuardedRun from guard.run(), use model_call() and tool_call() to wrap your model and tool invocations. Each call is checked against your guardrails before execution.

Model Calls

Parameters

What happens

  1. Check: POST /v1/runs/{id}/steps with type MODEL_CALL — guardrails are evaluated
  2. Execute: fn() is called (awaited if async)
  3. Report: PATCH /v1/runs/{id}/steps/{step_id} with status, duration, and token counts
If the guardrail check denies the step, PikarcBlockedError is raised before fn() executes — your model call never happens, and you’re never billed by the provider.

Token Extractor

The token_extractor function receives the return value of fn() and should return a tuple of (prompt_tokens, completion_tokens). This is how Pikarc tracks token usage and calculates costs. For OpenAI:
For Anthropic:
If omitted, token counts won’t be recorded for the step.

Tool Calls

Parameters

What happens

  1. Check: POST /v1/runs/{id}/steps with type TOOL_CALL — guardrails are evaluated
  2. Execute: fn() is called (awaited if async)
  3. Report: PATCH /v1/runs/{id}/steps/{step_id} with status and duration
Tool calls don’t have a token_extractor since tools don’t produce token counts.

Sync and Async Functions

Both model_call() and tool_call() accept sync or async callables for fn. The SDK detects whether the return value is awaitable and handles it automatically:

Full Example