{"slug": "session-9-cheat-sheet-agent-servers", "title": "Session 9 Cheat Sheet — Agent Servers", "summary": "A developer created a cheat sheet for deploying LangGraph agent servers, detailing how to package a LangGraph agent, run it locally with langgraph dev, deploy to LangSmith cloud, and stream it into a Next.js UI. The architecture separates the agent API (hosted by LangSmith) from the UI (hosted on Vercel), with a server-side proxy to inject the API key securely.", "body_md": "A\n\nframeto help you reason through the assignment — concepts, diagrams, and the API map. It deliberately doesnotcontain the answers or filled-in activity code. Instead it gives you thequestions to ask yourselfand themethodto get there. The work — and the learning — is in packaging the agent,inspecting a Studio/LangSmith trace, shipping it, and writing your own conclusions.Source repo:\n\n`09_Agent_Servers/`\n\n(a packaged LangGraph agent + a Next.js`frontend/`\n\n).No notebook— Q1/Q2 are answered in`README.md`\n\n. Corpus:`data/cat_health_guidelines.pdf`\n\n(a feline-health PDF the RAG tool indexes in-memory; benign).\n\n| You want to… | Reach for | One-liner |\n|---|---|---|\n| Tell LangGraph what graphs exist | `langgraph.json` `graphs` |\n`\"simple_agent\": \"app.graphs.simple_agent:graph\"` (id → `module:attribute` ) |\n| Export a runnable graph | a module-level `graph` |\n`graph = create_agent(model=..., tools=..., system_prompt=...)` |\n| Run the agent API locally | `langgraph dev` |\nserves `http://localhost:2024` + opens LangGraph Studio |\n| Self-host a prod container | `langgraph up` |\nlocal Docker; you own scaling/uptime/auth |\n| Deploy to LangSmith cloud | `langgraph deploy` |\nmanaged build+host (needs LangSmith Plus) → Deployment URL |\n| Talk to the agent in Python | `langgraph_sdk.get_client` |\n`client.runs.stream(None, \"agent\", input={...}, stream_mode=\"updates\")` |\n| Stream the agent into a UI | `@langchain/react` `useStream` |\n`useStream({ apiUrl: \"/api\", assistantId: \"simple_agent\" })` |\n| Hide the API key from the browser | `langgraph-nextjs-api-passthrough` |\n`initApiPassthrough({ apiUrl, apiKey, runtime: \"edge\" })` in `route.ts` |\n| Mark a var public in Next.js | `NEXT_PUBLIC_` prefix |\nonly `NEXT_PUBLIC_*` reaches the browser; everything else is server-only |\n| Deploy the UI | `vercel` / `vercel --prod` |\nset `LANGGRAPH_API_URL` , `LANGSMITH_API_KEY` , `NEXT_PUBLIC_API_URL` |\n| See what the agent actually did | LangSmith traces / Studio | every run is traced; Studio steps through nodes + tool calls |\n\n**Anchor:** LangSmith hosts the **agent as an API**; Vercel hosts the **UI and the\nserver-side proxy that injects the secret** — the browser only ever talks to\nsame-origin `/api/*`\n\n.\n\n``` php\nflowchart LR\n  User[User in browser] --> Vercel[Next.js UI on Vercel]\n  Vercel -->|\"/api/* passthrough (injects key server-side)\"| LS[LangSmith Agent API]\n  LS --> Agent[Your LangGraph graph]\n  Agent --> Tools[Tavily + Arxiv + RAG tool]\n  LS --> Traces[LangSmith tracing]\n  subgraph local[Local dev]\n    Dev[\"langgraph dev :2024\"] --> Studio[LangGraph Studio]\n  end\n```\n\nASCII fallback:\n\n```\nbrowser ─► Vercel UI ─► /api proxy (adds LANGSMITH_API_KEY server-side) ─► LangSmith Agent API ─► graph ─► tools\n                                                                              └─► LangSmith traces\n  local:  langgraph dev :2024 ─► LangGraph Studio (debug/step/fork)\n```\n\n**Why this shape?** A deployed agent is a **stateful API** (threads / runs /\nassistants + streaming), not a website. The two deployment targets map to two\nconcerns: LangSmith runs + observes the agent; Vercel serves the UI and keeps the\nsecret on the trusted server tier. The same compiled graph runs in Studio (debug)\nand in production (hosted) — only the environment differs.\n\n```\nuv sync                 # agent deps (Python 3.13)\ncp .env.example .env    # fill OPENAI_API_KEY, TAVILY_API_KEY, LANGSMITH_API_KEY\ncd frontend && npm install   # the frontend ships complete — no create-next-app needed\n```\n\n| Component | Role |\n|---|---|\n`app/models.py` |\nmodel factory `get_chat_model()` (default `gpt-5.4-mini` , `temperature=0` ) |\n`app/tools.py` |\ntool belt: `TavilySearch` , `ArxivQueryRun` , `retrieve_information` (RAG) |\n`app/rag.py` |\nloads `data/*.pdf` → split 750/0 → `text-embedding-3-small` → in-memory Qdrant |\n`app/graphs/simple_agent.py` |\n`create_agent(...)` → exports compiled `graph` |\n`langgraph.json` |\nmanifest: `graphs` + `assistants` the server exposes |\n`frontend/app/api/[...path]/route.ts` |\nsecure passthrough — injects the key server-side |\n`frontend/components/chat.tsx` |\n`useStream` chat UI pointed at `/api` |\n\nA notebook agent becomes a server by exporting a **compiled graph** and\nregistering it.\n\n`langgraph.json`\n\nmaps a `graph_id`\n\nto `\"module:attribute\"`\n\nand\ndeclares named `assistants`\n\n. `dependencies: [\".\"]`\n\ninstalls the local package;\n`env: \".env\"`\n\nloads keys. Docs: [https://docs.langchain.com/langgraph-platform/](https://docs.langchain.com/langgraph-platform/)\n\n```\n\"graphs\": { \"simple_agent\": \"app.graphs.simple_agent:graph\" }\n```\n\n`langgraph dev`\n\nserves the Agent Server API at `:2024`\n\nwith hot reload and opens\nStudio. Studio = **debugging**: visualize topology, step through runs, inspect\ntool calls, fork threads, switch assistants. Not a production UI. Docs:\n[https://docs.langchain.com/langgraph-platform/langgraph-studio](https://docs.langchain.com/langgraph-platform/langgraph-studio)\n\nThe production integration path. A passing local smoke test proves the manifest, graph import, and streaming all work — the README gate before deploying.\n\n``` python\nfrom langgraph_sdk import get_client\nclient = get_client(url=\"http://localhost:2024\")\nfor chunk in client.runs.stream(None, \"agent\", input={\"messages\": [...]}, stream_mode=\"updates\"):\n    ...\n```\n\n`langgraph deploy`\n\n= managed LangSmith cloud build+host (needs **Plus**) → a\n`https://<...>.us.langgraph.app`\n\nDeployment URL + optional auto-update-on-push.\n`langgraph up`\n\n= self-hosted Docker container. Either way you get the same API\nsurface (threads/runs/assistants) plus tracing. Docs:\n[https://docs.langchain.com/langsmith/deployments](https://docs.langchain.com/langsmith/deployments).\n**Docker/self-host instructions:** `langgraph up`\n\n(Docker required, production-like local) —\n[https://docs.langchain.com/langsmith/local-dev-testing#langgraph-up](https://docs.langchain.com/langsmith/local-dev-testing#langgraph-up); standalone Agent\nServers via Docker / Docker Compose / Kubernetes —\n[https://docs.langchain.com/langsmith/deploy-standalone-server](https://docs.langchain.com/langsmith/deploy-standalone-server).\n\n**Cloud** deploy (`langgraph deploy`\n\nor GitHub→UI) **requires Plus — $39/seat/mo** 1.\n\n**Free without Plus:** everything local (\n\n`langgraph dev`\n\n+ Studio + SDK, all of Part 1),\ntracing (5k traces/mo on the Developer plan), and self-hosting via `langgraph up`\n\n(Docker).\n**Check your plan:** LangSmith →\n\n**Settings → Billing and Usage**(\n\n`smith.langchain.com/settings/payments`\n\n) — a *personal*org is\n\n**Developer**(free, no cloud deploy); a\n\n*team/shared*org is\n\n**Plus**. An\n\n*\"Upgrade to Plus\"*banner means you're not on it.\n\n**Upgrade** is self-serve there (add a card);\n\n**Enterprise** is contact-sales. Plus includes\n\n**1 free Dev deployment, unlimited runs**— enough for this assignment; beyond it, ~$0.005/run plus uptime (⚠️ a Production deployment left running accrues cost).\n\n**No-Plus path to the deliverable:** self-host with\n\n`langgraph up`\n\n, or record the Loom against the **local Studio** demo (the README accepts \"Studio debugging\" as one of its two demo options). Cost table:\n\n[pricing](https://www.langchain.com/pricing)\n\n.\n\n[2](https://gist.github.com/starred.atom#user-content-fn-pricing-a8ef8788b69bb001303b553fbcbe337c)| Plan | Price | Free traces/mo | Cloud deploy? |\n|---|---|---|---|\n| Developer | $0/seat, 1 seat | 5,000 | ❌ |\n| Plus | $39/seat/mo |\n10,000 | ✅ 1 free Dev deployment |\n| Enterprise | custom | custom | ✅ + self-hosted/hybrid |\n\n`create_agent`\n\nwires a ReAct-style agent: the model decides when to call a tool,\nthe tool runs, control returns until the model gives a final answer. Tools: Tavily\n(web), Arxiv (papers), `retrieve_information`\n\n(RAG over the cat-health PDF).\n\nA `\"use client\"`\n\ncomponent subscribes to the agent's event stream and renders\nmessages as they arrive. Point it at the same-origin `/api`\n\nproxy, not the\nLangSmith URL directly. Docs: [https://www.npmjs.com/package/@langchain/react](https://www.npmjs.com/package/@langchain/react)\n\n```\nconst { messages, submit, isLoading } = useStream({ apiUrl: \"/api\", assistantId: \"simple_agent\" });\n```\n\nAnything in client code is readable by the user. The passthrough route runs\n**server-side** and injects `LANGSMITH_API_KEY`\n\ninto the upstream request; the\nbrowser only sees `/api/*`\n\n. Only `NEXT_PUBLIC_*`\n\nvars are public. Docs:\n[https://www.npmjs.com/package/langgraph-nextjs-api-passthrough](https://www.npmjs.com/package/langgraph-nextjs-api-passthrough)\n\n```\nexport const { GET, POST, ... } = initApiPassthrough({\n  apiUrl: process.env.LANGGRAPH_API_URL, apiKey: process.env.LANGSMITH_API_KEY, runtime: \"edge\" });\n```\n\nSet Root Directory to `frontend`\n\n, add `LANGGRAPH_API_URL`\n\n+ `LANGSMITH_API_KEY`\n\n(server-only) + `NEXT_PUBLIC_API_URL`\n\n, then `vercel --prod`\n\n. Verify end-to-end:\nthe live site streams, tool calls fire, traces appear in LangSmith. Docs:\n[https://vercel.com/docs/frameworks/nextjs](https://vercel.com/docs/frameworks/nextjs)\n\n### Q1 — Why does LangSmith deploy your agent as an API backend only, and why still a separate Vercel frontend?\n\n**Method to get there — ask yourself:**\n\n- When you hit your deployed agent, what comes back — HTML you could render in a\nbrowser, or JSON/streamed events? What does that tell you about whether LangSmith\ncan\n*be*your website? - List what the agent API exposes (threads? runs? assistants?). Is any of that a user interface?\n- If you skipped Vercel and pointed the browser directly at the LangSmith URL, what would the user need in the request — and what does §7 say about putting that in the browser?\n- Frame your answer as \"two concerns, two hosts.\" Name each host's job in one line.\n\n**Method to get there — ask yourself:**\n\n- Open devtools on any site → Network + Sources. What can you read? Could a secret compiled into client JS stay hidden?\n- In Next.js, which env vars reach the browser? What does the\n`NEXT_PUBLIC_`\n\nprefix do, and why are`LANGGRAPH_API_URL`\n\n/`LANGSMITH_API_KEY`\n\ndeliberately*not*prefixed while`NEXT_PUBLIC_API_URL`\n\nis? - Trace one request: browser →\n`/api/*`\n\n→ ? Where does`initApiPassthrough`\n\nadd the key — on the user's machine or on Vercel's server? - What could someone do with your key if they lifted it from the bundle? Let that consequence anchor your \"why.\"\n\n**Deliverable:** a new graph that, *after* the agent answers, has a judge model\ndecide whether the response was helpful and loops back for another attempt if not —\nwith a **safe loop limit** — registered in `langgraph.json`\n\n, deployed, with traces\ncompared for a passing vs failing query.\n**Method to get there — ask yourself:**\n\n- The provided agent uses\n`create_agent`\n\n. Can you insert a step that runs*after*the final answer with it? If not, what lower-level construct lets you own the nodes and edges (and a cycle)? - What nodes do you need — who answers, who runs tools, who judges? Draw the edges:\nwhen does the judge send control\n*back*to the agent vs to the end? - How will the judge \"decide\"? What does it compare (the answer against…?), and how do you keep its output easy to branch on?\n**What would happen if** the judge kept saying \"not helpful\"? Design the loop limit*first*— what will you count, and where do you force the end?- In Studio/LangSmith, inspect both runs: does the passing query end in one pass?\nDoes the failing one show the retry edge firing? Where do you\n*see*the judge call? - Reflect (the README asks): is the loop's\n*logic*any different in Studio vs production — or is it the same graph in a different environment?\n\n**Deliverable:** describe (optionally implement) how to add authentication so each\nuser only sees their own threads.\n**Method to get there — ask yourself:**\n\n- Hiding the chat page behind a login in React — does that actually stop someone\nfrom reading\n*another*user's threads through the API? Where must the real check live? - What would the server need to know on each request to scope threads to one user, and what could you stamp on a thread when it's created so reads can be filtered?\n- Where should the user's token be attached — the same place §7 puts the API key, or the browser? Why?\n- Look at the README's\n`lsd-custom-route-react-ui`\n\nreference for the pattern.\n\nGrounded against the LangChain docs and the LangChain pricing page (verify — plans and prices change; figures current ~mid-2026).\n\n**LangSmith Plus / deployment / cost (§4½):**\n\n- Billing setup, plan check, and upgrade-to-Plus steps —\n[https://docs.langchain.com/langsmith/billing](https://docs.langchain.com/langsmith/billing) - Deployment environments (Cloud vs standalone vs self-hosted; plan requirements) —\n[https://docs.langchain.com/langsmith/deployment](https://docs.langchain.com/langsmith/deployment) - Local development & testing (\n`langgraph dev`\n\nvs`langgraph up`\n\n) —[https://docs.langchain.com/langsmith/local-dev-testing](https://docs.langchain.com/langsmith/local-dev-testing)\n\n**Docker / self-host deployment ( langgraph up, standalone container):**\n\n- Self-host standalone Agent Servers —\n**Docker, Docker Compose, Kubernetes**—[https://docs.langchain.com/langsmith/deploy-standalone-server](https://docs.langchain.com/langsmith/deploy-standalone-server) `langgraph up`\n\n(Docker required; production-like local: API + PostgreSQL + Redis on :8123) —[https://docs.langchain.com/langsmith/local-dev-testing#langgraph-up](https://docs.langchain.com/langsmith/local-dev-testing#langgraph-up)- LangGraph CLI\n`up`\n\n/`build`\n\n/`dockerfile`\n\ncommands —[https://docs.langchain.com/langsmith/cli](https://docs.langchain.com/langsmith/cli) - Self-hosted deployment topologies (standalone vs hybrid vs full platform) —\n[https://docs.langchain.com/langsmith/deploy-to-self-hosted-overview](https://docs.langchain.com/langsmith/deploy-to-self-hosted-overview)\n\n**Packaging, server, SDK, frontend:**\n\n- LangGraph CLI reference (\n`dev`\n\n/`build`\n\n/`deploy`\n\n/`up`\n\n) —[https://docs.langchain.com/langsmith/cli](https://docs.langchain.com/langsmith/cli) - Application structure (\n`langgraph.json`\n\n) —[https://docs.langchain.com/langsmith/application-structure](https://docs.langchain.com/langsmith/application-structure) - Default assistants (the run id is the\n**graph id**) —[https://docs.langchain.com/langsmith/assistants](https://docs.langchain.com/langsmith/assistants) - Run a local server / Studio —\n[https://docs.langchain.com/oss/python/langgraph/local-server](https://docs.langchain.com/oss/python/langgraph/local-server) `useStream`\n\n(frontend streaming) —[https://www.npmjs.com/package/@langchain/react](https://www.npmjs.com/package/@langchain/react)- Secure passthrough proxy —\n[https://www.npmjs.com/package/langgraph-nextjs-api-passthrough](https://www.npmjs.com/package/langgraph-nextjs-api-passthrough) - Deploy the UI on Vercel (Next.js) —\n[https://vercel.com/docs/frameworks/nextjs](https://vercel.com/docs/frameworks/nextjs)\n\n## Footnotes\n\n-\nDeploy to Cloud —\n\n*\"Agent deployments running on Cloud require a Plus plan or above\"*—[https://docs.langchain.com/langsmith/deploy-to-cloud-overview](https://docs.langchain.com/langsmith/deploy-to-cloud-overview)[↩](https://gist.github.com/starred.atom#user-content-fnref-plus-a8ef8788b69bb001303b553fbcbe337c) -\nLangSmith pricing (Developer $0 / Plus $39-seat / Enterprise custom; free-trace tiers; deployment run + uptime rates) —\n\n[https://www.langchain.com/pricing](https://www.langchain.com/pricing)[↩](https://gist.github.com/starred.atom#user-content-fnref-pricing-a8ef8788b69bb001303b553fbcbe337c)", "url": "https://wpnews.pro/news/session-9-cheat-sheet-agent-servers", "canonical_source": "https://gist.github.com/donbr/be86b6da2cff3d9fbae0de3f8c5fa985", "published_at": "2026-07-01 00:10:45+00:00", "updated_at": "2026-07-08 03:58:01.809333+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "large-language-models", "ai-infrastructure"], "entities": ["LangGraph", "LangSmith", "Next.js", "Vercel", "Tavily", "Arxiv", "Qdrant", "OpenAI"], "alternates": {"html": "https://wpnews.pro/news/session-9-cheat-sheet-agent-servers", "markdown": "https://wpnews.pro/news/session-9-cheat-sheet-agent-servers.md", "text": "https://wpnews.pro/news/session-9-cheat-sheet-agent-servers.txt", "jsonld": "https://wpnews.pro/news/session-9-cheat-sheet-agent-servers.jsonld"}}