Skip to content

LangChain

The WhiteBoxXAI callback handler records what a LangChain or LangGraph application does: each LLM call (model, prompt, completion, tokens, latency), chain runs, tool calls and errors. It works with any LangChain chat model, so OpenAI, Anthropic, Gemini, Mistral, Bedrock, Ollama and the rest are all covered.

Each root run's records are sent as one governance run, so a run with a dozen LLM calls costs one Governance Event, not twelve.

Install

pip install "whitebox-xai-sdk[langchain]" langchain-openai     # or langchain-anthropic, langchain-google-genai, ...

Set up the handler

Register the application as an LLM system once, then create a monitor for it and a callback handler:

import os

from whiteboxxai import WhiteBoxXAI
from whiteboxxai.integrations.langchain import LangChainMonitor, WhiteBoxXAICallbackHandler

client = WhiteBoxXAI(api_key=os.environ["WHITEBOX_API_KEY"])

app = client.models.register(
    name="support-assistant",
    model_type="llm",
    framework="langchain",
    version="1.4.0",
    features=["question"],
    baseline_metrics={},
)

monitor = LangChainMonitor(client, application_name="support-assistant", model_id=app["id"])
handler = WhiteBoxXAICallbackHandler(monitor)

Create the handler directly

In SDK 1.3.0, use WhiteBoxXAICallbackHandler(monitor) as above. monitor.create_callback_handler() and monitor.register_application() try to register the application through a method the client doesn't have, and fail.

Use it

Pass the handler in the run config. It works with chains, chat models, agents and LangGraph graphs:

from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

prompt = ChatPromptTemplate.from_messages([
    ("system", "You answer customer questions using the policy excerpts provided."),
    ("human", "{question}"),
])
chain = prompt | ChatOpenAI(model="gpt-4o")

answer = chain.invoke(
    {"question": "Can I get a refund after 30 days?"},
    config={"callbacks": [handler]},
)

Swap ChatOpenAI for ChatAnthropic, ChatGoogleGenerativeAI, ChatMistralAI, ChatBedrock, ChatOllama or any other LangChain chat model; logging is the same.

For a LangGraph graph or agent:

result = graph.invoke({"messages": [("user", question)]}, config={"callbacks": [handler]})

For multi-agent systems where you want agents, tasks and agent-to-agent interactions recorded as a workflow, see LangChain Multi-Agent.

What's recorded

Event Recorded as
LLM call An LLM log: provider, model, prompt, completion, tokens, latency, status
Chain or graph run A chain execution on the registered application, with inputs, outputs and duration
Tool call The tool name, input, output and duration
Errors The failure, on the call or run it belongs to

LLM calls appear in the LLM & RAG audit trail.

Log retrievals

If your RAG chain retrieves documents, log the retrieval so retrieval quality is tracked:

monitor.log_rag_retrieval(
    query=question,
    documents=[{"document_id": d.metadata["id"], "content": d.page_content} for d in docs],
    num_retrieved=len(docs),
    relevance_scores=scores,
    ground_truth_ids=["kb-17"],    # optional: enables precision, recall, MRR and NDCG
    answer=answer.content,
)

Add safety scans and prompt versions

client.safety.analyze(content=answer.content, content_type="completion")

Governed prompt versions are managed with client.prompts; link the calls they produce by logging with prompt_version_id. See Evaluations & Prompt Versions.

Troubleshooting

Nothing appears. Check the handler is in config={"callbacks": [...]} on the invoke call (or attached to the model), and that WHITEBOX_API_KEY is set in the process running the chain.

AttributeError: ... has no attribute 'register_model'. You called create_callback_handler() or register_application(). Construct WhiteBoxXAICallbackHandler(monitor) directly instead.

Costs are blank. Cost is calculated only for model names WhiteBoxXAI has prices for. See LLM monitoring.

See also