Practical Examples

Three examples: RAG agent, multi-tool agent, LangGraph workflow.


Example 1: Doc Q&A bot (RAG agent)

Index docs/ and answer with a search tool + create_agent (see full code in the Chinese edition—structure is identical).

Key steps:

  1. DirectoryLoader + RecursiveCharacterTextSplitter
  2. Chroma + OpenAIEmbeddings
  3. @tool search_knowledge_base wrapping retriever.invoke
  4. checkpointer for multi-turn

Validate with doc-specific questions; inspect tool I/O in LangSmith.


Example 2: Research assistant (multi-tool)

Tools: web search stub, safe math, UTC time.

from datetime import datetime, timezone
from langchain.tools import tool
from langchain.agents import create_agent
from langgraph.checkpoint.memory import InMemorySaver

@tool
def web_search(query: str) -> str:
    """Search the web (demo stub)."""
    return f"[demo] Top result for '{query}': LangChain 1.0 uses create_agent on LangGraph."

@tool
def calculate(expression: str) -> str:
    """Evaluate a math expression."""
    return str(eval(expression, {"__builtins__": {}}, {}))

@tool
def now_utc() -> str:
    """Current UTC time."""
    return datetime.now(timezone.utc).isoformat()

agent = create_agent(
    "openai:gpt-4.1-mini",
    tools=[web_search, calculate, now_utc],
    checkpointer=InMemorySaver(),
)

Do not use eval on untrusted input in production.


Example 3: LangGraph QA workflow

Generate → check length → rewrite until OK:

from typing_extensions import TypedDict, Literal
from langgraph.graph import StateGraph, START, END
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model="gpt-4.1-mini", temperature=0.7)

class State(TypedDict):
    topic: str
    article: str
    ok: bool

def generate(state: State) -> dict:
    msg = llm.invoke(f"Write a 2-sentence article about {state['topic']}.")
    return {"article": msg.content, "ok": len(msg.content) >= 80}

def rewrite(state: State) -> dict:
    msg = llm.invoke(f"Expand this to at least 80 chars:\n{state['article']}")
    return {"article": msg.content, "ok": len(msg.content) >= 80}

def check(state: State) -> Literal["end", "rewrite"]:
    return "end" if state["ok"] else "rewrite"

graph = StateGraph(State)
graph.add_node("generate", generate)
graph.add_node("rewrite", rewrite)
graph.add_edge(START, "generate")
graph.add_conditional_edges("generate", check, {"end": END, "rewrite": "rewrite"})
graph.add_conditional_edges("rewrite", check, {"end": END, "rewrite": "rewrite"})
app = graph.compile()

Anti-patterns

Ship RAG without evals; one global thread for all users; InMemory checkpoints in prod.


Next steps