- Collects warranty information before proceeding.
- Classifies issues as hardware or software.
- Provides solutions or escalates to human support.
- Maintains conversation state across multiple turns.
Setup
-
Install the
langchainpackage:For more details, see our Installation guide. -
Set up LangSmith to inspect what is happening inside your agent:
-
Select a chat model. For this tutorial, we’ll use Claude 3.5 Sonnet:
1. Define custom state
First, define a custom state schema that tracks which stage is currently active:current_stage field is the core of the handoffs pattern - it determines which configuration (prompt + tools) is loaded on each turn.
2. Create handoff tools
Create tools that update the workflow state. These tools allow the agent to record information and transition to the next stage. The key to handoffs is usingCommand to update state, including the current_stage field:
record_warranty_status and record_issue_type return Command objects that update both the data (warranty_status, issue_type) AND the current_stage. This is the handoff mechanism - tools control the workflow.
3. Define stage configurations
Now define prompts and tools for each stage. We’ll use a simple dictionary to map stage names to their configurations:- See all stages at a glance
- Add new stages (just add another entry)
- Understand the workflow dependencies (
requiresfield) - Use prompt templates with state variables (e.g.,
{warranty_status})
4. Create stage-based middleware
Create middleware that readscurrent_stage from state and applies the appropriate configuration. We’ll use the @wrap_model_call decorator for a clean implementation:
- Reads current stage: Gets
current_stagefrom state (defaults to “warranty_collector”). - Looks up configuration: Finds the matching entry in
STAGE_CONFIG. - Validates dependencies: Ensures required state fields exist.
- Formats prompt: Injects state values into the prompt template.
- Applies configuration: Overrides the system prompt and available tools.
request.override() method is key - it allows us to dynamically change the agent’s behavior based on state without creating separate agent instances.
5. Create the agent
Now create the agent with the stage-based middleware and a checkpointer for state persistence:Why a checkpointer? The checkpointer maintains state across conversation turns. Without it, the
current_stage state would be lost between user messages, breaking the handoff flow.6. Test the workflow
Test the complete handoff workflow:- Warranty verification stage: Asks about warranty status
- Issue classification stage: Asks about the problem, determines it’s hardware
- Resolution stage: Provides warranty repair instructions
7. Understanding the handoff mechanism
Let’s trace what happens at each turn:Turn 1: Initial message
- System prompt:
WARRANTY_COLLECTOR_PROMPT - Tools:
[record_warranty_status]
Turn 2: After warranty recorded
Tool call:record_warranty_status("in_warranty") returns:
- System prompt:
ISSUE_CLASSIFIER_PROMPT(formatted withwarranty_status="in_warranty") - Tools:
[record_issue_type]
Turn 3: After issue classified
Tool call:record_issue_type("hardware") returns:
- System prompt:
RESOLUTION_SPECIALIST_PROMPT(formatted withwarranty_statusandissue_type) - Tools:
[provide_solution, escalate_to_human]
current_stage, and middleware responds by applying the appropriate configuration.
8. Manage message history
A critical aspect of production handoffs is managing what each agent sees in the conversation history. Without proper management, message history grows unbounded and agents can get confused by conversations from other stages. After a few agent transitions, the full message history includes conversations from all previous agents. The key is to separate message history from cross-agent memory:- Message history: Agent-scoped, bounded, ephemeral (what the agent sees)
- State dict: Cross-agent, persistent, structured data (what the agent knows)
- System messages: Bridge between state and context (injected summaries)
@before_model middleware to trim messages before each agent sees them:
9. Add flexibility: Go back
A key UX requirement is allowing users to correct mistakes. Add “go back” tools:Complete example
Here’s everything together in a runnable script:Next steps
- Learn about the supervisor pattern for centralized orchestration
- Explore middleware for more dynamic behaviors
- Read the multi-agent overview to compare patterns
- Use LangSmith to debug and monitor your multi-agent system