init() (or call the framework subpackage’s instrument() directly for more control), and DecimalAI auto-captures traces, tool calls, and the underlying manifest.
instrument() requires 0.10.2 or newer. On 0.10.0 and earlier the
function was called install() — same arguments, same behaviour. It still
works after the rename, with a DeprecationWarning, so code you have already
written keeps running. The name moved because install had come to mean
something else entirely: adding a skill to your workspace. See
Vocabulary.decimalai.init(langchain=True) is unaffected on every version.First-class
Native adapters with the deepest capture: full manifests (tool schemas or full config introspection), multi-agent structure, and — where the framework’s architecture allows it — live skill delivery.LangChain & LangGraph
Callback handler. Chains, agents, LangGraph nodes all auto-traced, with skill injection via
instrument(enable_skill_loader=True).OpenAI Agents SDK
Deepest integration. Full manifest from agent introspection, plus the live
load_skill tool.Claude Agent SDK / Claude Code
Stream-wrapped tracing for
query(), disk-installed skills for Claude Code.Supported
Native adapters with a narrower surface — either tracing-only or skills-only, documented honestly on each page.Pydantic AI
Skill loader + live
load_skill tool via instrument(). Tracing flows through the underlying provider SDK.Google ADK
Native ADK plugin. One trace per invocation with model, tools, and sub-agent activity.
LlamaIndex
Query engines, retrievers, synthesizers via the LlamaIndex instrumentation dispatcher.
Community / OTel-generic
These route through the generic OpenTelemetry exporter. They keep working, but they aren’t native adapters — manifest capture is limited to what OTelgen_ai.* conventions express.
CrewAI
Crews, tasks, agent conversations via OpenTelemetry.
Haystack & anything else
Any framework emitting OTel
gen_ai.* semantic-convention spans, Haystack included.Capability comparison
“Names only” means DecimalAI knows which tool was called but not its full input schema. If schema-aware manifests matter for your use case (e.g. you want the regression check to flag schema changes), use the explicit
register_manifest() form for those frameworks. “Skills rail” is how registry skills reach the model on that adapter — see Skills for the offered → delivered → activated ladder.
Module-level reference
Install each framework’s dependencies with its extra — e.g.
pip install "decimalai[langchain]" — so the adapter has the package it hooks into. CrewAI and Haystack ship through the OTel pathway rather than a subpackage of their own: there’s no decimalai.crewai module, and init(crewai=True) is a convenience alias for the OTel exporter.
AutoGen / AG2 is no longer an integration.
decimalai.init(autogen=True)
and decimalai.autogen.instrument() still run — they install the generic OTel
exporter and warn — but nothing instruments AutoGen agents for you. The
classic autogen distribution is frozen at 0.14.1 (AG2 moved to ag2 1.x,
which no longer provides the autogen API), and Microsoft’s
autogen-core/autogen-agentchat is a different framework that was never
advertised here. Both land on
generic OpenTelemetry, which is where to go
next.No framework at all
Two more rails cover raw provider-SDK usage:- Direct provider tracing —
init(openai=True),init(anthropic=True), orinit(google=True)auto-trace rawopenai/anthropic/google.genaiSDK calls via OpenInference instrumentors (install the matchingopeninference-instrumentation-<provider>package, or the flag warns and skips). Don’t combine with a framework flag that already traces the same provider, or calls are captured twice. decimalai.anthropic— not a tracing adapter: it’s the SkillRouter prompt-injection adapter for the raw Anthropic Messages API (instrument(enable_skill_loader=True)patchesclient.messages.create()to inject skills intosystem). There is no tool loop in a singlemessages.create()call, soenable_load_skill_toolis accepted but dormant there.
Mark where a run begins and ends
On the raw rails there is one thing you have to say yourself. A provider instrumentor sees a single SDK call at a time — it has no idea which calls belong to the same run, because there is no run object for it to hook. Left alone, a tool-use loop of twomessages.create() calls arrives as two unrelated single-span traces, and a second agent in the same process can’t be told apart from the first.
Wrap the run and both problems go away:
support-bot. Concurrent runs stay separate — the boundary is per-context, not global — so agent_run is what makes a threaded or asyncio service traceable at all. Nest it inside your own request handler and every call the run makes lands in the right place.
It is also what lets the skills rail land on the trace. The trace it opens is what a routing decision gets attributed to, so without it a raw-provider run still ships — it just carries no routing_id and no offered skill names. The SDK records nothing rather than guess which run a decision belonged to.
Two things it deliberately does not do: it adds no input/output of its own (previews still come from the real LLM calls), and it invents no steps — a tool your code ran in-process still emits nothing, because a waterfall should only show what actually happened.
Grouping is only for the raw provider rails. Every framework adapter — LangChain, OpenAI Agents, CrewAI, LlamaIndex, Pydantic AI, ADK, Claude Agent SDK — already knows where its runs start, and wraps them for you. Pydantic AI is the one worth calling out: it does no tracing of its own and rides entirely on the provider instrumentor, so
decimalai.pydantic_ai.instrument() opens the run scope on your behalf. You don’t need agent_run there.agent_run does one more thing, and that half is not provider-only: it says whose run this is. LlamaIndex installs a single span handler for the whole process, so if you serve more than one agent from one process, wrap each run in agent_run("...") to give it its own name and its own manifest. Adapters that take an agent name per run — LangChain’s CallbackHandler(agent_name=...), for instance — don’t need it.What’s next
Tracing
Manual decorators if you need custom span boundaries inside an instrumented framework.
Manifests
Override the auto-detected manifest when needed.