Building AI Agents with LangChain and LangGraph: Part 2 › Reply Agent Implementation
Michael BrenndoerferAugust 2, 20252 min read
Building AI Agents with LangChain and LangGraph: Part 2 › Reply Agent ImplementationOne section · Sections in this article8 / 9 ↓
Sections in this article9
Reading tools Definitions & inline links
Toggle tooltip visibility. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
Let's combine everything we've learned into a simple reply agent that demonstrates all the key concepts:
- Workflow orchestration with conditional logic
- Tool integration with proper error handling
- Clean architecture for maintainability
- Extensible design for adding more tools and capabilities
This serves as a template for building real-world agentic systems.
In[19]:
Code# reply_agent.py
from typing import Literal
from langchain.chat_models import init_chat_model
from langchain.tools import tool
from langgraph.graph import MessagesState, StateGraph, END, START
@tool
def draft_customer_reply(customer_name: str, request_category: str, reply: str) -> str:
"""Draft a reply to a customer."""
return f"I am drafting a reply to {customer_name} in the category {request_category}.\n Content: {reply}"
llm = init_chat_model("google_vertexai:gemini-2.0-flash", temperature=0)
model_with_tools = llm.bind_tools([draft_customer_reply], tool_choice="any")
def call_llm(state: MessagesState) -> MessagesState:
"""Run LLM"""
output = model_with_tools.invoke(state["messages"])
return {"messages": [output]}
def run_tool(state: MessagesState) -> MessagesState:
"""Performs the tool call"""
result = []
for tool_call in state["messages"][-1].tool_calls:
observation = draft_customer_reply.invoke(tool_call["args"])
result.append(
{"role": "tool", "content": observation, "tool_call_id": tool_call["id"]}
)
return {"messages": result}
def should_continue(state: MessagesState) -> Literal["run_tool", "__end__"]:
"""Route to tool handler, or end if Done tool called"""
# Get the last message
messages = state["messages"]
last_message = messages[-1]
# If the last message is a tool call, check if it's a Done tool call
if last_message.tool_calls:
return "run_tool"
# Otherwise, we stop (reply to the user)
return END
# Create the workflow
workflow = StateGraph(MessagesState)
# Nodes
workflow.add_node("call_llm", call_llm)
workflow.add_node("run_tool", run_tool)
# Edges
workflow.add_edge(START, "call_llm")
workflow.add_conditional_edges(
"call_llm", should_continue, {"run_tool": "run_tool", END: END}
)
workflow.add_edge("run_tool", END)
# Compile the workflow
app = workflow.compile()Running Your Production Agent
To deploy this agent, save the code above as reply_agent.py and run it from your terminal:
python reply_agent.pyThe agent will process your request through the complete workflow, demonstrating how all the concepts work together in a real application.
Example Usage and Output
Here's what happens when you run the agent:
Input: "Inform Jeremy about his delivery status being in-progres"
Processing:
- LLM analyzes the request
- Determines appropriate tool and parameters
- Executes the reply tool
- Returns formatted result
Output: Complete reply with correct classification
In[20]:
Code# Demonstration of the complete workflow
result = app.invoke(
{
"messages": [
{
"role": "user",
"content": "Inform Jeremy about his delivery status being in-progres.",
}
]
}
)
print("=== Agent Workflow Result ===")
for message in result["messages"]:
message.pretty_print()Out[20]:
Console=== Agent Workflow Result ===
================================[1m Human Message [0m=================================
Inform Jeremy about his delivery status being in-progres.
==================================[1m Ai Message [0m==================================
Tool Calls:
draft_customer_reply (e1122d59-7c36-41b3-a8fe-d1f235c79a98)
Call ID: e1122d59-7c36-41b3-a8fe-d1f235c79a98
Args:
request_category: Delivery Status
customer_name: Jeremy
reply: Your delivery is in progress.
=================================[1m Tool Message [0m=================================
I am drafting a reply to Jeremy in the category Delivery Status.
Content: Your delivery is in progress.