{"id":50831365,"url":"https://github.com/langchain-samples/travel-planner-deepagents-workshop","last_synced_at":"2026-06-13T23:30:32.834Z","repository":{"id":358723583,"uuid":"1242727247","full_name":"langchain-samples/travel-planner-deepagents-workshop","owner":"langchain-samples","description":null,"archived":false,"fork":false,"pushed_at":"2026-05-18T19:29:42.000Z","size":4418,"stargazers_count":0,"open_issues_count":7,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-18T21:44:12.065Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/langchain-samples.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-18T17:39:54.000Z","updated_at":"2026-05-18T19:29:46.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/langchain-samples/travel-planner-deepagents-workshop","commit_stats":null,"previous_names":["langchain-samples/travel-planner-deepagents-workshop"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/langchain-samples/travel-planner-deepagents-workshop","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/langchain-samples%2Ftravel-planner-deepagents-workshop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/langchain-samples%2Ftravel-planner-deepagents-workshop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/langchain-samples%2Ftravel-planner-deepagents-workshop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/langchain-samples%2Ftravel-planner-deepagents-workshop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/langchain-samples","download_url":"https://codeload.github.com/langchain-samples/travel-planner-deepagents-workshop/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/langchain-samples%2Ftravel-planner-deepagents-workshop/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34304627,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-13T02:00:06.617Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-13T23:30:31.880Z","updated_at":"2026-06-13T23:30:32.828Z","avatar_url":"https://github.com/langchain-samples.png","language":"Jupyter Notebook","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Deep Agents Travel Planner Workshop\n\nA hands-on, single-notebook walkthrough that builds a production-style travel planner agent from scratch using [Deep Agents](https://docs.langchain.com/oss/python/deepagents/overview) on top of LangChain and LangGraph, then evaluates it with LangSmith.\n\nThe notebook lives at `notebooks/deepagents-travel-planner.ipynb` and is designed to be worked through top-to-bottom in a guided session with a LangChain engineer.\n\n## What You'll Build\n\nBy the end of the notebook you'll have a travel planning agent that can:\n\n- Plan a multi-day trip from a single user request\n- Delegate research to specialized subagents (`hotel-search`, `flight-search`, `activity-search`) running in parallel\n- Read and write files on a virtual filesystem via `read_file` / `write_file` / `edit_file`\n- Pause for human approval before \"booking\" anything\n- Remember a traveler's preferences across conversations (per-user, with a shared global namespace)\n- Follow a team-authored `AGENTS.md` and load on-demand `SKILL.md` files for each deliverable (itinerary, budget, packing list, travel brief)\n- Emit a final itinerary and budget in your team's exact format\n\nYou'll also build a small LangSmith evaluation suite that runs the same dataset against two OpenAI models (`gpt-5.4` and `gpt-4.1-mini`), with four metrics — trajectory match, constraint check, efficiency, and LLM-as-judge response quality — so you can compare cost / latency / quality side-by-side in the LangSmith experiment comparison view.\n\n## Notebook Outline\n\nThe notebook is split into eleven parts. Each part introduces one concept and adds one capability:\n\n| Part | Topic | What's introduced |\n| --- | --- | --- |\n| 0 | Setup \u0026 Installation | `uv sync` or `pip install -r requirements.txt`, `.env`, model config |\n| 1 | Your First Deep Agent | `create_deep_agent`, the harness, planner + virtual filesystem out of the box |\n| 2 | Adding Custom Tools | Deterministic offline stubs for discovery (`search_travel`) and pricing/availability |\n| 3 | Understanding Backends | `StateBackend` (per-thread default), preview of `StoreBackend` for cross-thread persistence |\n| 4 | Adding Subagents | `hotel-search`, `flight-search`, `activity-search` + an orchestrator that fans out via `task()` |\n| 5 | Middleware Deep Dive | Built-in `TodoListMiddleware`, writing a custom `@wrap_tool_call` logger |\n| 6 | Human-in-the-Loop | `HumanInTheLoopMiddleware`, interrupts, `Command(resume=...)` |\n| 7 | Long-Term Memory | `CompositeBackend` routing `/memories/user/` and `/memories/shared/` to a `StoreBackend` with per-user namespaces |\n| 8 | `AGENTS.md` \u0026 Skills | Identity file + on-demand `SKILL.md` files for each deliverable |\n| 9 | The Complete Travel Planner | All layers composed end-to-end |\n| 10 | Evaluations | LangSmith dataset, four evaluators (trajectory, constraint, efficiency, LLM-judge), two-model comparison |\n| 11 | Next Steps | Where to take the agent next (real APIs, calendar, multi-leg trips, group travel) |\n\nEach part is independently runnable — you can stop at any layer and have a working agent for that scope.\n\n## Pre-work\n\n### Clone the repo\n```bash\ngit clone \u003crepo-url\u003e\ncd travel-planner-deepagents-workshop\n```\n\n### Configure environment variables\n```bash\ncp .env.example .env\n# Fill in: OPENAI_API_KEY (or your provider's keys) + LANGSMITH_API_KEY for Part 10 evals\n```\n\nNo Tavily key needed — discovery is handled by a deterministic offline stub so the workshop runs without external APIs.\n\nIf corporate policy blocks API keys, contact your LangChain representative and we'll find a workaround.\n\n### Install dependencies\n\nTwo options — both install the exact same pinned versions (`requirements.txt` is generated from `uv.lock` and is pip-tested on Python 3.11).\n\n**Option A: `uv`** (recommended if you have it)\n```bash\npip install uv\nuv sync\nsource .venv/bin/activate\n```\n\n**Option B: `pip`**\n```bash\npython3.11 -m venv .venv\nsource .venv/bin/activate\npip install --upgrade pip\npip install -r requirements.txt\n```\n\nVersions are pinned to a known-good combo (`deepagents==0.5.2`, `langgraph==1.1.6`, `langchain-core==1.2.28`) to avoid the `ToolRuntime.__init__() missing 'tools'` skew that newer `langgraph` releases trigger with `deepagents` 0.5.x.\n\n## Running\n\n### As a notebook\n\nOpen `notebooks/deepagents-travel-planner.ipynb` in JupyterLab, VS Code, or Cursor and select the workshop's `.venv` as the kernel.\n\nIf your editor doesn't auto-detect the venv, register it as a named Jupyter kernel:\n\n```bash\n.venv/bin/python -m ipykernel install --user --name=travel-planner --display-name=\"Travel Planner\"\n```\n\nThen pick **Travel Planner** from the kernel selector.\n\n### As a LangGraph Studio agent\n\nThe agent in `agents/travel_planner/` is registered in `langgraph.json`. Launch it locally with:\n\n```bash\nsource .venv/bin/activate\nlanggraph dev\n```\n\nThis starts an API server at `http://localhost:2024` and prints a LangGraph Studio URL. Studio gives you a visual graph view, message-level tracing, checkpoint history, and a chat panel.\n\n## Model Configuration\n\nModel selection is centralized in `utils/models.py`. The default is OpenAI (`openai:gpt-5.4`). To use a different provider, edit `.env` only — `utils/models.py` auto-detects Azure OpenAI when `AZURE_OPENAI_ENDPOINT` is set. AWS Bedrock and Google Vertex AI examples are kept as commented blocks in `utils/models.py` for reference.\n\nThe notebook's Part 10 evaluations call `get_model()` (from `utils/models.py`), so the eval section automatically inherits the active provider — no code edits needed.\n\n### Azure OpenAI / APIM gateway (Azure URL shape)\n\nSetting `AZURE_OPENAI_ENDPOINT` in `.env` auto-switches `utils/models.py` to `AzureChatOpenAI`. No code changes required. Required vars:\n\n```\nAZURE_OPENAI_API_KEY=\u003cyour-key\u003e\nAZURE_OPENAI_ENDPOINT=\u003cyour-endpoint\u003e\nAZURE_OPENAI_API_VERSION=2025-03-01-preview\nAZURE_OPENAI_DEPLOYMENT=\u003cdeployment-name\u003e\n```\n\nNote: Part 10's two-model comparison targets the same Azure deployment in this mode — LangSmith renders two distinct experiments (different `experiment_prefix` labels), but the underlying compute is identical. For true cross-model comparison, use standard OpenAI credentials.\n\n### AWS Bedrock\n```\nAWS_ACCESS_KEY_ID=...\nAWS_SECRET_ACCESS_KEY=...\nAWS_REGION_NAME=us-east-1\nAWS_MODEL_ARN=...\n```\n\n### Google Vertex AI\n```\nGOOGLE_APPLICATION_CREDENTIALS=./vertexCred.json\n```\nMake sure `vertexCred.json` is in `.gitignore`.\n\n## Repo Layout\n\n```\ntravel-planner-deepagents-workshop/\n├── notebooks/\n│   └── deepagents-travel-planner.ipynb   # the workshop notebook\n├── agents/\n│   └── travel_planner/                   # standalone agent for `langgraph dev`\n│       ├── agent.py                      # mirrors the notebook's final composition\n│       ├── AGENTS.md                     # agent identity \u0026 workflow rules\n│       └── skills/                       # on-demand output formats\n│           ├── itinerary-format/SKILL.md\n│           ├── budget-summary/SKILL.md\n│           ├── packing-list/SKILL.md\n│           └── travel-brief/SKILL.md\n├── utils/\n│   └── models.py                         # centralized model selection\n├── langgraph.json                        # registers the travel_planner agent\n├── pyproject.toml\n├── requirements.txt                      # pinned, pip-tested\n└── .env.example\n```\n\n## Resources\n\n- **[Deep Agents Documentation](https://docs.langchain.com/oss/python/deepagents/)** — harness reference, backends, middleware\n- **[LangChain Documentation](https://docs.langchain.com/oss/python/langchain/overview)** — `create_agent`, tools, middleware\n- **[LangGraph Documentation](https://docs.langchain.com/oss/python/langgraph/overview)** — state, interrupts, `Store`, checkpointers\n- **[LangChain vs LangGraph vs Deep Agents](https://docs.langchain.com/oss/python/concepts/products)** — how the layers relate\n- **[LangSmith](https://smith.langchain.com)** — tracing, datasets, evaluations, the experiment comparison view used in Part 10\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flangchain-samples%2Ftravel-planner-deepagents-workshop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flangchain-samples%2Ftravel-planner-deepagents-workshop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flangchain-samples%2Ftravel-planner-deepagents-workshop/lists"}