|
@@ -0,0 +1,212 @@
|
|
|
|
|
+# TravelMind — 多角色智能旅行规划系统
|
|
|
|
|
+
|
|
|
|
|
+TravelMind 是一个基于 **LangGraph 多角色 Agent 工作流** 的智能行程规划系统:用户用自然语言描述旅行需求(出发地、目的地、日期、预算、偏好等),系统自动完成需求解析、航班/酒店资源查询、目的地地图研究、行程编排、风险评审与迭代优化,最终输出结构化多日行程。
|
|
|
|
|
+
|
|
|
|
|
+> 项目名中的 "Mind" 取自 *multi-agent mind*:多个各司其职的 Agent 以 Supervisor 模式协同工作,像一支"思维团队"一样规划行程。
|
|
|
|
|
+
|
|
|
|
|
+## ✨ 核心特性
|
|
|
|
|
+
|
|
|
|
|
+- **自然语言直接规划**:输入"帮我规划 6 月下旬从北京去东京玩 5 天,预算 1.5 万以内",即可获得完整行程方案
|
|
|
|
|
+- **多角色 Agent 协作**:需求解析、资源查询、地图研究、行程规划、行程评审 5 个 Agent 分工协作
|
|
|
|
|
+- **Supervisor 迭代评审**:规划结果经过确定性校验与独立评审,不合格自动重新规划(带重试上限,避免死循环)
|
|
|
|
|
+- **真实数据查询**:航班/酒店走 **SerpApi Google Flights/Hotels**,景点/餐饮/天气走 **高德地图官方 MCP**
|
|
|
|
|
+- **MCP 标准化接入**:自建航班/酒店搜索 MCP 服务器(FastMCP),与外部高德 MCP 统一接入
|
|
|
|
|
+- **防编造设计**:候选筛选、路线评估、计划校验等环节使用**确定性代码**而非 LLM,保证 ID、日期、价格等信息的真实性,防止模型编造航班、酒店、景点和价格
|
|
|
|
|
+- **模型无关**:兼容 OpenAI 及其兼容服务(DeepSeek、通义千问等),仅需配置 `MODEL_BASE_URL`
|
|
|
|
|
+
|
|
|
|
|
+## 🏗️ 架构总览
|
|
|
|
|
+
|
|
|
|
|
+系统采用 **LangGraph 状态图** 编排完整工作流,Supervisor 在关键节点做路由决策:
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+用户需求
|
|
|
|
|
+ │
|
|
|
|
|
+ ▼
|
|
|
|
|
+┌──────────────┐ 澄清/报错(条件路由) ┌──────────────────┐
|
|
|
|
|
+│ 需求解析Agent │ ─────────────────────► │ 补充需求/终止 │
|
|
|
|
|
+└──────┬───────┘ └──────────────────┘
|
|
|
|
|
+ │ TravelRequest(结构化)
|
|
|
|
|
+ ▼
|
|
|
|
|
+┌──────────────┐ 高德 MCP 工具 ┌──────────────────┐
|
|
|
|
|
+│ 资源查询Agent │ ─────────────────────► │ 地图研究Agent │
|
|
|
|
|
+│ 航班/酒店 │ │ 景点/餐饮/天气 │
|
|
|
|
|
+└──────┬───────┘ └────────┬─────────┘
|
|
|
|
|
+ │ 候选资源 │ POI 数据
|
|
|
|
|
+ ▼ ▼
|
|
|
|
|
+┌──────────────────────────────────────────────────────────────┐
|
|
|
|
|
+│ 候选筛选 → 路线评估 → 行程规划Agent │
|
|
|
|
|
+│ (生成结构化多日行程) │
|
|
|
|
|
+└──────────────────────┬───────────────────────────────────────┘
|
|
|
|
|
+ │
|
|
|
|
|
+ ▼
|
|
|
|
|
+ ┌──────────────────┐ 未通过(重新规划循环) ┌──────────────┐
|
|
|
|
|
+ │ 校验 → 评审Agent │ ◄────────────────────── │ Supervisor │
|
|
|
|
|
+ └──────┬───────────┘ │ (路由决策) │
|
|
|
|
|
+ │ 通过 └──────────────┘
|
|
|
|
|
+ ▼
|
|
|
|
|
+ ┌──────────────────┐
|
|
|
|
|
+ │ 最终定稿/输出 │
|
|
|
|
|
+ └──────────────────┘
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+工作流环节:**需求解析 → 资源查询 → 候选筛选 → 地图研究 → 路线评估 → 行程规划 → 校验 → 评审 → 最终定稿**,其中规划/评审环节存在带重试上限的迭代循环(`recursion_limit = 80`)。
|
|
|
|
|
+
|
|
|
|
|
+### 角色分工
|
|
|
|
|
+
|
|
|
|
|
+| Agent | 职责 |
|
|
|
|
|
+|-------|------|
|
|
|
|
|
+| **RequirementAgent** 需求解析 | 把自然语言转换为结构化 `TravelRequest`,意图识别与字段提取(仅解析,不规划);缺字段时走澄清流程 |
|
|
|
|
|
+| **ResourceSearchAgent** 资源查询 | 调用航班/酒店 MCP 工具搜索外部资源,指导工具调用顺序并汇总为结构化结果 |
|
|
|
|
|
+| **MapResearchAgent** 地图研究 | 调用高德地图 MCP 工具,搜索目的地周边景点、餐饮与天气,返回结构化 POI 数据 |
|
|
|
|
|
+| **ItineraryPlannerAgent** 行程规划 | 基于候选资源与地图研究结果,生成包含每日活动安排的结构化多日行程 |
|
|
|
|
|
+| **TripReviewerAgent** 行程评审 | 从风险控制角度独立评审,识别节奏、地理、预算等维度的问题并给出修改意见 |
|
|
|
|
|
+| **Supervisor** 监督协调 | 汇总校验与评审意见,决定 `replan` / `finalize` / `finalize_with_risks` / `terminate` |
|
|
|
|
|
+
|
|
|
|
|
+### 确定性模块(不使用 LLM)
|
|
|
|
|
+
|
|
|
|
|
+以下环节刻意使用确定性代码,保证准确性与成本控制:
|
|
|
|
|
+
|
|
|
|
|
+| 模块 | 原因 |
|
|
|
|
|
+|------|------|
|
|
|
|
|
+| Candidate Selector | 排序和过滤规则确定 |
|
|
|
|
|
+| Route Evaluator | 距离和评分可确定性计算 |
|
|
|
|
|
+| Plan Validator | ID、日期、预算必须准确 |
|
|
|
|
|
+| Finalizer | 防止最终展示阶段重新编造信息 |
|
|
|
|
|
+
|
|
|
|
|
+LLM 只负责自然语言理解、复杂取舍、行程编排和体验审查。
|
|
|
|
|
+
|
|
|
|
|
+### MCP 集成
|
|
|
|
|
+
|
|
|
|
|
+通过 `langchain-mcp-adapters` 的 `MultiServerMCPClient` 同时接入两个 MCP 服务器:
|
|
|
|
|
+
|
|
|
|
|
+1. **travel_search(自建)**:stdio 传输,`mcp_servers/travel_search_server.py`(FastMCP)包装 `TravelSearchService`,提供 `search_airports`、`search_flights`、`search_return_flights`、`search_hotels` 工具,底层调用 SerpApi
|
|
|
|
|
+2. **amap(高德官方)**:Streamable HTTP 传输,`https://mcp.amap.com/mcp`,提供 `maps_*` 系列工具(POI 搜索、餐饮、天气、距离测量、路线规划等)
|
|
|
|
|
+
|
|
|
|
|
+## 🛠️ 技术栈
|
|
|
|
|
+
|
|
|
|
|
+- **Python ≥ 3.10**,[uv](https://docs.astral.sh/uv/) 包管理
|
|
|
|
|
+- **LangChain 1.x / LangGraph**:Agent 与状态图编排
|
|
|
|
|
+- **langchain-openai**:统一模型接入(OpenAI / DeepSeek / Qwen 等)
|
|
|
|
|
+- **langchain-mcp-adapters + mcp**:MCP 客户端与自建 MCP 服务器(FastMCP)
|
|
|
|
|
+- **httpx**:SerpApi HTTP 调用(支持 SOCKS 代理)
|
|
|
|
|
+- **pydantic / pydantic-settings**:数据模型与配置管理
|
|
|
|
|
+- **rich**:终端输出美化
|
|
|
|
|
+- **pytest**:单元测试
|
|
|
|
|
+
|
|
|
|
|
+## 🚀 快速开始
|
|
|
|
|
+
|
|
|
|
|
+### 1. 环境准备
|
|
|
|
|
+
|
|
|
|
|
+需要 [uv](https://docs.astral.sh/uv/) 包管理器(或使用任意虚拟环境工具):
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+# 进入项目目录并安装依赖(自动创建 .venv)
|
|
|
|
|
+uv sync
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 2. 配置环境变量
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+cp .env.example .env
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+编辑 `.env`,填写以下必填项(`app/config.py` 会从项目根目录 `.env` 读取,缺配置时会给出明确错误):
|
|
|
|
|
+
|
|
|
|
|
+| 变量 | 说明 | 必填 |
|
|
|
|
|
+|------|------|------|
|
|
|
|
|
+| `MODEL_API_KEY` | OpenAI 或兼容服务的 API Key | ✅ |
|
|
|
|
|
+| `MODEL_NAME` | 模型名,如 `gpt-4.1-mini`、`qwen-plus`、`deepseek-chat` | ✅ |
|
|
|
|
|
+| `MODEL_BASE_URL` | OpenAI 官方接口可留空;兼容接口填对应 Base URL | 视服务 |
|
|
|
|
|
+| `SERPAPI_API_KEY` | SerpApi 密钥(Google Flights/Hotels 搜索) | ✅ |
|
|
|
|
|
+| `AMAP_API_KEY` | 高德开放平台密钥(MCP 地图服务) | ✅ |
|
|
|
|
|
+| `REQUEST_TIMEOUT_SECONDS` | 请求超时(秒),默认 `120` | 否 |
|
|
|
|
|
+
|
|
|
|
|
+> ⚠️ `.env` 包含敏感密钥,已被 `.gitignore` 排除,**切勿提交到版本库**。密钥缺失时,`Settings.require()` 会抛出带具体变量名的错误。
|
|
|
|
|
+
|
|
|
|
|
+### 3. 运行
|
|
|
|
|
+
|
|
|
|
|
+支持两种输入方式:
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+# 方式一:命令行参数直接传入
|
|
|
|
|
+uv run python main.py 帮我规划6月下旬从北京去东京玩5天,预算1.5万以内
|
|
|
|
|
+
|
|
|
|
|
+# 方式二:交互式输入(支持多行,输入空行结束)
|
|
|
|
|
+uv run python main.py
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+运行结束后会输出最终行程方案与执行状态(trace_id、各环节执行次数、Supervisor 决策、总耗时等)。
|
|
|
|
|
+
|
|
|
|
|
+## 🧪 测试
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+# 运行全部单元测试
|
|
|
|
|
+uv run pytest
|
|
|
|
|
+
|
|
|
|
|
+# 或使用自动化回归入口(只跑本地单元测试)
|
|
|
|
|
+uv run python -m scripts.run_regression
|
|
|
|
|
+
|
|
|
|
|
+# 真实接口集成测试(会调用真实模型、SerpApi 和高德 MCP,可能产生费用)
|
|
|
|
|
+uv run python -m scripts.run_regression --integration
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+## 📁 项目结构
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+travel-mind/
|
|
|
|
|
+├── main.py # CLI 入口:读取需求并执行完整工作流
|
|
|
|
|
+├── pyproject.toml # 项目配置与依赖(uv)
|
|
|
|
|
+├── .env.example # 环境变量模板(.env 不入库)
|
|
|
|
|
+├── app/
|
|
|
|
|
+│ ├── config.py # pydantic-settings 配置中心(读取 .env)
|
|
|
|
|
+│ ├── llm.py # 大模型工厂(兼容 OpenAI/DeepSeek/Qwen)
|
|
|
|
|
+│ ├── mcp_client.py # MCP 工具加载器(自建 + 高德双服务器)
|
|
|
|
|
+│ ├── agents/ # 五个角色 Agent
|
|
|
|
|
+│ │ ├── requirement_agent.py # 需求解析
|
|
|
|
|
+│ │ ├── resource_agent.py # 资源查询
|
|
|
|
|
+│ │ ├── map_agent.py # 地图研究
|
|
|
|
|
+│ │ ├── itinerary_agent.py # 行程规划
|
|
|
|
|
+│ │ └── reviewer_agent.py # 行程评审
|
|
|
|
|
+│ ├── graph/ # LangGraph 工作流(builder + nodes + state)
|
|
|
|
|
+│ │ ├── planner_builder.py # 完整主图编排
|
|
|
|
|
+│ │ ├── supervisor_nodes.py # 监督协调与路由
|
|
|
|
|
+│ │ └── ... # 各环节节点
|
|
|
|
|
+│ ├── schemas/ # Pydantic 数据模型(航班/酒店/行程/路线…)
|
|
|
|
|
+│ ├── services/ # 业务服务(搜索/筛选/评估/校验/定稿)
|
|
|
|
|
+│ ├── clients/
|
|
|
|
|
+│ │ └── serpapi_client.py # SerpApi HTTP 客户端
|
|
|
|
|
+│ └── logging_config.py # 日志与 trace_id
|
|
|
|
|
+├── mcp_servers/
|
|
|
|
|
+│ └── travel_search_server.py # 自建旅行搜索 MCP 服务器(FastMCP)
|
|
|
|
|
+├── scripts/ # 各环节调试脚本 + 回归测试入口
|
|
|
|
|
+└── tests/ # pytest 单元测试
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+## 📌 当前限制
|
|
|
|
|
+
|
|
|
|
|
+该项目是生产架构导向的可运行 MVP,而不是已上线商业系统:
|
|
|
|
|
+
|
|
|
|
|
+- 航班和酒店数据用于查询与规划,不执行真实预订
|
|
|
|
|
+- 航班接口报价的计价范围需以供应商页面为准
|
|
|
|
|
+- 部分未来日期无法查询准确天气
|
|
|
|
|
+- 未完整覆盖门票、餐饮和市内交通价格
|
|
|
|
|
+- 没有数据库和长期会话持久化
|
|
|
|
|
+- 没有针对大规模并发进行压力测试
|
|
|
|
|
+- MCP 和第三方 API 失效时的降级能力仍可增强
|
|
|
|
|
+
|
|
|
|
|
+## 🔭 生产化方向
|
|
|
|
|
+
|
|
|
|
|
+- FastAPI 服务接口
|
|
|
|
|
+- Redis 缓存与限流
|
|
|
|
|
+- LangGraph Checkpointer 持久化
|
|
|
|
|
+- 用户会话管理
|
|
|
|
|
+- MCP 超时、熔断和降级
|
|
|
|
|
+- OpenTelemetry 链路追踪
|
|
|
|
|
+- Agent 调用成本统计
|
|
|
|
|
+- Prompt 和工作流评测集
|
|
|
|
|
+- Docker 与 CI/CD
|
|
|
|
|
+- 多供应商数据源切换
|
|
|
|
|
+
|
|
|
|
|
+## 📄 许可
|
|
|
|
|
+
|
|
|
|
|
+个人学习/作业项目,未指定开源许可证。
|