Assevradocs

Using it

Integrations

One command per tool you already run — OpenTelemetry, LangGraph, Langfuse, Phoenix, the OpenAI Agents SDK, Anthropic.

Assevra provides a Python SDK and recorder, serialized trace adapters, and capture/export recipes. capture can execute a command you supply. The integrations below are not vendor partnerships.

Stack Available interface
Python SDK and recorder
LangGraph Full-message-history capture recipe
OpenAI Agents Run-item and function-call capture recipe
OTel / Phoenix Supported serialized OTLP/OpenInference adapter
Langfuse Paginated observation export recipe
MCP tool definitions JSON Schema contract import; not a live server connection

Local fixtures test serialization and normalization. SDK recipes are based on vendor documentation; run a smoke test against your own installed SDK and hosted service. Preserve context, tool results, case identity, and observed final state where relevant. Spans alone do not establish a complete agent trial: select the appropriate root run or export an explicitly assembled trajectory.

assevra integrate --list
assevra integrate langgraph

LangGraph

import json

records = []
for example_input in inputs:
    state = graph.invoke({"messages": [("user", example_input)]})
    final = state["messages"][-1]
    records.append({
        "input": example_input,
        "agent_output": final.content,
        # Carry the calls through: they feed `tool_call` and `action_correctness`.
        "tool_calls": [
            {"name": c["name"], "arguments": c.get("args", {})}
            for message in state["messages"]
            for c in getattr(message, "tool_calls", []) or []
        ],
    })

with open("traces.jsonl", "w") as fh:
    for record in records:
        fh.write(json.dumps(record) + "\n")
# The capture step above already wrote traces.jsonl.
mv traces.jsonl traces.json
assevra bootstrap --from traces.json --format generic --out evals/agent.jsonl

OpenAI Agents SDK

import json
from agents import Agent, Runner

records = []
for prompt in prompts:
    result = await Runner.run(agent, prompt)
    items = result.to_input_list()
    records.append({
        "input": prompt,
        "agent_output": str(result.final_output),
        "trajectory": items,
        "tool_calls": [{"name": item["name"], "arguments": item.get("arguments", "{}")}
                       for item in items if item.get("type") == "function_call"],
        "tool_results": [item for item in items if item.get("type") == "function_call_output"],
    })

with open("traces.json", "w") as fh:
    json.dump(records, fh)
# The capture step above already wrote traces.json.
assevra bootstrap --from traces.json --format generic --out evals/agent.jsonl

Arize Phoenix

# Phoenix instruments through OpenInference; if traces appear in the Phoenix UI,
# they are already in the shape Assevra reads.
import phoenix as px
px.launch_app()
import json
from phoenix.client import Client

spans = Client().spans.get_spans_dataframe()
spans.to_json("traces.json", orient="records")
assevra bootstrap --from traces.json --format otel --out evals/agent.jsonl

Langfuse

# Langfuse's decorators or SDK already record every generation. Nothing to add.
from langfuse import observe

@observe()
def handle(message: str) -> str:
    return agent.run(message)
# Export the observations you want to evaluate.
import json
from langfuse import Langfuse

client = Langfuse()
records, page_number = [], 1
while True:
    page = client.api.observations.get_many(type="GENERATION", limit=100, page=page_number)
    records.extend(json.loads(o.json()) for o in page.data)
    if len(page.data) < 100:
        break
    page_number += 1
with open("traces.json", "w") as fh:
    json.dump(records, fh)
assevra bootstrap --from traces.json --format generic --out evals/agent.jsonl

OpenTelemetry

# Any OTel-instrumented LLM app already emits what Assevra needs. If you are
# starting from scratch, record the two attributes that matter:
from opentelemetry import trace

tracer = trace.get_tracer("my-agent")
with tracer.start_as_current_span("agent.turn") as span:
    span.set_attribute("input.value", user_message)
    output = agent.run(user_message)
    span.set_attribute("output.value", output)
# Point your collector at a file exporter, or dump spans you already store:
# any OTLP JSON export works, including a raw `resourceSpans` document.
cp $OTEL_EXPORT_DIR/spans.json traces.json
assevra bootstrap --from traces.json --format otel --out evals/agent.jsonl

Anthropic Messages API

import json

log = []
for prompt in prompts:
    message = client.messages.create(
        model="claude-opus-4-8",
        max_tokens=1024,
        system=policy_text,
        messages=[{"role": "user", "content": prompt}],
    )
    log.append({
        "model": message.model,
        "system": policy_text,
        "messages": [
            {"role": "user", "content": prompt},
            {"role": "assistant", "content": message.content[0].text},
        ],
        # Cost and latency become gateable dimensions once you record them.
        "usage": {
            "input_tokens": message.usage.input_tokens,
            "output_tokens": message.usage.output_tokens,
        },
    })

with open("traces.json", "w") as fh:
    json.dump(log, fh)
# The capture step above already wrote traces.json.
assevra bootstrap --from traces.json --format anthropic --out evals/agent.jsonl

Review the drafted rows and add acceptance criteria before running a release gate. The generic API export may include sensitive fields; retain only the evidence your evaluation needs.

Vendor references: Langfuse query SDK, Phoenix span exports, OpenAI Agents run results. Langfuse deployments may use different observation API versions; this recipe uses the paginated v1 compatibility API.

Something wrong or missing on this page?Edit it on GitHub.