LangChain and LangGraph#
Status: available. An optional callback handler lives at maida.integrations.langchain. It records LLM calls and tool calls to the active Maida run automatically.
Requirements: langchain-core must be installed. Install Maida with the LangChain extra:
uv add "maida-ai[langchain]>=0.5"
If langchain-core is missing, accessing LangChainCallbackHandler raises an ImportError that identifies the LangChain extra. Importing core maida remains safe.
Usage:
from maida import trace
from maida.integrations import LangChainCallbackHandler
@trace
def run_agent():
handler = LangChainCallbackHandler()
config = {"callbacks": [handler]}
# Use config with any LangChain chain, LLM, or tool:
result = my_chain.invoke(input_data, config=config)
return result
The handler captures:
LLM calls (
on_llm_start/on_chat_model_start->on_llm_end): records model name, prompt, response, and token usage viarecord_llm_call.Tool calls (
on_tool_start->on_tool_end/on_tool_error): records tool name, args, result, and error status viarecord_tool_call.
The offline LangChain example uses FakeListLLM and a local tool, so it requires no API key or network call:
python langchain-minimal.py
maida view
The normal run has this structural signature:
event sequence:
RUN_START -> TOOL_CALL -> LLM_CALL -> RUN_ENDtool sequence:
lookup(one call)LLM calls: one
FakeListLLMcallterminal status:
ok
The deterministic examples below retain the legacy single-run interface only
as a migration aid for comparing already-completed adapter traces. New
multi-trial gates should execute the agent with maida run and policy v2.
Use the LangChain regression mode to see the compatibility check catch one extra tool call:
# Capture the known-good behavior.
python langchain-minimal.py
maida baseline --out langchain-baseline.json
# Simulate a code change that repeats the local lookup.
python langchain-minimal.py --regression
maida assert --baseline langchain-baseline.json --tool-call-tolerance 0
The regression signature is RUN_START -> TOOL_CALL -> TOOL_CALL -> LLM_CALL -> RUN_END, with the tool sequence lookup -> lookup, one FakeListLLM call, and terminal status ok. The final command reports the tool-call increase from 1 to 2 and exits with code 1, so the same check can block a pull request even though the agent itself completed successfully.
For a multi-node graph, loop failure, and guardrail walkthrough, continue with the full LangGraph tutorial.
Guardrails (e.g. stop_on_loop) with LangChain / LangGraph:
All guardrails work with the callback handler. When a guardrail fires, the handler raises _MaidaAbortSignal (a BaseException) which bypasses both LangChain’s callback error handling and LangGraph’s graph executor — stopping the run immediately and preventing further token-wasting LLM calls. See Guardrails for details. To reuse a handler across runs, call handler.reset() between runs.
Notes:
The handler requires an active Maida run - wrap your entrypoint with
@traceor setMAIDA_IMPLICIT_RUN=1.Only callbacks delivered to this handler are recorded. Calls made without the handler in their callback config are invisible to Maida.
Tool errors are recorded as
TOOL_CALLevents withstatus="error"and include the error message.LLM errors are recorded as
LLM_CALLevents withstatus="error"(not as separateERRORevents).