TravelPlanner代理
一个旅行计划系统,使用MCP服务器引导Claude代理完成一个自主的7阶段工作流程:从用户意图到发布的包含行程、餐厅、酒店和评论注释的Notion旅行计划。
运作原理
User: "Plan a trip to Tokyo, Apr 10-18"
|
v
+---------------+ +--------------------+
| Claude Agent | | travel-planner MCP | (stdio)
| | | |
| - WebSearch | | - workflow state |
| - Notion MCP | | - validation |
| - reasoning | | - stage prompts |
+---------------+ +--------------------+
|
v
+---------------+
| Notion MCP | (4 databases)
+---------------+MCP服务器充当 工作流编排器 -它管理状态,验证工件,并告诉代理接下来要做什么。代理人做 发电工作 --搜索POI、安排行程并发布到Notion。
自主循环
在用户发出请求后,代理在没有人为干预的情况下运行一个自驱动循环:
resume_trip(workspace_id) or resume_latest()
|
+---> found? resume from where it left off
+---> not found?
|
v
start_trip(destination, dates, workspace_tag="tokyo-spring")
| returns session_id + workspace_id
v
+-> get_next_action(session_id) -----> returns stage instructions
| |
| v
| Agent generates artifact (WebSearch, scheduling, etc.)
| |
| v
| submit_artifact(session_id, stage, data)
| |
| +---> rejected? fix violations, resubmit (max 3 attempts)
| +---> accepted? loop back to get_next_action
| +---> blocked? ask user for help
|
+-- repeat until all stages complete会话恢复
会话通过以下方式在对话中持续存在 workspace_id。当对话结束时,代理可以稍后继续:
resume_trip(workspace_id)--恢复特定会话(start_trip返回的workspace_id)resume_latest()--自动恢复最近活动的会话,或列出多个会话供用户选择- 代理提示包括在开始任何新行程之前运行的步骤0恢复检查
七个阶段
| # | 阶段 | 代理做什么 | 服务器做什么 |
|---|---|---|---|
| 1 | POI搜索 | WebSearch 30-50个兴趣点 | 根据JSON模式进行验证 |
| 2 | 调度 | 将POI安排到每日行程中 | 使用硬规则引擎进行验证(日落时间、场地关闭、时间重叠、旅行时间) |
| 3 | 餐馆 | 在网上搜索每天poi附近的午餐/晚餐 | 验证日期参考和near_poi链接 |
| 4 | 酒店 | WebSearch查找夜间区域集群附近的酒店 | 验证入住/退房日期 |
| 5 | 审查 | (无-服务器端) | 运行硬规则+软规则+可选的Codex审查,合并到审查报告中 |
| 6 | 概念 | 通过Notion MCP创建4个Notion数据库 | 生成发布清单,跟踪部分发布进度 |
| 7 | 验证 | Playwright的Notion页面截图 | 标记行程已完成 |
回顾与回归
第5阶段(审查)很特别——它完全在服务器端运行。如果发现硬约束违规,服务器 使工作流程倒退 使用机器可读的补救有效负载返回到违规阶段:
{
"status": "regressed",
"target_stage": "scheduling",
"violations": [{"rule": "nature_sunset", "item": "Mount Fuji", "detail": "ends at 20:00, limit is 19:00"}],
"stale_artifacts": ["itinerary", "restaurants", "hotels"],
"valid_artifacts": ["poi_candidates"],
"remediation_hint": "Fix 1 violation(s) (nature_sunset). Affected: Mount Fuji"
}然后,代理只重新生成过时的工件并重新提交。
错误恢复
- 3-尝试预算 每个阶段--提交3次失败后,该阶段将被阻止
resolve_blocked工具——人类可以重试(重置尝试)、跳过(前进过去)或覆盖(按原样接受)- 最多2次回归 每次行程--防止无限的审查循环
cancel_trip--随时放弃旅行
MCP服务器参考
工具(18)
| 工具 | 说明 |
|---|---|
start_trip | 使用目的地、日期和可选的workspace_tag初始化行程 |
get_next_action | 获取阶段指令、输入工件、输出模式、先前错误 |
submit_artifact | 验证(JSON模式+规则引擎)并保存阶段的输出 |
search_pois | 通过codex exec发现+claude-p转换进行服务器端POI搜索 |
search_restaurants | 通过codex exec发现+claude-p转换进行服务器端餐厅搜索 |
search_hotels | 通过codex exec发现+claude-p转换进行服务器端酒店搜索 |
run_review | 服务器端阶段5:硬规则+软规则+可选的Codex审查 |
build_notion_manifest | 使用4个数据库配置+条目生成Notion清单 |
record_notion_urls | 跟踪每个数据库的发布进度(支持部分发布) |
complete_trip | 验证后将工作流标记为已完成 |
get_workflow_status | 只读状态检查(当前阶段、尝试、工件) |
update_profile | 添加深度合并到用户配置文件中 |
complete_profile_collection | 信号配置文件收集完成,服务器验证完整性 |
list_trips | 发现所有行程,可选择按workspace_id或workspace_tag筛选 |
cancel_trip | 放弃旅行 |
resolve_blocked | 人工辅助恢复:重试/跳过/覆盖 |
resume_trip | 按workspace_id恢复活动会话(交叉对话) |
resume_latest | 恢复最近活动的会话,或列出多个可供选择的会话 |
资源(7)
| URI | 描述 |
|---|---|
travel://config/guardrails | 调度约束规则(YAML) |
travel://config/property-mapping | 概念数据库属性模式 |
travel://trip/{id}/profile | 合并用户配置文件(基础+行程覆盖) |
travel://trip/{id}/artifact/{name} | 舞台工件: poi-candidates, itinerary, restaurants, hotels, review-report |
travel://trip/{id}/state | 工作流状态(当前阶段、尝试、错误) |
travel://trip/{id}/notion-manifest | 缓存的Notion发布清单 |
travel://config/contract/{name} | 每个阶段的JSON模式合约 |
提示(1)
| 提示 | 描述 |
|---|---|
plan_trip | 对代理的自主控制回路进行编程。拿 user_request 作为论据。 |
项目结构
SETUP.md Full setup guide (prerequisites, troubleshooting)
requirements-mcp.txt MCP server venv dependencies
requirements-mcp-dev.txt Dev/test dependencies
.mcp.json.example MCP server registration template (copy to .mcp.json)
tripdb/ SQLite data layer (schema, 11 CLI commands, seed scripts)
mcp_server/ MCP server (17 tools, 7 resources, 1 prompt)
server.py FastMCP entry point
workflow.py State machine (stage transitions, regression, recovery)
validation.py JSON Schema + rule engine validation
artifact_store.py Atomic artifact read/write
config.py Paths, constants, shared utilities
prompts.py plan_trip prompt template
rules/ Constraint engine
hard_rules.py 4 hard constraints (sunset, closing, overlap, travel time)
soft_rules.py 3 soft rules (pace, region cluster, meal coverage)
profile/ User profile CRUD with deep-merge semantics
review/ Codex CLI integration + report merging
output/ Notion manifest builder + property mapping
pipeline/ Shell-based pipeline runner (alternative to MCP)
config/ User profile (profile.yaml)
assets/
configs/ Guardrails YAML + JSON Schema contracts
prompts/ Stage-specific prompt templates
data/{trip_id}/ Generated trip artifacts快速开始
# 1. Create venv and install deps
python3.12 -m venv .venv-mcp
.venv-mcp/bin/pip install -r requirements-mcp.txt
# 2. Initialize the database
python3 -m tripdb.seed.import_all
# 3. Register the MCP server
claude mcp add -s project travel-planner -- "$(pwd)/.venv-mcp/bin/python3" -m mcp_server.server
# 4. Verify
.venv-mcp/bin/python3 -c "from mcp_server.server import mcp; print(f'OK: {len(mcp._tool_manager._tools)} tools')"有关完整的设置指南(先决条件、故障排除、两个Python目标说明),请参阅 设置.md.
用它
在Claude Code(或任何MCP客户端)中 travel-planner 服务器将可用:
5月10日至14日,计划一次为期5天的日本京都之旅。缓慢的步伐,寺庙和花园。
要在新对话中继续旅行:
继续我的京都之旅。
代理的步骤0恢复检查将调用 resume_latest() 然后从中断的地方继续。
护栏
硬约束(如果违反,则阻止管道):
| 规则 | 约束 |
|---|---|
nature_sunset | 自然POI必须在19:00之前结束 |
staffed_closing | 科技/文化/地标场馆必须在16:00前结束 |
time_overlap | 无重叠时段(亲子豁免) |
travel_time | POI之间的间隙必须适合旅行时间 |
软约束(生成警告):
| 规则 | 约束 |
|---|---|
daily_pace | 每天3-5个POI(来自个人资料) |
region_cluster | 每天最多3个不同区域 |
meal_coverage | 每天应该有午餐+晚餐窗口 |
测试
# Run full test suite (338 tests, ~1s)
.venv-mcp/bin/python3 -m pytest tests/ -v --tb=short
# Run MCP workflow E2E tests only
.venv-mcp/bin/python3 -m pytest tests/test_miami_e2e.py -v| 套件 | 测试内容 |
|---|---|
tests/test_miami_e2e.py | 完整的MCP工作流程E2E:从start_trip到complete_trip、桥接同步、会话隔离、工作区恢复 |
tests/test_pipeline_e2e.py | 规则引擎+带有SF夹具数据的清单生成器 |
tests/data/test_e2e.py | CLI生命周期(添加/安排/确认/重新安排/删除/导出) |
tests/data/test_bridge.py | MCP工件->SQLite桥同步(导入、去重、幂等性、工作区) |
tests/data/test_cli.py | CLI命令单元测试(所有11个命令) |
tests/data/test_schema.py | 数据库模式约束、视图、触发器 |
tests/test_rules.py | 带边缘案例的硬+软规则引擎 |
tests/test_profile*.py | 配置文件加载、验证、完整性、启发工作流程 |
双语输出
所有文物和Notion条目都包括英文和中文字段(name_en / name_cn).4个Notion数据库是:
- 行程 (按天分组的板视图)
- 餐馆 (表格视图)
- 酒店 (表格视图)
- 通知 (表视图--标记和拒绝审阅)
