Installation
pip install "decimalai[langchain]". Each extra floors its framework at the framework’s latest release. Two extras ask more of the environment:
[adk],[pydantic-ai]and[all]need Python 3.11+.[evals]is not part of[all]. litellm pinsopenai<3, while[openai],[openai-agents]and[pydantic-ai]needopenai>=3, so install[evals]in an environment of its own.
pip show decimalai, or put a floor on the SDK so pip fails with an error instead:
Quick Start
An agent gets its prompt and skills from its framework’sagent_config(), which you pass into your own agent:
agent_config() reads DECIMAL_API_KEY and traces its own runs, so a file that uses one needs no init() call. Eight frameworks have one: LangChain, OpenAI Agents, the Claude Agent SDK, the OpenAI SDK, Anthropic, the Gemini API, Pydantic AI and Google ADK. See Frameworks.
decimalai.init() is for tracing with a framework flag, and for settings such as base_url, enabled or a default agent name:
Your own model calls
Code that calls a model itself, through a provider SDK or a tool loop of your own, gets an agent’s prompt and skills fromdecimalai.agent_config(), as plain values. On the OpenAI SDK, the Gemini API and the Anthropic Messages API, use that module’s own agent_config() instead: it hands the tool over in the provider’s shape and traces each run. Start a run for each user message:
support.run(message, variables=...)routesmessageand fills the saved prompt’s{{name}}variables fromvariables(attributes or dict keys). A variable with no value raisesdecimalai.MissingPromptVariablebefore any model call.run.tool_specis theload_skilltool in no provider’s format, so translate it.run.load_skill(name)returns a listed skill’s full text, from any thread or task. A skill already loaded in this run, an unknown name or an outage comes back as a sentence the model can act on.support.promptis the saved prompt with its variables unfilled, or thefallback=text, for code that only wants the text.prompt_version,prompt_hashandprompt_sourcesay which prompt is in use.prompt_sourceis"decimalai","decimalai (cached copy)"when DecimalAI could not be reached,"fallback (unreachable)"when nothing was cached either,"fallback (none saved)"when the agent has no saved prompt, or"fallback (no key)"with no key.variableslists the prompt’s variables, andskill_namesthe agent’s skills.
agent_config() re-reads the prompt in the background at most once a minute. A name your workspace has no agent by is created, so a misspelled name makes a new agent rather than an error. With no key it runs from your project alone. on_unavailable="fail" makes support.run() raise when DecimalAI never returned the agent’s skills; by default the run goes on without them. A run’s record (prompt version, variable names, skills offered and loaded) goes on a trace only inside an OpenTelemetry run, such as agent_run(support.name) with a provider flag.
A chat on Claude
Claude rejects a changed system prompt or tool definition partway through a chat (why), so a chat keeps one conversation:decimalai.init()
Call it once, before the calls it configures.
str
default:"DECIMAL_API_KEY env"
Your DecimalAI API key. Falls back to
DECIMAL_API_KEY, then to its alias DECIMALAI_API_KEY.str
default:"https://api.decimal.ai"
Backend URL.
bool
default:"True"
Set
False to disable all tracing (useful in tests): no adapter is installed and no call is made to the DecimalAI API. It also stops a skill loader an earlier init() installed, until a later init(enabled=True).str
default:"DECIMAL_AGENT_NAME env"
The agent this process traces and routes skills for, wherever a call names no agent. See The default agent name.
bool
default:"True unless DECIMALAI_SKILLS=0"
Whether
crewai=True also turns on CrewAI’s skill loader, the one flag with a skill loader. False installs tracing only. With langchain, False silences the warning a run without agent_config()’s middleware logs. Unset, it falls back to DECIMALAI_SKILLS, then to True.str
default:"DECIMALAI_SKILL_AUTHORITY env, else auto"
Whether the LangChain and OpenAI Agents adapters upload the local
SKILL.md files you wrote. "harness" always does, for a runtime that loads skills from disk itself (Claude Code, Cursor). "auto" and "router" do only when instrument() is asked to, with disk_sync=True or skill_dirs=. Nothing is ever written to disk.bool
default:"True"
Probes the backend once to validate the key and
base_url. Raises DecimalConfigError on a 401/403 or a connection failure. Pass False in CI or cold-start-sensitive paths.float
default:"3.0"
Seconds before the probe gives up. On timeout,
init() logs a warning and continues.Instrumentation flags
Each flag is abool, default False, and traces that surface. Google ADK and Pydantic AI have no flag: an ADK agent is traced by DecimalAIPlugin() in its App, and a Pydantic AI agent by agent_config()’s capability.
crewai=True is shorthand for init() plus decimalai.crewai.instrument(agent_name=..., enable_skill_loader=True). Use the explicit instrument() form when you need other arguments, and don’t combine the two forms for one framework: on LangChain the second call ignores its agent_name.
The default agent name
You name the agent once, ininit() or in the DECIMAL_AGENT_NAME environment variable, and every call that is not given a name of its own uses it:
instrument(), start_trace(), @decimalai.trace, SkillRouter()), init(agent_name=...), DECIMAL_AGENT_NAME, then the call’s own fallback (the decorated function’s name for @decimalai.trace, the framework’s own name for an adapter).
agent_name matters for skills too: skills assigned to one agent are only offered when the router is told which agent is asking. An agent built from agent_config("<name>") is routed and traced as that name on all eight frameworks that have one, whatever the framework calls it, a Pydantic AI Agent’s own name= included. For the flag and instrument() forms, every adapter’s instrument() uses the name init() was given (or DECIMAL_AGENT_NAME) when it is not passed one, so naming the agent in init() is enough; an agent_name= passed to instrument() wins over it.
SkillRouter(agent_name=None), passed explicitly, means no agent: the router offers the organization-wide skill set. register_manifest(), flush_manifest_for_ci() and decimalai.agent_config() take the name as a required argument.
With verify=True, init() also logs a WARNING when the name is not an existing agent but is within two characters of one (refund_bot beside refund-bot). Such a typo files traces under a second agent, which is offered none of the first one’s skills, and nothing errors.
Environment Variables
What’s next
Tracing
Decorators and helpers to capture LLM and tool calls.
Frameworks
Each framework’s
agent_config(), and tracing for CrewAI and OTel.