Proving it still works
Five tests, one for each promise the desk makes. They run in under a second and need no key, which is what makes them worth having.
Every test sends one message on a fresh thread and looks at the reply.
from langgraph.checkpoint.memory import InMemorySaver
from desk import agent
from tools import Customer
THREAD = 0
def ask(who, text):
global THREAD
THREAD += 1
config = {"configurable": {"thread_id": f"t{THREAD}"}}
result = agent.invoke({"messages": [{"role": "user", "content": text}]}, config,
context=Customer(who), version="v2")
return result.value["messages"][-1].textdef test_an_order_is_answered_to_its_owner():
assert "shipped" in ask("ravi", "Where is A17?")
def test_another_customers_order_is_refused():
assert "not one of your orders" in ask("mei", "Where is A17?")
def test_a_policy_question_is_answered_from_the_documents():
assert "5 working days" in ask("ravi", "How long does a refund take?")
def test_an_uncovered_question_is_refused():
assert "A person will reply" in ask("ravi", "Do you sell gift cards?")
def test_passwords_never_reach_the_model():
assert "reset link" in ask("ravi", "What is my password?")pytest -q -p no:warnings test_desk.pyPick one to watch it run, step by step.
Each test walks one path through the drawing: two through the order tools, one through the policy search, and one that the guardrail ends before the model is reached at all.
The owner check, the policy answer, the refusal and the guardrail are all covered. Run these before swapping in a hosted model: if they pass, your code is right, and anything that changes afterwards is the model.
Where to read next
LangChain is larger than one desk. These are the areas left out above, and what each is for.
| Topic | What it is for |
|---|---|
| Event streaming | stream_events with version="v3": typed events for tokens, tool calls and middleware, recommended for new apps. |
| Handoffs | Agents that pass the whole conversation to another agent, which then talks to the user directly. |
| Skills | Loading instructions and tools into an agent only when a task needs them. |
| Custom workflows | Mixing fixed steps and agents in one LangGraph graph. |
| Multi-agent tutorials | A personal assistant with subagents, customer support with handoffs, a knowledge base with a parallel router, and a SQL assistant with skills. |
| SQL agent | An agent that writes and runs SQL queries against a database. |
| LangSmith observability | Tracing every run to LangSmith by setting two environment variables. |
| Integration tests and evals | Testing against real providers, and scoring an agent's answers on a dataset. |
| Context engineering and memory concepts | The documentation's guides to what goes into each model call, and to kinds of memory. Lessons 18 and 22 use two of its techniques. |
| Component architecture | Diagrams of how models, tools, retrievers, vector stores and agents fit together. |
| Runtimes, frameworks and harnesses | How LangChain, LangGraph and Deep Agents relate. |
| Deep Agents | A ready-made agent on top of LangChain with planning, a virtual filesystem and subagents. |
| Frontend and Agent Chat UI | React components and a chat interface for LangChain agents. |
| Deployment and Studio | Running agents on LangSmith's servers and inspecting them in a browser. |
| Voice agents | Speech in and out around an agent. |
| Provider integrations | Hundreds of chat models, embedding models, vector stores and loaders, each its own package. |
- Add a returns policy to
POLICIESand a test that asks about returns. - Add a test that a refund Mei is not entitled to leaves
ORDERSalone. - Point
DeskModelat a hosted model and run the tests again.
You understood something today that you didn't yesterday.