How to Integrate LangGraph for banking with LangSmith for multi-agent systems
Combining LangGraph for banking with LangSmith gives you two things most agent systems lack: controlled execution and observability. In banking workflows, that means you can route customer requests through a governed multi-agent graph while tracing every decision, tool call, and handoff for audit and debugging.
This is the pattern you want for regulated AI systems: LangGraph handles stateful orchestration, and LangSmith gives you trace-level visibility into what happened and why.
Prerequisites
- •Python 3.10+
- •A LangChain-compatible environment
- •Installed packages:
- •
langgraph - •
langsmith - •
langchain-openaior your model provider SDK
- •
- •API keys configured:
- •
OPENAI_API_KEYor equivalent LLM key - •
LANGSMITH_API_KEY
- •
- •LangSmith project configured in your environment
- •Access to your banking tools or mock services:
- •account lookup
- •transaction history
- •KYC/AML checks
- •Basic familiarity with:
- •LangGraph
StateGraph - •LangSmith tracing via environment variables or callbacks
- •LangGraph
Integration Steps
- •Install the packages and configure tracing
Start by installing the core libraries and enabling LangSmith tracing through environment variables. For most setups, this is enough to get traces from your graph execution into LangSmith.
pip install langgraph langsmith langchain-openai
import os
os.environ["LANGSMITH_API_KEY"] = "lsv2-your-key"
os.environ["LANGSMITH_TRACING"] = "true"
os.environ["LANGSMITH_PROJECT"] = "banking-multi-agent"
os.environ["OPENAI_API_KEY"] = "sk-your-key"
If you’re running in a controlled banking environment, keep these values in your secrets manager instead of hardcoding them.
- •Define a shared state for the multi-agent workflow
In banking, agents should not pass loose strings around. Use a typed state object so each node in the graph knows exactly what it can read and write.
from typing import TypedDict, Annotated, Optional
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
class BankingState(TypedDict):
messages: Annotated[list, add_messages]
customer_id: str
intent: Optional[str]
risk_flag: Optional[bool]
response: Optional[str]
This state becomes the contract between agents like intake, compliance review, and customer response generation.
- •Create agent nodes and attach traceable model calls
Use explicit node functions so each agent step is visible in LangSmith traces. If you use a chat model inside a node, the call will be captured when tracing is enabled.
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
def classify_intent(state: BankingState):
prompt = f"""
Classify this banking request into one of:
balance_inquiry, card_dispute, loan_question, suspicious_activity
Messages: {state["messages"]}
"""
result = llm.invoke(prompt)
return {"intent": result.content.strip()}
def compliance_check(state: BankingState):
risky_intents = {"suspicious_activity", "card_dispute"}
return {"risk_flag": state["intent"] in risky_intents}
def generate_response(state: BankingState):
prompt = f"""
You are a banking assistant.
Intent: {state["intent"]}
Risk flag: {state["risk_flag"]}
Write a concise customer response.
"""
result = llm.invoke(prompt)
return {"response": result.content.strip()}
If your bank uses separate specialist agents, keep them as separate nodes like this instead of packing everything into one prompt.
- •Build the LangGraph workflow and compile it
Now wire the nodes into a graph with conditional routing. This is where multi-agent control becomes explicit.
def route_after_compliance(state: BankingState):
if state["risk_flag"]:
return "manual_review"
return "respond"
def manual_review(state: BankingState):
return {
"response": (
"Your request requires additional review by our operations team. "
"A specialist will contact you shortly."
)
}
graph = StateGraph(BankingState)
graph.add_node("classify_intent", classify_intent)
graph.add_node("compliance_check", compliance_check)
graph.add_node("respond", generate_response)
graph.add_node("manual_review", manual_review)
graph.add_edge(START, "classify_intent")
graph.add_edge("classify_intent", "compliance_check")
graph.add_conditional_edges(
"compliance_check",
route_after_compliance,
{
"manual_review": "manual_review",
"respond": "respond",
},
)
graph.add_edge("respond", END)
graph.add_edge("manual_review", END)
app = graph.compile()
At this point, every run through the graph is traceable in LangSmith because the underlying LLM calls are traced automatically when LANGSMITH_TRACING=true.
- •Run the graph with metadata for auditability
For banking systems, pass metadata like customer segment, channel, or case ID. That makes traces easier to search in LangSmith later.
initial_state = {
"messages": [("user", "I noticed an unfamiliar card payment.")],
"customer_id": "cust_10291",
}
result = app.invoke(
initial_state,
config={
"run_name": "card_dispute_flow",
"metadata": {
"customer_id": "cust_10291",
"channel": "mobile_app",
"region": "EU",
},
# optional tags help with filtering in LangSmith UI
"tags": ["banking", "multi-agent", "compliance"],
},
)
print(result["intent"])
print(result["risk_flag"])
print(result["response"])
That metadata becomes part of the trace context in LangSmith, which matters when compliance teams need to inspect specific flows.
Testing the Integration
Use a simple invocation and confirm that both the graph output and LangSmith trace appear as expected.
test_state = {
"messages": [("user", "Can you show me my account balance?")],
"customer_id": "cust_55501",
}
output = app.invoke(
test_state,
config={
"run_name": "balance_inquiry_test",
"metadata": {"customer_id": "cust_55501"},
"tags": ["test", "smoke"],
},
)
print(output)
Expected output:
{
'messages': [('user', 'Can you show me my account balance?')],
'customer_id': 'cust_55501',
'intent': 'balance_inquiry',
'risk_flag': False,
'response': '...customer-facing answer...'
}
In LangSmith, you should see:
- •one top-level run for
balance_inquiry_test - •child traces for each LLM call inside graph nodes
- •metadata fields like
customer_id,channel, andregion - •tags such as
banking,multi-agent, andtest
Real-World Use Cases
- •
Dispute triage system
- •One agent classifies card disputes.
- •Another checks policy constraints.
- •A final agent drafts customer responses while high-risk cases route to manual review.
- •
KYC onboarding assistant
- •One node collects identity data.
- •Another validates completeness.
- •A compliance node flags missing documents or suspicious patterns before approval.
- •
Fraud support copilot
- •An intake agent detects fraud-related language.
- •A risk agent decides whether escalation is required.
- •A resolution agent generates safe next steps for support staff or customers.
The main value here is control plus visibility. LangGraph gives you deterministic orchestration across specialized agents, while LangSmith gives you production-grade traces when something breaks or needs audit review.
Keep learning
- •The complete AI Agents Roadmap — my full 8-step breakdown
- •Free: The AI Agent Starter Kit — PDF checklist + starter code
- •Work with me — I build AI for banks and insurance companies
By Cyprian Aarons, AI Consultant at Topiax.
Want the complete 8-step roadmap?
Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.
Get the Starter Kit