Skip to main content
TypeSafe AI answers typed questions about a piece of state through its System One API. A request sends a state plus a map of named questions built from three primitives — Noul (yes/no), Choice (labeled alternatives), and Score (an ordered rubric) — and returns one typed answer per question. Arize AX captures every call through the openinference-instrumentation-typesafe package, which wraps both TypeSafeClient.system_one and AsyncTypeSafeClient.system_one as OpenInference LLM spans.
This is the Python guide. For the TypeScript / JavaScript instrumentor, see TypeSafe AI (JS).
A System One call is not a chat exchange, so the state and the answers are recorded as input.value and output.value rather than as llm.input_messages / llm.output_messages.

Prerequisites

  • Python 3.10+
  • typesafe-sdk 0.6.0 or newer — the range the instrumentor patches
  • An Arize AX account (sign up)
  • A TYPESAFE_API_KEY from TypeSafe AI

Launch Arize AX

  1. Sign in to your Arize AX account.
  2. From Space Settings, copy your Space ID and API Key. You will set them as ARIZE_SPACE_ID and ARIZE_API_KEY below.

Install

Configure credentials

Setup tracing

Run TypeSafe AI

This example asks all three question types about one support ticket in a single call.
Questions can be passed as the SDK objects shown above or as raw dictionaries — the instrumentor records either form.

Expected output

Verify in Arize AX

  1. Open your Arize AX space and select project typesafe-tracing-example.
  2. You should see a new trace within ~30 seconds containing a single TypeSafeClient LLM span carrying:
    • input.value — the request body (state, model, questions) as JSON
    • output.value — the response body (model, answers, usage) as JSON
    • llm.invocation_parameters — the call configuration: the model and any extra_body fields
    • llm.request.model_name (jev-latest — the instrumentor falls back to the client default when the call omits model) and llm.response.model_name (the resolved version, for example jev-1.13.0)
    • llm.token_count.prompt, llm.token_count.completion, and llm.token_count.total, when the API reports usage
  3. If no traces appear, see Troubleshooting.

Check from the skill, CLI, or SDK

Confirm spans are actually reaching your Arize AX project. Use whichever fits your workflow — the skill and CLI work for any framework; the SDK check is shown for each language.
Install the Arize Skills plugin and let your coding agent check for you:
Then prompt your agent:
Use the arize-trace skill to export and analyze recent traces from my project. Confirm spans are arriving, and summarize any errors or latency issues.

Trace the async client

AsyncTypeSafeClient is instrumented by the same TypeSafeAIInstrumentor() call — no extra setup. Its spans are named AsyncTypeSafeClient and carry identical attributes.

Mask sensitive payloads

The state is the document you are asking about, so it often carries customer data. Because the state and the questions are recorded only in input.value, hide_inputs keeps the whole request off the span, and hide_outputs does the same for the answers:
Model names and token counts survive masking, so cost and latency dashboards keep working. llm.invocation_parameters holds no request content — only the model and any extra_body fields — so mask it with hide_llm_invocation_parameters only if those are sensitive. You can also suppress tracing for a block with suppress_tracing(), and attach session, user, metadata, and tag information with the using_session, using_user, and using_attributes context managers.

Troubleshooting

  • No traces in Arize AX. Confirm ARIZE_SPACE_ID and ARIZE_API_KEY are set in the same shell that runs example.py.
  • TypeSafe spans missing but other spans present. TypeSafeAIInstrumentor().instrument(...) must run before the first system_one call. Import order is not the constraint here: the instrumentor patches the method on the TypeSafeClient class, so importing typesafe_sdk — or even constructing a client — before instrumenting is fine. Importing instrumentation first is simply the easiest way to guarantee the call order.
  • No span for client.models.list(). Expected — the instrumentor only wraps system_one.
  • TypeSafeAuthenticationError. Verify TYPESAFE_API_KEY is set and valid; the client reads it from the environment unless you pass api_key explicitly.
  • Instrumentor installs but never patches. It declares typesafe-sdk >= 0.6.0 as an instrumented dependency, and OpenTelemetry’s base instrumentor logs a dependency conflict and skips patching rather than raising when the installed SDK falls outside that range. Check the version with pip show typesafe-sdk.
  • Answers present but a question is missing from the response. The SDK drops answer types it doesn’t model yet and logs a warning; the raw payload is still on response.raw_http_response.

Resources

TypeSafe AI Documentation

OpenInference TypeSafe Instrumentor (Python)

Runnable TypeSafe Tracing Examples

TypeSafe AI SDK on PyPI

TypeSafe AI (JS/TS) tracing