LendingTree deployed a production multi-agent system on Amazon Bedrock to deliver 24/7 mortgage guidance. The architecture coordinates three specialized agents (research, calculation, guidance) using LangGraph state machines, enforces tool boundaries via the Model Context Protocol, and applies Amazon Bedrock guardrails at the invocation layer to meet financial-services compliance requirements.
This is not a demo. It is a regulated financial product where every recommendation must be auditable and every tool invocation must respect authorization boundaries.
Architecture: Three Agents, One State Machine
LendingTree’s system separates concerns across three agents:
- Research Agent: Retrieves mortgage product data, rates, and lender information from internal databases and external APIs.
- Calculation Agent: Performs amortization schedules, affordability checks, and payment projections using mortgage-specific formulas.
- Guidance Agent: Synthesizes research and calculations into personalized recommendations for the user.
LangGraph orchestrates handoffs. Each agent is a node in a directed graph. State transitions are explicit: the research agent completes, writes results to shared state, and triggers the calculation agent. The calculation agent writes its output and triggers the guidance agent. No agent can skip ahead or invoke tools outside its designated scope.
LangGraph State Management
LangGraph maintains a shared state object that flows through the graph. Each agent reads from and writes to this state. The orchestrator enforces read/write boundaries:
from langgraph.graph import StateGraph, END
class MortgageState(TypedDict):
user_query: str
research_results: dict
calculations: dict
final_guidance: str
compliance_flags: list
workflow = StateGraph(MortgageState)
workflow.add_node("research", research_agent)
workflow.add_node("calculate", calculation_agent)
workflow.add_node("guide", guidance_agent)
workflow.add_edge("research", "calculate")
workflow.add_edge("calculate", "guide")
workflow.add_edge("guide", END)
workflow.set_entry_point("research")
app = workflow.compile()
State is immutable per transition. If the calculation agent fails, LangGraph does not automatically roll back the research agent’s writes. The system logs the partial state and returns an error to the user. There is no transactional rollback. Compensating actions must be implemented manually if needed.
Model Context Protocol for Tool Boundaries
LendingTree uses MCP to expose mortgage-specific tools. Each agent has a scoped set of tools:
- Research Agent:
get_rates,search_lenders,fetch_product_details - Calculation Agent:
calculate_monthly_payment,generate_amortization_schedule,check_affordability - Guidance Agent:
format_recommendation,log_compliance_event
MCP servers enforce these boundaries. The research agent cannot invoke calculate_monthly_payment. The calculation agent cannot invoke search_lenders. This prevents cross-contamination and limits blast radius when an agent misbehaves.
MCP tool definitions include parameter schemas, return types, and authorization metadata. The orchestrator validates every tool call against the agent’s allowed set before forwarding to the MCP server.
Amazon Bedrock Guardrails
Bedrock guardrails operate at two layers:
- Model Invocation Layer: Filters prompts and completions for prohibited content (personally identifiable information, financial advice disclaimers, regulatory language).
- Orchestration Layer: Enforces rate limits, token budgets, and logging requirements.
LendingTree configured guardrails to block completions that lack required disclosures. If the guidance agent generates a recommendation without the federally mandated APR disclaimer, the guardrail rejects the completion and forces a retry with the disclosure template injected.
Guardrails also enforce output structure. The guidance agent must return JSON with specific fields: recommendation, disclaimer, sources, timestamp. If the model returns unstructured text, the guardrail rejects it.
Observability and Audit Trails
Every agent invocation writes to CloudWatch Logs with structured metadata:
- Agent ID
- Tool calls (name, parameters, result)
- Model invocation (prompt hash, completion hash, token count)
- Compliance flags (missing disclaimers, out-of-scope queries)
- Execution time and state transitions
LendingTree uses this log stream to reconstruct the decision path for any recommendation. If a user disputes advice, the compliance team can trace which tools were called, which data was retrieved, and which model generated the final text.
The system also emits custom CloudWatch metrics for agent-level success rates, tool invocation latency, and guardrail rejection counts. These feed into operational dashboards and alerting rules.
Failure Modes and Partial Execution
LangGraph does not provide automatic retries or circuit breakers. LendingTree implemented these at the agent level:
- Tool Timeout: If
get_ratesdoes not respond within 5 seconds, the research agent logs the failure and returns partial results. The calculation agent proceeds with cached rate data if available. - Model Failure: If Bedrock returns a 503, the agent retries up to three times with exponential backoff. After three failures, the orchestrator halts and returns an error to the user.
- Guardrail Rejection: If the guidance agent’s output is rejected, the orchestrator injects the missing disclaimer and retries once. If the second attempt fails, the system escalates to a human reviewer.
Partial execution is logged but not rolled back. If the research agent succeeds but the calculation agent fails, the user sees a partial response with an error message. The system does not attempt to undo the research agent’s work.
Deployment Shape
The system runs on AWS Lambda behind API Gateway. Each agent is a separate Lambda function. LangGraph’s orchestrator is another Lambda that invokes agents via direct function calls (not HTTP).
State is stored in DynamoDB. Each user session gets a unique partition key. The orchestrator writes state updates after each agent completes. This allows the system to resume from the last successful agent if a timeout occurs.
Amazon Bedrock is invoked via the AWS SDK. LendingTree uses Amazon Nova models with custom fine-tuning for mortgage terminology. Guardrails are configured per model and enforced server-side by Bedrock.
Trade-offs and Design Decisions
| Dimension | Choice | Trade-off |
|---|---|---|
| Orchestration | LangGraph state machine | Explicit control over handoffs, but no automatic retries or rollback |
| Tool Isolation | MCP per-agent scopes | Strong boundaries, but requires manual schema maintenance |
| Compliance | Bedrock guardrails | Server-side enforcement, but adds latency and retry complexity |
| State Persistence | DynamoDB per session | Resumable execution, but eventual consistency can cause stale reads |
| Deployment | Lambda per agent | Independent scaling, but cold starts add 200-500ms per invocation |
Technical Verdict
Use this architecture when:
- You need strong tool boundaries and auditable decision paths in a regulated domain.
- You can tolerate partial execution and manual compensating actions.
- You have distinct agent responsibilities that map cleanly to a directed graph.
- You need server-side compliance enforcement that cannot be bypassed by prompt injection.
Avoid this architecture when:
- You need transactional guarantees or automatic rollback on failure.
- Your agents must share tools dynamically or negotiate responsibilities at runtime.
- You cannot tolerate the latency overhead of guardrails and Lambda cold starts.
- Your compliance requirements demand synchronous human-in-the-loop approval before every action.
LendingTree’s system prioritizes auditability and compliance over execution speed. The architecture is defensible in court, but it is not fast. If you need sub-second responses, you will need to cache aggressively and pre-warm Lambda functions.