全栈开发知识库

05 · 项目一:智能旅行助手从 0 到 1

对应官方仓库 code/chapter13/helloagents-trip-planner。输入"城市 + 日期 + 偏好",四个 Agent 协作调用高德地图,生成带地图、天气、酒店、预算的完整行程。本篇按里程碑推进,每个里程碑结束都有一个可验证的 checkpoint,不通过不要往下走。

0. 开工前核对

  • [ ] 第 02 篇的 LLM 三件套(LLM_MODEL_ID / LLM_API_KEY / LLM_BASE_URL)已验证可用
  • [ ] 高德Web 服务 Key 和 Web 端 JS API Key 都已到手
  • [ ] hello-agents 仓库已 clone
  • [ ] uvx --version 有输出(MCP 服务器靠它启动)

1. 项目全景

用户浏览器 (Vue, :5173)
    │  POST /api/trip/plan
    ▼
FastAPI 后端 (:8000)
    │
    ▼
MultiAgentTripPlanner ──── 顺序执行四步 ────────────────┐
    1️⃣ 景点搜索专家 ──[TOOL_CALL]──▶ 高德MCP maps_text_search
    2️⃣ 天气查询专家 ──[TOOL_CALL]──▶ 高德MCP maps_weather
    3️⃣ 酒店推荐专家 ──[TOOL_CALL]──▶ 高德MCP maps_text_search
    4️⃣ 行程规划专家 ──(无工具)──▶ 整合前三步结果,输出行程JSON
    └──────────────────────────────────────────────────┘
    │  解析JSON为 TripPlan
    ▼
前端 Result.vue 渲染:每日卡片 + 高德JS地图打点 + 预算表

后端目录(先混个脸熟,里程碑 3 逐个精读):

backend/
├── run.py                         # 启动入口
├── requirements.txt
├── .env.example                   # 环境变量模板
└── app/
    ├── config.py                  # 读取.env的配置类
    ├── api/main.py                # FastAPI应用 + CORS + 挂路由
    ├── api/routes/trip.py         # POST /api/trip/plan(主流程)
    ├── api/routes/map.py          # 地图相关接口
    ├── api/routes/poi.py          # POI搜索接口(POI=Point of Interest"兴趣点",地图术语,泛指景点/餐厅/酒店等地点)
    ├── agents/trip_planner_agent.py   # ⭐核心:四Agent协作系统
    ├── services/llm_service.py    # 构造HelloAgentsLLM
    ├── services/amap_service.py   # 高德HTTP API封装(MCP之外的直调)
    ├── services/unsplash_service.py   # 景点配图(可选)
    └── models/schemas.py          # ⭐所有Pydantic模型

2. 里程碑一:后端跑起来(约 1 小时)

cd hello-agents/code/chapter13/helloagents-trip-planner/backend

uv venv && source .venv/bin/activate        # Windows: .venv\Scripts\activate
uv pip install -r requirements.txt

cp .env.example .env

编辑 .env,至少填四项:

LLM_MODEL_ID=deepseek-chat
LLM_API_KEY=sk-你的key
LLM_BASE_URL=https://api.deepseek.com/v1
AMAP_API_KEY=你的高德Web服务Key

启动:

uvicorn app.api.main:app --reload --host 0.0.0.0 --port 8000

✅ Checkpoint 1:终端出现多智能体系统初始化成功的日志(能看到四个 Agent 各自的工具数);浏览器打开 http://localhost:8000/docs 能看到接口列表。

初始化卡在"创建共享 MCP 工具"?那是 uvx 第一次下载 amap-mcp-server,等一两分钟;一直失败则检查网络和 uv 安装。

3. 里程碑二:不碰前端,先用 /docs 调通主接口(约 1 小时)

打开 /docs → POST /api/trip/plan → Try it out,填入:

{
  "city": "北京",
  "start_date": "2026-09-01",
  "end_date": "2026-09-03",
  "travel_days": 3,
  "preferences": ["历史文化"],
  "transportation": "公共交通",
  "accommodation": "经济型"
}

(八个字段中 city、start_date、end_date、travel_days、transportation、accommodation 为必填,另有可选的 free_text_input 传额外要求;422 报错时对照 models/schemas.py 的 TripRequest 修改。)

点 Execute 后转到后端终端看直播:四个步骤依次打印——搜索景点 → 查询天气 → 搜索酒店 → 生成行程计划。全程 1~3 分钟,这是 LLM 多次调用的正常耗时。

✅ Checkpoint 2:响应体是 {"success": true, "message": ..., "data": {...}} 的包装结构,data 里是完整行程:days 数组里每天有 attractions、meals、hotel,外层还有 weather_info、budget 和 overall_suggestions。

常见失败:

  • 景点搜索为空 → AMAP_API_KEY 填成了 JS API 的 Key,换成 Web 服务 Key
  • 返回了兜底计划(内容明显是模板)→ 看终端 Traceback,多半是规划 Agent 输出的 JSON 解析失败,重试一次或换更强的模型

4. 里程碑三:精读后端代码(约 1~2 天)

推荐阅读顺序(每读一个文件,回答括号里的问题):

  1. models/schemas.py(整个系统流转的数据长什么样?TripPlan 里有哪些嵌套模型?)
  2. config.py(.env 里每个变量被谁读走了?)
  3. api/routes/trip.py(HTTP 请求进来后,到调用 planner 之间发生了什么?)
  4. agents/trip_planner_agent.py ⭐ 逐行读,重点: - 四段 system prompt:为什么每段都给 [TOOL_CALL:...] 的完整示例?(答:让模型照抄格式,提高工具调用成功率) - MCPTool 只创建一次、四个 Agent 共享(避免重复启动 MCP 子进程) - _build_planner_query:前三个 Agent 的输出如何拼进第四个的输入 - _parse_response:从 LLM 回复里抠 JSON + 失败兜底 _create_fallback_plan
  5. services/amap_service.py(哪些高德能力走 MCP、哪些走直接 HTTP?为什么两条路都要?)

✅ Checkpoint 3:合上代码,你能在纸上画出"一次请求从进入到返回"经过的每个文件。

5. 里程碑四:前端跑起来(约半天)

cd ../frontend
npm install
cp .env.example .env

编辑前端 .env,三个变量(注意两个高德 Key 都要填,且和后端那个是三个不同的 Key):

# 后端API地址(本机开发保持默认)
VITE_API_BASE_URL=http://localhost:8000

# 高德地图 Web API Key(与后端 AMAP_API_KEY 相同的那种"Web服务"Key)
VITE_AMAP_WEB_KEY=你的高德Web服务Key

# 高德地图 Web端 JS API Key(地图显示用)
VITE_AMAP_WEB_JS_KEY=你的高德JS API Key

启动(保持后端也在运行,两个终端):

npm run dev

✅ Checkpoint 4:打开 http://localhost:5173,填表单生成计划,等待后跳转结果页:行程卡片、地图打点、天气、预算全部显示。

  • 地图空白 → VITE_AMAP_WEB_JS_KEY 填错或和 Web 服务 Key 填反了(浏览器 F12 控制台会有高德的具体报错);改完 .env 要重启 npm run dev 才生效
  • 请求发不出去/CORS 报错 → 后端 .env 的 CORS_ORIGINS 要包含 http://localhost:5173

6. 里程碑五:动手改造(检验真懂了没有)

按难度递增,至少完成前两个:

  1. 改提示词:让行程规划专家在每天行程里增加一条"拍照打卡建议"。(改 PLANNER_AGENT_PROMPT 的 JSON 模板 + schemas.py 对应模型 + 前端展示,三处联动——体会"改一个字段要动几个文件")
  2. 加接口:后端加 GET /api/trip/tips?city=xxx,用一个新的 SimpleAgent 返回该城市的 3 条旅行贴士。
  3. 加 Agent:插入第五个"美食搜索专家"(prompt 仿照酒店专家,keywords 用"美食"),把结果也拼给规划专家。
  4. 提速:并发化前三步:景点/天气/酒店三个 Agent 互不依赖,却在 plan_trip 里串行执行。用 concurrent.futures.ThreadPoolExecutor 让它们并行跑,总耗时约缩短一半。(规划专家必须等三者都完成,仍在最后)
  5. 换 MCP:把 server_command 换成其他 MCP 服务器(如天气类),观察 auto_expand 展开出的新工具名。

7. 本项目带走的能力

  • 多 Agent 顺序流水线的完整实现套路(共享工具、prompt 分工、结果拼接)
  • MCP 工具从配置到调用的全链路
  • "LLM 输出 JSON → Pydantic 模型 → 前端渲染"的数据管道,以及每一环的容错

下一篇:06 · 项目二:深度研究智能体从 0 到 1

本页由 Markdown 自动渲染 · 共 628 篇笔记