Navigate docs

al-instrument

Auto-instrument LangChain agents with AgentLattice governance. One command adds identity, authorization, and audit trails to every tool your agent calls.

Install

pip install al-instrument

Requires Python 3.9+. Dependencies: libcst, httpx, agentlattice, langchain-agentlattice.

Quick Start

# See what al-instrument would change (diff to stdout)
al-instrument agent.py

# Apply the changes
al-instrument agent.py --apply

# Apply + register the agent + verify governance wiring
al-instrument agent.py --apply --register --test

The diff is the tutorial. Review the generated code to understand exactly what governance means for your agent.

What It Does

al-instrument runs a five-stage pipeline on your Python file:

1. Analyze

Uses libcst (Concrete Syntax Tree) to find every LangChain tool definition in your code. Three patterns are detected:

# Pattern 1: @tool decorator
@tool
def search_database(query: str) -> str:
    """Search the customer database."""
    return db.search(query)

# Pattern 2: StructuredTool.from_function()
search_tool = StructuredTool.from_function(
    name="search", func=search_database, description="Search the DB"
)

# Pattern 3: BaseTool subclass
class SearchTool(BaseTool):
    name: str = "search"
    description: str = "Search the database"
    def _run(self, query: str) -> str:
        return db.search(query)

Detection is deterministic. No LLM involved. Handles aliased imports (from langchain_core.tools import tool as my_tool).

2. Classify

Each detected tool is classified with an action type and risk level using the {domain}.{verb} taxonomy:

Domain Example verbs Default risk
db query, read, write, delete read/write
email send, read write
file read, write, delete read/write
api query, execute read/write
code execute write
web query, read read
payment execute admin
system execute admin

If ANTHROPIC_API_KEY or OPENAI_API_KEY is set, classification uses an LLM for intelligent action type assignment. Without an API key, it falls back to tool.{name} with a default risk level of write.

3. Generate

Transforms your source code using libcst (preserving all comments, formatting, and whitespace):

# BEFORE
from langchain_core.tools import tool

@tool
def search_database(query: str) -> str:
    """Search the customer database."""
    return db.search(query)

@tool
def send_email(to: str, subject: str, body: str) -> str:
    """Send an email to a customer."""
    return email_client.send(to, subject, body)

agent = create_react_agent(llm, [search_database, send_email])
# AFTER
import os
from langchain_core.tools import tool
from agentlattice import AgentLattice
from langchain_agentlattice import govern

al = AgentLattice(api_key=os.getenv("AL_API_KEY"))

@tool
def search_database(query: str) -> str:
    """Search the customer database."""
    return db.search(query)

# AgentLattice governance: read-only database access, auto-approved by default policy
search_database = govern(search_database, al=al, action_type="db.query")

@tool
def send_email(to: str, subject: str, body: str) -> str:
    """Send an email to a customer."""
    return email_client.send(to, subject, body)

# AgentLattice governance: external communication, requires human approval
send_email = govern(send_email, al=al, action_type="email.send")

# Agent constructor works unchanged — govern() shadows the original names
agent = create_react_agent(llm, [search_database, send_email])

4. Register (optional)

With --register, al-instrument registers your agent with the AgentLattice API and writes the API key to your .env file:

AL_SERVICE_KEY=sk-svc-... al-instrument agent.py --apply --register

You can also pass the key directly:

al-instrument agent.py --apply --register --service-key sk-svc-...

5. Verify (optional)

With --test, al-instrument calls execute_sync() for each action type to verify that governance policies are correctly wired:

al-instrument agent.py --apply --register --test

The verifier checks that each action type gets a policy decision from AgentLattice, confirming that the governance pipeline is live end-to-end.

CLI Reference

al-instrument <file> [options]

Arguments:
  file                  Python file containing LangChain agent code

Options:
  --apply               Write instrumented code back to the file (default: show diff)
  --register            Register the agent with AgentLattice (requires --apply)
  --test                Verify governance wiring (requires --register)
  --service-key KEY     AL_SERVICE_KEY for registration (default: $AL_SERVICE_KEY)
  --agent-name NAME     Agent name for registration (default: derived from filename)
  --base-url URL        AgentLattice API base URL (default: https://www.agentlattice.io)
  --ci                  CI mode: non-interactive, exit codes only

Idempotency

Running al-instrument on an already-instrumented file is safe. It detects the from langchain_agentlattice import govern import and skips with a message:

File already has AgentLattice governance (govern() imported). Skipping.

Report Output

After every run, al-instrument prints a structured report:

════════════════════════════════════════════════════
  al-instrument report
════════════════════════════════════════════════════

  TOOLS FOUND: 3
    search_database  → db.query     (read, auto-approved)
    send_email       → email.send   (write, requires approval)
    delete_records   → db.delete    (delete, requires approval)

  CLASSIFICATION: LLM-assisted (Claude)
  CHANGES: written to agent.py

  ACTION REQUIRED (1 item):
    1. agent.py:42 — TODO(al-instrument): Replace tool references
       in your agent constructor

  NEXT STEPS:
    1. Review the diff: git diff agent.py
    2. Fix the TODO above (swap tool references)
    3. Set AL_API_KEY in your environment
    4. Run your agent — governance is active
    5. Visit https://www.agentlattice.io/dashboard to configure policies

════════════════════════════════════════════════════

How It Fits Together

al-instrument generates code that uses two AgentLattice packages:

  • agentlattice (Python SDK) provides the AgentLattice client that communicates with the API
  • langchain-agentlattice provides the govern() wrapper that gates tool execution

After instrumentation, every tool call flows through: Tool invoked → govern() calls al.gate() → AgentLattice evaluates policy → Approved/Denied → Tool executes or raises error.

Configure policies, approval flows, and audit rules in the AgentLattice dashboard.