§ ARTICLE / · 7 min read
Governing LangChain agents with Execlave in 10 minutes
You have a LangChain agent in production. It calls tools, retrieves documents, and makes decisions. Your compliance team wants an audit trail. Your CTO wants cost controls. Your security team wants prompt injection defense. Here's how to add all three without refactoring your chains.
TL;DR
Add 3 lines of SDK code to wire Execlave into any LangChain agent via callbacks. Get policy enforcement, audit trails, kill switches, and compliance logging without changing your chain logic.
This is a working tutorial with copy-paste code. By the end you'll have policy enforcement, immutable audit trails, and kill switches on any LangChain agent. Python and TypeScript examples included.
What you're building
A LangChain agent that:
- Logs every LLM call, tool invocation, and retriever hit to a centralized dashboard
- Enforces policies before tool calls execute (allowlists, cost limits, PII detection)
- Blocks execution when a policy violation is detected
- Generates compliance-ready audit trails with cryptographic verification
- Can be paused or killed remotely via dashboard or Slack
All of this happens in the callback layer—your existing chain logic stays untouched.
Prerequisites
- An Execlave account with an API key (free tier available)
- A registered agent in Execlave (create one in Dashboard → Agents)
- LangChain
>=0.3(Python) or@langchain/core >=0.3(JS)
Step 1: Install the SDK with LangChain extra (2 minutes)
The LangChain integration is an optional extra, so the default SDK doesn't pull LangChain as a transitive dependency.
Python
pip install 'execlave-sdk[langchain]'TypeScript
npm install @execlave/sdk @langchain/coreAdd your API key to your environment:
# .env
EXECLAVE_API_KEY=exe_live_...Step 2: Create the callback handler (2 minutes)
One handler wires Execlave into every callback LangChain emits. Create it once at app startup and reuse it across requests.
Python
from execlave import Execlave
from execlave.integrations.langchain import ExeclaveCallbackHandler
import os
exe = Execlave(api_key=os.environ["EXECLAVE_API_KEY"])
handler = ExeclaveCallbackHandler(exe, agent_id="support-bot")TypeScript
import { Execlave } from '@execlave/sdk';
import { ExeclaveCallbackHandler } from '@execlave/sdk/integrations/langchain';
const exe = new Execlave({ apiKey: process.env.EXECLAVE_API_KEY! });
const handler = new ExeclaveCallbackHandler(exe, { agentId: 'support-bot' });Important: Use the agent_id / agentId from your Execlave dashboard, not the LangChain agent's role or name.
Step 3: Attach to your chain (1 minute)
Pass the handler via the callbacks field when you invoke or stream. If you already have callbacks, append the Execlave handler—don't replace them.
Python
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_messages([("user", "{question}")])
llm = ChatOpenAI(model="gpt-4o-mini")
chain = prompt | llm
# Enforcement runs on chain start and every tool call
answer = chain.invoke(
{"question": "Summarize our Q3 pipeline"},
config={"callbacks": [handler]},
)TypeScript
import { ChatOpenAI } from '@langchain/openai';
import { ChatPromptTemplate } from '@langchain/core/prompts';
const prompt = ChatPromptTemplate.fromMessages([['user', '{question}']]);
const chain = prompt.pipe(new ChatOpenAI({ model: 'gpt-4o-mini' }));
const answer = await chain.invoke(
{ question: 'Summarize our Q3 pipeline' },
{ callbacks: [handler] },
);That's it. Every LLM call, tool invocation, and retriever lookup is now traced and enforced.
Step 4: Create your first policy (3 minutes)
In the Execlave dashboard, create a policy to control what your agent can do. Here's a tool allowlist that only permits specific tools:
{
"name": "Support Bot Tool Allowlist",
"policyType": "tool_allowlist",
"config": {
"allowedTools": ["search_knowledge_base", "create_ticket"]
},
"enforcementMode": "block",
"severity": "high"
}If the agent tries to call any other tool, the chain will raise a PolicyBlockedError before the tool executes.
Step 5: Handle policy blocks (2 minutes)
Wrap your chain invocation in try/catch to handle policy violations gracefully:
Python
from execlave.errors import PolicyBlockedError
try:
answer = chain.invoke({"question": user_input}, config={"callbacks": [handler]})
except PolicyBlockedError as exc:
# exc.violations contains the matched policies
return {
"error": "This action was blocked by policy",
"violations": exc.violations
}TypeScript
import { PolicyBlockedError } from '@execlave/sdk';
try {
const answer = await chain.invoke({ question: userInput }, { callbacks: [handler] });
} catch (err) {
if (err instanceof PolicyBlockedError) {
return {
error: 'This action was blocked by policy',
violations: err.violations,
};
}
throw err;
}What you just built
In under 10 minutes, you've added:
- Full execution traces: Every LLM call, tool invocation, agent step, and retriever lookup logged with input, output, latency, and cost
- Runtime policy enforcement: Tool allowlists, cost budgets, PII detection, and prompt injection scanning—all evaluated before execution
- Compliance-ready audit trail: Append-only, cryptographically signed logs retained for 1+ years
- Kill switches: Pause or stop any agent from the dashboard or Slack
And you did it without changing a single line of your chain logic—just added a callback handler.
Next steps
- Add more policy types: Cost limits, rate controls, content filtering, time-based restrictions (Policy Reference)
- Set up approval workflows: Route high-risk actions through human-in-the-loop gates (require_approval mode)
- Export compliance reports: Generate signed audit packages for SOC 2, EU AI Act, or ISO 27001 (Compliance page)
- Wire alerts to Slack: Get notified when policies are violated or budgets are breached (Docs)
Common questions
Does this slow down my agent?
No. Policy evaluation runs in <20ms p50 (sub-millisecond for cached decisions). The callback handler is async, so tracing doesn't block your chain.
What if Execlave is down?
The SDK fails open by default—if the enforcement API is unreachable, your chain proceeds and logs a warning. You can configure fail-closed mode if you prefer.
Can I use this with agents that have tools?
Yes. The callback handler automatically detects tool calls and enforces policies before each tool executes. This is the primary use case.
Does this work with LangGraph?
Yes. LangGraph is built on LangChain callbacks, so the same handler works. Every node in your graph becomes a span in the trace.
Full working example
For a complete runnable example with a tool-calling agent, see the LangChain integration docs.
Start governing your LangChain agents
Free tier includes 10,000 traces/month, unlimited agents, and 90-day retention. No credit card required.
Get started free