Auto-Instrumentation Overview
Zero-code instrumentation for existing agent codebases.
Overview
auto_instrument() monkey-patches popular AI SDKs at runtime to automatically send validations to AgentTrust — no decorator or client code required. Supported targets: OpenAI SDK, LangChain (LCEL + legacy), LangGraph.
Why It Matters
The lowest-friction integration for existing codebases. Add two lines at startup and all LLM calls are governed.
Prerequisites
pip install agentrust-py
# Plus your framework: openai, langchain, langgraphStep-by-Step Guide
1. Call before framework imports (recommended)
from agentrust_sdk import auto_instrument
auto_instrument() # must run before openai/langchain imports
import openai
# ... rest of app2. Alternative: install() / auto_install()
A second, independent patcher lives in agentrust_sdk.auto. It covers Anthropic,
which auto_instrument() does not, but omits LangGraph.
from agentrust_sdk.auto import install
install(agent_id="my-agent") # patches OpenAI, Anthropic, LangChain callbacksauto_instrument() | auto.install() | |
|---|---|---|
| OpenAI | ✅ | ✅ |
| LangChain | ✅ LCEL + legacy | ✅ callback handler |
| LangGraph | ✅ | ❌ |
| Anthropic | ❌ | ✅ |
| Reversible | ✅ remove_patches() | ❌ |
Prefer auto_instrument() unless you specifically need the Anthropic patch. For Anthropic
with full control, ClaudeAgentGuard is the explicit
alternative.
3. Disable auto-instrumentation
export AGENTRUST_AUTO_INSTRUMENT=false4. What gets patched
| Library | Patched methods |
|---|---|
| OpenAI | chat.completions.create — sync and async. The Responses API is not patched. |
| LangChain | Runnable.invoke (LCEL), plus legacy BaseLLM.predict and Chain.__call__ |
| LangGraph | CompiledStateGraph.invoke and .ainvoke |
Only the module-level OpenAI client is patched
auto_instrument() patches openai.chat.completions.create on the module-level default
client and on the AsyncOpenAI class. Calls made through your own
client = OpenAI() instance are not governed. Either use the module-level
openai.chat.completions.create(...), or wrap your call site in @harness.
Patches are reversible: remove_patches() restores the original callables. A process
restart is the safest rollback once traffic has been served.
Integration pattern A
From examples/README.md — Pattern A is auto-instrument for zero application code change.
Examples
from agentrust_sdk import auto_instrument, embed_gateway
embed_gateway()
auto_instrument(agent_id="my-openai-agent")
# Module-level call — this IS governed.
import openai
response = openai.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello"}],
)
# Instance call — this is NOT governed by auto_instrument().
# from openai import OpenAI
# client = OpenAI()
# client.chat.completions.create(...) # ← bypasses the patchSee examples/minimal.py and examples/openai_direct.py.
Best Practices
- Call
auto_instrument()as early as possible inmain()or__init__.py - Pass
agent_id=toauto_instrument()— called directly it defaults to"auto-instrumented"and reads no env var. (AGENTRUST_AUTOLOAD_AGENT_IDis read only by the autoload bootstrap.) - Combine with
embed_gateway()for local dev - Use
@harnessinstead when you need explicit agent boundaries
Common Mistakes
- Importing OpenAI before
auto_instrument()(patch may not apply) - Expecting a meaningful
agent_idfor free — it defaults to"auto-instrumented" - Expecting your own
OpenAI()instance to be governed — only the module-level client is patched - Using auto-instrument with Team-tier graph adapters (use
AgentTrustNodeinstead)
Troubleshooting
| Issue | Fix |
|---|---|
| Calls not validated | Confirm AGENTRUST_ENABLED=true and AGENTRUST_AUTO_INSTRUMENT is not false; check import order; confirm you are not calling through your own OpenAI() instance |
| Double validation | Don't combine auto-instrument + @harness on same path |
| LangGraph not patched | Ensure langgraph is installed; check logs |