融合大模型、RAG、本地攻略与高德地图能力的智能旅行规划系统
Trip Planner 是一个面向中文旅行场景的 AI 旅行规划项目。用户输入目的地、日期、预算、人数和偏好后,系统可以走两条链路:快速生成可编辑的结构化 itinerary,或进入深度规划模式,由 Destination Intelligence Agent 联网检索、反思补查并生成带来源的 Markdown 攻略。
相比只输出一段文本的 LLM Demo,这个项目更强调“研究、规划、追问、修改”的完整闭环:深度规划负责把旅行前的信息收集和判断过程沉淀成报告,浮动聊天机器人负责在结果页继续问答、联网检索和自然语言改行程。地图、天气、预算、历史与导出能力围绕这两个核心流程提供支撑。
展示素材统一维护在 assets/showcase/,覆盖规划表单、行程结果、深度规划研究过程、历史行程和浮动聊天助手等核心界面。
| 规划页 | 行程生成结果 |
|---|---|
![]() |
![]() |
| 深度规划研究过程 | 历史行程 |
|---|---|
![]() |
![]() |
| 浮动聊天助手 |
|---|
![]() |
-
演示视频:
聊天机器人运行.mp4/ Bilibili 在线演示 -
深度规划报告样例:
厦门、汕头 15天14晚旅行攻略
2026-07-03- 聊天记忆系统:浮动旅行助手接入长期记忆框架,支持
session_id作用域、memory_opt_out、显式记住/查询/删除/清空/统计/关闭长期记忆等管理命令。 - 记忆存储:新增
chatbot_memory_itemsSQLite 表作为权威元数据层,按 semantic / episodic / perceptual 分类保存偏好、行程事件与实时查询观察;Chroma 语义索引可通过CHATBOT_MEMORY_USE_CHROMA=true开启,默认降级为关键词与元数据排序。 - 聊天链路:
MemoryManager在ChatbotIntentRouter前完成记忆操作检测和上下文检索,并把memory_context显式注入 Ask / Search / Research / Update 节点;前端聊天 payload 会携带匿名会话 ID 和记忆关闭开关。 - 实时查询:浮动助手补充 SSE 流式响应、位置建议、目的地跨度检查和可选 12306 MCP 实时铁路余票查询。
- 聊天记忆系统:浮动旅行助手接入长期记忆框架,支持
2026-06-25- 深度规划模式:规划页支持「快速规划」与「深度规划」两条链路,深度规划会创建后台任务并生成带研究来源的 Markdown 攻略。
- 报告转行程:深度攻略和历史 Markdown Report 可转换为结果页使用的结构化 itinerary,继续复用地图、天气、预算、编辑和导出能力。
- 浮动旅行助手:结果页接入 ChatUI 对话框,支持问答、联网检索和基于自然语言的当前行程修改。
- 联网搜索配置:深度规划支持 Tavily / SearXNG 优先级选择,失败后自动兜底另一搜索服务。
- 工程启动:后端依赖改为
uv工作流,使用uv sync安装依赖、uv run uvicorn ...启动服务。
2026-06-15- 地图服务:增强高德 POI 数据解析,补充评分、参考消费、标签、电话、距离等字段,并支持基于景点坐标推荐附近餐饮与住宿。
- 行程生成:从 RAG 攻略片段提取门票参考,生成景点预算时优先使用本地攻略价格,并过滤跨目的地提示污染。
- 工程质量:补充地图服务、行程服务与 RAG 检索测试,前后端类型模型同步扩展地图字段。
2026-04-29- RAG:扩充知识库至 5 个目的地(大理/成都/西安/厦门/三亚),评估样例集扩充至 15 条,完成规则级 Rerank 多层降权与 Query Rewrite 目的地过滤,消除跨目的地污染。
- 地图前端:新增地图路线虚线箭头可视化与打卡标记。
2026-04-25:完成第一轮 RAG 在线阶段优化,已接入轻量化 Query Rewrite、轻量 Rerank 与检索调试脚本。2026-04-15:新增 Redis 缓存层,已覆盖天气查询、地图查询与 RAG 检索结果缓存。
更多更新见:CHANGELOG.md
- 🔎 深度规划模式:通过 Destination Intelligence Agent 联网检索官方旅行、交通、景点、住宿、餐饮与动态公告,经过分章节总结、反思补查和来源整理,生成可追溯的 Markdown 深度攻略
- 🧭 研究式规划过程:深度规划不是单次问答,而是后台任务式工作流;服务层会持久化任务状态、研究 query、最终报告与来源列表,前端可在历史页和深度报告页继续查看
- 🧩 报告转结构化行程:支持把深度规划报告或历史 Markdown Report 转换为结果页 itinerary,继续复用地图、天气、预算、保存、编辑和导出链路
- 💬 浮动旅行助手:结果页内置 ChatUI 对话助手,可识别问答、联网搜索、风险核查、比较建议和行程修改意图,并把修改结果回写到当前 itinerary;普通接口和 SSE 流式接口共用同一套 Agent 图
- 🧠 可治理记忆系统:聊天机器人会维护短期
history/conversation_summary、前端 traveler profile 和后端长期记忆;长期记忆按 session / trip 作用域保存,并支持显式记住、检索、删除、清空、统计和关闭保存 - 🗃️ SQLite + 可选 Chroma 记忆检索:
chatbot_memory_items保存 semantic / episodic / perceptual 记忆及生命周期元数据,Chroma 语义索引可选开启;不可用时自动回退到关键词、目的地、行程 ID、重要性和时间排序 - 🌐 联网检索型回答:聊天助手复用 Tavily / SearXNG 搜索能力,适合处理营业时间、交通变化、预约提醒、天气风险等动态旅行问题
- 🚄 实时交通查询预留:支持通过可选 12306 MCP 查询铁路余票,并把实时结果作为带过期语义的感知记忆候选
- 🧠 LLM 结构化行程生成:基于 LangGraph + LangChain + DashScope 调用
qwen-max生成结构化旅行计划,并支持单日自然语言编辑 - 📚 RAG 攻略增强:使用本地 Markdown 攻略 + Chroma 向量检索,为快速规划和编辑补充目的地上下文
- 🧭 RAG 在线优化:规则级 Query Rewrite(含目的地过滤)+ 多层 Rerank 降权(行程/简介/目的地不匹配),消除跨目的地污染
- 🗺️ 高德地图接入:补充景点、餐饮、住宿的地址、经纬度、POI ID、评分、参考消费、标签、电话和距离,并支持附近餐饮住宿推荐、路线估算、虚线箭头路线可视化与打卡标记
- 🍽️ 本地生活推荐扩展:餐饮与住宿推荐模型预留美团/大众点评等第三方来源字段,可在高德推荐基础上叠加榜单、评价数、来源链接与推荐理由
- 🌦️ 天气感知提示:前端展示天气预报,并根据雨天/阴天自动修正旅行提示
- ⚡ Redis 缓存层:覆盖天气、地图与 RAG 检索缓存,减少重复外部调用开销
- 💰 预算拆分:按交通、住宿、餐饮、门票、其他费用拆分,并优先使用本地攻略中的门票参考价格
- 🪄 智能编辑:支持用户用自然语言调整某一天行程
- 🗂️ 历史管理:支持保存、查看、打开、删除历史 itinerary
- 📄 文档导出:支持当前草稿或已保存行程导出 Markdown 与中文 PDF
- 🖥️ 前端可视化:提供规划页、结果页、深度规划报告页和历史页,完成核心业务闭环展示
- 后端:FastAPI + Pydantic + SQLAlchemy + uv
- LLM:LangChain + DashScope (
qwen-max) - 向量库:ChromaDB
- 缓存:Redis
- 外部服务:HTTPX + 高德地图 Web 服务 + 高德 JavaScript API + Tavily / SearXNG + 可选 12306 MCP
- 前端:Vue 3 + Vite + Ant Design Vue + ChatUI + React 组件桥接
- 数据库:SQLite
| 层级 | 关键文件 | 职责 |
|---|---|---|
| 前端页面 | frontend/src/views/*.vue |
Landing、规划页、结果页、深度规划页、历史页展示与交互 |
| 前端组件 | frontend/src/components/ |
高德地图、浮动聊天助手、聊天悬浮球与 React 版聊天体验 |
| 前端接口 | frontend/src/services/api.ts |
Axios / fetch 封装,覆盖普通请求、SSE 流式聊天、天气、位置建议与导出 |
| API 路由 | backend/app/api/routes/ |
trip、chatbot、export、weather、location 路由 |
| 服务层 | backend/app/services/ |
行程编排、深度规划任务、报告目录、报告转 itinerary、地图 enrich、位置建议、铁路查询、天气、联网搜索、缓存、导出、存储 |
| Agent 层 | backend/app/agents/ |
快速行程生成、浮动聊天助手、Destination Intelligence 深度攻略、Report 转 itinerary |
| Chatbot 记忆层 | backend/app/agents/chatbot_agent/memory/ |
记忆操作检测、分类、检索、排序、SQLite/Chroma 存储、过期归档与管理命令 |
| RAG 层 | backend/app/rag/ |
本地攻略向量入库、检索、缓存与轻量 Rerank |
| 集成层 | backend/app/integrations/ |
Tavily / SearXNG 聚合搜索、12306 MCP 客户端;本地 12306 MCP 服务(backend/servers/mcp_12306/)随后端自动启动/停止 |
| 数据层 | backend/data/、backend/db/ |
本地 Markdown 攻略、SQLite 业务数据、Chroma 向量库 |
flowchart TD
Client[前端客户端]
subgraph Frontend[Frontend]
FrontApp[Vue 页面]
ChatUI[FloatingChatbotReact]
FrontApi[api.ts]
end
subgraph Backend[Backend]
MainApp[main.py]
subgraph Routes[Routes]
TripRoute[trip.py]
ChatbotRoute[chatbot.py]
ExportRoute[export.py]
WeatherRoute[weather.py]
LocationRoute[location.py]
end
subgraph Services[Services]
TripService[trip_service.py]
DeepService[deep_planning_service.py]
ReportService[report_itinerary_service.py]
StorageService[storage_service.py]
MapService[map_service.py]
LocationService[location_service.py]
TransportService[transport_query_service.py]
WebSearchService[web_search_service.py]
WeatherService[weather_service.py]
ExportService[export_service.py]
end
subgraph Agent[Agent]
PlannerAgent[trip_planner_agent]
ChatbotAgent[chatbot_agent]
DestinationAgent[destination_intelligence_agent]
ReportAgent[report_itinerary_agent]
RagTool[rag_tool.py]
end
subgraph ChatbotMemory[Chatbot Memory]
MemoryManager[memory/manager.py]
MemoryStore[memory/stores.py]
MemoryRetriever[memory/retriever.py]
MemoryDB[(chatbot_memory_items)]
MemoryVector[(chatbot_memories)]
end
subgraph RAG[RAG]
Retriever[retriever.py]
VectorDB[vector_db.py]
ChromaDB[(db/chroma_db)]
GuideData[(data/*.md)]
end
subgraph Models[Models]
Schemas[schemas.py]
DBModels[db_models.py]
end
SQLite[(db/app.db)]
end
Client --> FrontApp
FrontApp --> ChatUI
FrontApp --> FrontApi
ChatUI --> FrontApi
FrontApi --> MainApp
MainApp --> TripRoute
MainApp --> ChatbotRoute
MainApp --> ExportRoute
MainApp --> WeatherRoute
MainApp --> LocationRoute
TripRoute --> Schemas
TripRoute --> TripService
TripRoute --> DeepService
TripRoute --> ReportService
ChatbotRoute --> ChatbotAgent
WeatherRoute --> WeatherService
ExportRoute --> ExportService
LocationRoute --> LocationService
TripService --> PlannerAgent
TripService --> MapService
TripService --> TransportService
TripService --> StorageService
TripService --> Schemas
PlannerAgent --> RagTool
DeepService --> DestinationAgent
ReportService --> ReportAgent
ChatbotAgent --> TripService
ChatbotAgent --> WebSearchService
ChatbotAgent --> TransportService
ChatbotAgent --> MemoryManager
MemoryManager --> MemoryRetriever
MemoryManager --> MemoryStore
MemoryRetriever --> MemoryStore
MemoryStore --> MemoryDB
MemoryStore -. optional .-> MemoryVector
RagTool --> Retriever --> VectorDB --> ChromaDB
GuideData --> VectorDB
StorageService --> DBModels --> SQLite
MemoryDB --> SQLite
Schemas --> TripRoute
WeatherService --> WeatherRoute
ExportService --> ExportRoute
LocationService --> LocationRoute
TripRoute --> FrontApi
ChatbotRoute --> FrontApi
WeatherRoute --> FrontApi
ExportRoute --> FrontApi
LocationRoute --> FrontApi
快速规划数据流:前端收集用户输入 → 后端调用 LLM + RAG 生成结构化行程 → 地图服务补充地址、坐标和路线 → 前端展示地图、天气、预算和每日行程 → 用户可保存、编辑、查看历史并导出文档。
深度规划数据流:前端提交深度规划任务 → 后台 Destination Intelligence Agent 制定搜索计划、联网检索、分章节总结和反思补查 → 生成带来源的 Markdown 深度攻略 → 历史页展示任务状态与研究来源 → 用户可查看深度报告,也可把报告转换为结构化 itinerary 并进入结果页继续追问、编辑和导出。
聊天助手数据流:结果页把当前 itinerary、聊天历史、traveler profile、session_id 和 memory_opt_out 发送到 /chatbot/message 或 /chatbot/message/stream → Chatbot Agent 先解析记忆操作并检索相关记忆 → 再分类旅行意图 → 进入 Ask、Search、Research 或 Update 分支 → 返回回答、来源、调研步骤或更新后的 itinerary → 前端同步刷新当前行程、profile 和 conversation summary。
记忆系统的详细设计见 docs/chatbot_memory_system_design.md。README 中保留总体架构和当前落地边界。
当前系统同时维护三类上下文:
- Working Memory:前端维护最近
history、conversation_summary和当前 itinerary 摘要,用于本轮和短期追问。 - Semantic Memory:保存可复用偏好和事实,例如不早起、少走路、预算敏感、喜欢博物馆和咖啡。
- Episodic / Perceptual Memory:保存行程编辑事件、已确认决策,以及天气、开放时间、铁路余票、搜索摘要等带时效性的观察。
flowchart TD
Request[ChatbotMessageRequest<br/>message + session_id + trip_id + profile] --> Scope[MemoryManager.resolve_scope]
Scope --> Operation[MemoryOperationDetector<br/>add / retrieve / manage / passive]
Operation -->|manage| Manage[MemoryManager.manage<br/>list / delete / clear / opt_out / stats]
Manage --> DirectReply[直接返回管理结果]
Operation -->|add/passive/retrieve| Prepare[MemoryManager.prepare_context]
Prepare --> Retrieve[MemoryRetriever.retrieve]
Retrieve --> SQLite[(SQLite<br/>chatbot_memory_items)]
Retrieve -. CHATBOT_MEMORY_USE_CHROMA=true .-> Chroma[(Chroma<br/>chatbot_memories)]
Retrieve --> Rank[ranker<br/>关键词 + 作用域 + 重要性 + 时间 + 可选向量]
Rank --> MemoryContext[memory_context<br/>Top-K + profile patch + working notes]
MemoryContext --> Router[ChatbotIntentRouter]
Router --> Graph[LangGraph<br/>Ask / Search / Research / Update]
Graph --> Response[ChatbotMessageResponse]
Response --> WriteBack[add_interaction<br/>抽取 profile / update / search 候选记忆]
WriteBack --> SQLite
WriteBack -. optional index .-> Chroma
关键约束:
session_id由前端 localStorage 生成并随聊天请求发送;没有 session 时只允许写入trip:{trip_id}范围的行程级记忆。memory_opt_out=true或用户发出关闭长期记忆命令时,不再写入长期记忆;聊天仍可使用本轮 Working Memory 正常工作。- SQLite 是记忆生命周期、权限和删除状态的权威来源;Chroma 只做可选语义召回,默认关闭,开启失败时自动降级。
memory_context是后端内部上下文,不直接暴露给前端,但会显式传给 Router 和各节点,避免检索到的记忆停留在 graph state 里却没有被 prompt 消费。
Trip_Planner/
├── backend/
│ ├── app/
│ │ ├── config.py # 环境变量、数据库 Base、全局配置
│ │ ├── agents/
│ │ │ ├── trip_planner_agent/ # 快速结构化行程生成与单日编辑
│ │ │ ├── chatbot_agent/ # 浮动聊天助手:路由、问答、搜索、研究、行程修改、长期记忆
│ │ │ │ ├── memory/ # 记忆检测、分类、检索、排序、存储与维护
│ │ │ │ ├── nodes/ # Ask / Search / Research / Update 等节点
│ │ │ │ ├── routing/ # 静态路由、语义路由与 LLM 决策路由
│ │ │ │ └── prompts/ # 聊天、搜索、研究、编辑与实时查询 prompt
│ │ │ ├── destination_intelligence_agent/ # 深度目的地攻略生成
│ │ │ ├── report_itinerary_agent/ # Markdown Report 转结构化 itinerary
│ │ │ └── tools/ # RAG Query Rewrite 等工具
│ │ ├── api/
│ │ │ ├── main.py # FastAPI 应用入口
│ │ │ └── routes/
│ │ │ ├── trip.py # 生成、编辑、保存、查询、删除接口
│ │ │ ├── chatbot.py # 浮动聊天助手普通接口与 SSE 流式接口
│ │ │ ├── export.py # Markdown / PDF 导出接口
│ │ │ ├── location.py # 位置建议与目的地跨度检查接口
│ │ │ └── weather.py # 天气预报接口
│ │ ├── models/
│ │ │ ├── schemas.py # Pydantic 请求体 / 响应体 / itinerary / chatbot 模型
│ │ │ └── db_models.py # TripRecord 与 ChatbotMemoryItem 表定义
│ │ ├── rag/
│ │ │ ├── vector_db.py # Markdown 切片、Chroma 入库与检索
│ │ │ └── retriever.py # 检索封装、RAG 缓存与轻量 Rerank
│ │ ├── integrations/
│ │ │ ├── web_search.py # Tavily / SearXNG 兜底搜索聚合
│ │ │ ├── mcp_12306.py # 可选 12306 MCP 客户端
│ │ │ └── mcp_12306_process.py # 本地 12306 MCP Node 子进程启动/停止(随后端 lifespan)
│ │ └── services/
│ │ ├── trip_service.py # 行程主编排逻辑、预算计算、地图 enrich
│ │ ├── deep_planning_service.py # 深度规划后台任务
│ │ ├── report_catalog_service.py # 深度报告与历史 Report 目录管理
│ │ ├── report_itinerary_service.py # Report 转 itinerary 缓存与复用
│ │ ├── cache_service.py # Redis 缓存封装与降级逻辑
│ │ ├── local_life_service.py # 可选餐饮/住宿本地生活数据源
│ │ ├── location_service.py # 位置建议、出发地/目的地跨度校验
│ │ ├── map_service.py # 高德地图 POI、地理编码、路线补充
│ │ ├── transport_query_service.py # 实时交通查询统一封装
│ │ ├── web_search_service.py # 联网搜索服务封装
│ │ ├── weather_service.py # 高德天气服务封装
│ │ ├── storage_service.py # SQLite 保存、查询、列表、删除
│ │ └── export_service.py # Markdown / PDF 渲染与导出
│ ├── data/ # 本地攻略文档
│ ├── eval/ # RAG 检索评估样例集
│ ├── scripts/ # ingest、地图验证、RAG 调试与评估脚本
│ ├── tests/ # pytest 测试
│ ├── .env.example # 后端环境变量模板
│ ├── pyproject.toml # 后端 Python 依赖声明
│ └── uv.lock # uv 锁定文件
├── frontend/
│ ├── src/
│ │ ├── services/
│ │ │ └── api.ts # Axios 封装与前端 API 调用
│ │ ├── types/
│ │ │ └── index.ts # TypeScript 数据类型定义
│ │ ├── views/
│ │ │ ├── Home.vue # 规划页
│ │ │ ├── Result.vue # 结果展示页
│ │ │ ├── DeepPlanResult.vue # 深度规划 Markdown 报告与来源页
│ │ │ └── History.vue # 历史列表页
│ │ ├── components/
│ │ │ ├── AmapTripMap.vue # 地图展示组件
│ │ │ ├── FloatingChatbot.vue # Vue 外壳
│ │ │ ├── FloatingChatbotReact.tsx # ChatUI 主体验、流式响应、本地记忆 payload
│ │ │ └── ChatbotOrb.tsx # 聊天悬浮球
│ │ ├── App.vue # 页面切换入口
│ │ └── main.ts # 前端入口
│ ├── .env.example # 前端环境变量模板
│ └── package.json
├── CHANGELOG.md # 项目功能与架构更新日志
├── docs/
│ └── chatbot_memory_system_design.md # 浮动助手记忆系统设计
├── .gitignore
└── README.md
docs/默认作为本地开发与面试准备文档目录处理;当前.gitignore只放行docs/chatbot_memory_system_design.md这类需要随项目说明同步的关键设计文档。
backend/app/services/trip_service.py负责 itinerary 主流程编排,包括天数拆分、预算估算、地图 enrich 以及编辑后的统一刷新。backend/app/services/deep_planning_service.py负责创建深度规划后台任务,把规划表单整合成研究 query,并持久化任务进度、最终 Markdown 与来源列表。backend/app/services/report_itinerary_service.py负责把 Destination Intelligence Report 转换为结果页可展示的结构化 itinerary,并缓存转换结果。backend/app/services/cache_service.py负责 Redis 客户端懒加载、JSON 缓存读写与 Redis 不可用时的优雅降级。backend/app/agents/trip_planner_agent/负责调用大模型生成结构化旅行草稿,并处理单日编辑时的 LLM 输出。backend/app/agents/chatbot_agent/负责浮动旅行助手的记忆预处理、意图识别、补充问答、联网搜索、研究型回答和 itinerary 修改。backend/app/agents/chatbot_agent/memory/负责长期记忆系统,包括操作检测、候选分类、SQLite/Chroma 存储、检索排序、过期归档、opt-out 与管理命令。backend/app/agents/destination_intelligence_agent/负责联网检索、分章节总结、反思补查和最终 Markdown 深度攻略生成。backend/app/agents/report_itinerary_agent/负责把 Markdown 攻略抽取为结构化结果页数据。backend/app/agents/tools/rag_tool.py负责 RAG 在线阶段的 Query Rewrite,把目的地、偏好、节奏与备注整理成更适合检索的 query。backend/app/rag/retriever.py负责基础向量召回后的结果封装、Redis 缓存以及轻量 Rerank,把更贴近旅行规划目标的片段排到前面。backend/app/services/map_service.py负责对接高德地图 Web 服务,并结合 Redis 缓存补充地址、经纬度、评分、参考消费、标签、电话、路线估算和附近餐饮住宿推荐。backend/app/services/location_service.py负责位置建议和跨城市/跨区域目的地跨度检查,辅助前端表单减少歧义输入。backend/app/services/transport_query_service.py负责封装可选 12306 MCP 实时铁路余票查询,供聊天助手实时问答使用。backend/app/services/web_search_service.py负责封装联网搜索服务,供聊天助手和研究节点复用。backend/app/services/export_service.py负责把 itinerary 渲染成 Markdown 与中文 PDF。backend/app/services/storage_service.py负责 SQLite 数据保存、读取、历史列表和删除。frontend/src/services/api.ts负责前端与后端接口通信,包括普通 HTTP 和聊天 SSE 流式响应。frontend/src/views/Result.vue负责承接 itinerary 的结果展示、地图、天气和导出交互。frontend/src/components/FloatingChatbotReact.tsx负责浮动助手主体交互,构造包含session_id、memory_opt_out、profile、summary 和 history 的聊天请求。backend/scripts/debug_rag_retrieval.py负责调试 RAG 在线阶段,输出检索 query、top-k 召回片段、rerank_score与rerank_reasons。backend/scripts/evaluate_rag_retrieval.py负责基于小型样例集评估 RAG 检索效果,输出 Top1 命中、TopK 命中、关键词覆盖与噪声片段数量。backend/eval/rag_eval_cases.json记录旅行场景下的 RAG 检索评估样例,用于对比后续检索优化前后的效果变化。
以下命令默认从项目根目录 Trip_Planner/ 开始执行。后端依赖使用 uv 管理,前端依赖使用 npm 管理。
如果本机还没有安装 uv:
curl -LsSf https://astral.sh/uv/install.sh | shcd Trip_Planner
cd backend
# 手动复制 .env.example 为 .env,并填写你的配置
cp .env.example .env
# 安装/同步 Python 依赖,自动创建 backend/.venv
uv sync
# 启动 FastAPI 服务
uv run python -m uvicorn app.api.main:app --host 0.0.0.0 --port 8000启动后访问:
http://127.0.0.1:8000/
http://127.0.0.1:8000/docs
cd Trip_Planner
cd frontend
npm install
# 手动复制 .env.example 为 .env,并填写你的配置
cp .env.example .env
npm run dev启动后访问:
http://127.0.0.1:5173
LLM_PROVIDER=openai_compatible
LLM_API_KEY=your_dashscope_api_key
LLM_MODEL=qwen-max
LLM_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
LLM_TIMEOUT_SECONDS=60
LLM_MAX_RETRIES=1
CHROMA_DB_DIR=db/chroma_db
CHROMA_COLLECTION_NAME=travel_guides
CHATBOT_MEMORY_COLLECTION_NAME=chatbot_memories
CHATBOT_MEMORY_USE_CHROMA=false
EMBEDDING_MODEL=nomic-embed-text:latest
EMBEDDING_API_KEY=
EMBEDDING_BASE_URL=http://127.0.0.1:11434/
EMBEDDING_BATCH_SIZE=10
CHATBOT_ROUTER_USE_EMBEDDINGS=false
AMAP_API_KEY=your_amap_web_service_key
AMAP_BASE_URL=https://restapi.amap.com/v3
AMAP_DEFAULT_CITY=
AMAP_TIMEOUT_SECONDS=20
ENABLE_AMAP_ENRICHMENT=true
REDIS_ENABLED=false
REDIS_URL=redis://127.0.0.1:6379/0
REDIS_KEY_PREFIX=trip_planner
REDIS_DEFAULT_TTL_SECONDS=1800
REDIS_WEATHER_TTL_SECONDS=1800
REDIS_MAP_TTL_SECONDS=86400
REDIS_RAG_TTL_SECONDS=21600
DESTINATION_INTELLIGENCE_AGENT_API_KEY=your_deep_planning_llm_api_key
DESTINATION_INTELLIGENCE_AGENT_MODEL_NAME=qwen-max
DESTINATION_INTELLIGENCE_AGENT_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
TAVILY_API_KEY=your_tavily_api_key
SEARXNG_BASE_URL=http://your-searxng-host:8888/
DEEP_PLANNING_SEARCH_ENGINE=tavily
ENABLE_12306_MCP=false
MCP_12306_URL=http://127.0.0.1:10808/mcp
MCP_12306_TIMEOUT_SECONDS=30
MCP_12306_MAX_RESULTS=20
MCP_12306_AUTOSTART=false
ENABLE_LOCAL_LIFE_ENRICHMENT=false
LOCAL_LIFE_TIMEOUT_SECONDS=20
MEITUAN_API_BASE_URL=
MEITUAN_API_KEY=
DIANPING_API_BASE_URL=
DIANPING_API_KEY=VITE_API_BASE_URL=http://你的服务器地址:8000
VITE_AMAP_JS_KEY=your_amap_javascript_api_key注意:
- 如果浏览器在本机打开,
VITE_API_BASE_URL不要写远程服务器内部的127.0.0.1 - 后端高德 key 使用 Web 服务 key
- 前端地图 key 使用 JavaScript API key
DESTINATION_INTELLIGENCE_AGENT_*和TAVILY_API_KEY用于深度规划与浮动聊天助手的联网检索能力SEARXNG_BASE_URL可配置私有 SearXNG 实例,深度规划支持tavily/searxng优先级选择CHATBOT_MEMORY_USE_CHROMA=false时,聊天长期记忆仍会写入 SQLite,但检索使用关键词、作用域、重要性和时间排序;设置为true后会使用CHATBOT_MEMORY_COLLECTION_NAME对应的 Chroma collection 做语义召回CHATBOT_ROUTER_USE_EMBEDDINGS=true会让聊天意图路由优先使用 embedding 语义匹配,embedding 配置与 RAG/记忆共用ENABLE_12306_MCP=true时需要把MCP_12306_URL指向可访问的 Streamable HTTP MCP 端点,通常以/mcp结尾MCP_12306_AUTOSTART=true时后端启动会自动拉起本地backend/servers/mcp_12306/(vendor 自 Joooook/12306-mcp)Node 子进程,日志直接打印在运行后端的终端;首次使用需先手动执行一次cd backend/servers/mcp_12306 && npm install && npm run build,构建产物缺失时后端只打印警告并跳过启动,不影响后端正常运行- Redis 与本地生活推荐都是可选能力,未配置时会自动降级到无缓存或高德基础推荐
- 修改
.env后需要重启对应服务
首次使用 Chroma 检索前,执行:
cd backend
uv run python scripts/ingest_data.py成功后会看到类似结果:
written_count: 9
| 方法 | 路径 | 说明 |
|---|---|---|
GET |
/ |
服务启动检查 |
GET |
/health |
健康检查 |
POST |
/trip/generate |
快速生成结构化行程 |
POST |
/trip/deep-generate |
创建深度规划后台任务 |
POST |
/trip/edit |
智能编辑行程 |
POST |
/trip/save |
保存行程 |
GET |
/trip |
历史列表 |
GET |
/trip/{trip_id} |
行程详情 |
GET |
/trip/{trip_id}/deep-itinerary |
把已完成深度规划转换为结果页 itinerary |
GET |
/trip/reports/{report_id} |
查询历史 Markdown Report 详情 |
GET |
/trip/reports/{report_id}/itinerary |
把历史 Markdown Report 转换为结果页 itinerary |
GET |
/trip/reports/{report_id}/markdown |
查看历史 Markdown Report 原文 |
DELETE |
/trip/{trip_id} |
删除行程 |
POST |
/chatbot/message |
浮动旅行助手普通对话 |
POST |
/chatbot/message/stream |
浮动旅行助手 SSE 流式对话 |
GET |
/location/suggestions |
位置建议 |
POST |
/location/span-check |
出发地/目的地跨度检查 |
POST |
/export/markdown |
直接导出当前草稿 Markdown |
POST |
/export/pdf |
直接导出当前草稿 PDF |
GET |
/export/{trip_id}/markdown |
导出已保存行程 Markdown |
GET |
/export/{trip_id}/pdf |
导出已保存行程 PDF |
GET |
/weather/forecast |
查询天气 |
cd backend
uv run pytest tests/test_api_trip.py -q运行全部后端测试:
cd backend
uv run pytest -qcd backend
uv run python scripts/test_map_service.pycd backend
uv run python scripts/test_trip_service_real.py项目把“测试”和“评测”分开处理:测试主要验证接口、服务和模型代码是否按预期工作;评测用于观察 RAG 检索质量、Agent 路由稳定性、工具调用边界和真实 LLM 输出质量。涉及 RAG、Prompt、聊天路由、记忆、实时查询或行程修改的改动,建议在普通测试之外补跑对应 eval。
RAG 检索评测用于判断本地攻略检索是否命中正确材料,并持续观察跨目的地污染、弱相关片段和 Top-1 排序问题。当前已落地的入口如下:
cd backend
uv run python scripts/evaluate_rag_retrieval.py也可以指定自定义样例集:
cd backend
uv run python scripts/evaluate_rag_retrieval.py --cases eval/rag_eval_cases.json运行前需要确保已经执行过 RAG 入库:
cd backend
uv run python scripts/ingest_data.py该脚本只读取 backend/db/chroma_db 中已有的 Chroma collection,不回退到关键词索引或本地 JSON 索引;如果向量库目录、collection 或 embedding 配置不可用,会直接报错。
核心指标:
| 指标 | 含义 |
|---|---|
top1_title_hit_rate |
第一条检索结果是否命中预期标题 |
topk_title_hit_rate |
Top-K 结果中是否包含预期标题 |
required_keyword_coverage |
Top-K 内容是否覆盖必要关键词 |
noise_count_total |
命中标题噪声片段数量 |
cross_destination_noise_count_total |
跨目的地污染片段数量 |
最近记录的 RAG 检索基线:
cases: 15
top1_title_hit_rate: 11/15
topk_title_hit_rate: 15/15
required_keyword_coverage: 57/63
noise_count_total: 0
cross_destination_noise_count_total: 0
评测样例维护在 backend/eval/rag_eval_cases.json。每次调整 backend/app/agents/tools/rag_tool.py、backend/app/rag/retriever.py、backend/app/rag/vector_db.py、攻略 Markdown 数据、embedding 模型或 rerank 规则后,都应该重新跑这一组评测并记录指标变化。
聊天助手评测覆盖普通问答、联网搜索、Research、行程修改、确认流、记忆、SSE 事件和越界拒识。评测样例维护在 backend/eval/chatbot_cases.yaml,按 smoke、regression、release 分层,并用 risk_level 标识高风险 case。
确定性回归评测使用 FakeChatLLM 和 fixture-backed 工具,不访问真实 LLM 或外部网络:
cd backend
uv run pytest eval/test_chatbot_eval_runner.py -q如果需要生成完整 Markdown 报告,可以使用 CLI runner:
cd backend
uv run python -m eval.test_chatbot_eval_runner \
--harness fixture \
--llm fake \
--stage smoke \
--report-path eval/reports/chatbot_agent_eval_results.md真实 LLM / 真实工具评测只建议在发布前或专项排查时手动运行,因为会调用配置的模型、搜索、天气或交通服务:
cd backend
uv run python -m eval.test_chatbot_eval_runner \
--harness real \
--llm real \
--stage release \
--limit 20 \
--report-path eval/reports/chatbot_agent_eval_results_real_llm.mdChatbot eval 主要关注:
| 指标 | 含义 |
|---|---|
pass_rate |
case 级整体通过率 |
high_risk_pass_rate |
高风险 case 通过率,例如确认前不得修改、取消不得修改、越界拒识 |
router_accuracy |
意图路由是否命中预期 intent |
search/update/out_of_scope precision/recall/f1 |
搜索、修改和越界拒识的触发边界 |
state_pass_rate |
itinerary、确认草稿、profile、conversation_summary 等状态是否正确 |
source_pass_rate |
实时搜索或研究回答是否带有符合预期的来源 |
memory_pass_rate |
记忆写入、检索、删除、清空和 opt-out 是否符合预期 |
stream_pass_rate |
SSE 流式事件序列是否满足前端契约 |
groundedness_pass_rate / rubric_pass_rate |
回答是否基于来源、是否满足人工规则量表 |
| 改动类型 | 建议补跑 |
|---|---|
| 普通后端服务、API 或模型字段 | uv run pytest -q |
| RAG query rewrite、检索、rerank、embedding 或攻略数据 | uv run python scripts/evaluate_rag_retrieval.py |
| Chatbot 路由、工具、记忆、确认流、SSE 或 Prompt | uv run pytest eval/test_chatbot_eval_runner.py -q |
| 真实 LLM Prompt、模型供应商或联网工具行为 | CLI runner 的 --harness real --llm real 小样本评测 + 人工抽查 |
| 发布候选版本 | 普通测试 + RAG eval + Chatbot deterministic eval;高风险能力再补真实 LLM release 抽样 |
更完整的规划见 docs/rag-build-and-evaluation-plan.md 和 docs/chatbot_agent_eval_plan.md。端到端行程生成质量、上下文压缩质量和线上反馈闭环仍属于后续增强方向。
Home.vue
-> POST /trip/deep-generate
-> deep_planning_service.py 后台任务
-> destination_intelligence_agent
-> 搜索计划 / 联网检索 / 分章节总结 / 反思补查
-> Markdown Report + Sources
-> History.vue / DeepPlanResult.vue
-> GET /trip/{trip_id}/deep-itinerary
-> report_itinerary_agent
-> Result.vue
FloatingChatbot.vue / FloatingChatbotReact.tsx
-> buildChatbotPayload()
session_id / memory_opt_out / profile / conversation_summary / history / current_itinerary
-> POST /chatbot/message 或 POST /chatbot/message/stream
-> MemoryManager
resolve_scope / detect_operation / prepare_context
-> ChatbotIntentRouter
static / semantic / LLM decision
-> Ask / Search / Research / Update
-> 当前 itinerary 问答、联网搜索、调研步骤、实时交通查询或行程回写
-> add_interaction 写入长期记忆候选
-> 前端刷新 itinerary / profile / conversation_summary
用户输入“记住我不想早起”
-> MemoryOperationDetector 标记 add
-> MemoryClassifier 生成 semantic memory
-> MemoryStore 写入 chatbot_memory_items
-> 可选写入 Chroma chatbot_memories
-> 继续进入普通旅行意图路由
用户输入“我之前说过什么偏好?”或“忘掉不吃辣”
-> MemoryOperationDetector 标记 retrieve / manage
-> retrieve 走 MemoryRetriever + AskNode 生成自然语言回答
-> manage 可直接 list / delete / clear / opt_out / stats
Home.vue
-> POST /trip/generate
-> trip_service.py
-> trip_planner_agent
-> rag_tool.py / vector_db.py
-> map_service.py
-> Itinerary
Result.vue
-> POST /trip/edit
-> trip_service.py
-> generate_day_edit_draft()
-> 更新目标 DayPlan
点击导出 PDF / Markdown
-> 当前草稿:POST /export/pdf 或 POST /export/markdown
-> 已保存行程:GET /export/{trip_id}/pdf 或 GET /export/{trip_id}/markdown
-> export_service.py
-> ReportLab 生成 PDF / Markdown 文本
优先检查:
- 后端是否启动在
8000 frontend/.env的VITE_API_BASE_URL是否正确- 修改
.env后是否重启前端 - 浏览器控制台是否有网络错误
优先检查:
VITE_AMAP_JS_KEY是否配置- 高德 JavaScript API key 是否可用
- itinerary 中是否有经纬度字段
- 后端
ENABLE_AMAP_ENRICHMENT是否为true
优先检查:
DESTINATION_INTELLIGENCE_AGENT_API_KEY和DESTINATION_INTELLIGENCE_AGENT_MODEL_NAME是否配置TAVILY_API_KEY或SEARXNG_BASE_URL是否可用deep_planning_reflection_rounds是否过高导致请求耗时过长- 后端日志里是否有 LLM、搜索超时或 Report 转换错误
优先检查:
- 后端
/chatbot/message是否可访问 - 如果前端使用流式响应,确认
/chatbot/message/stream没有被代理或网关缓冲 - 聊天助手使用的 LLM 环境变量是否和后端主 LLM 配置一致
- 如果请求是联网搜索,确认
TAVILY_API_KEY是否配置
优先检查:
- 请求 payload 是否带有稳定的
session_id - 前端 localStorage 中
trip_planner.chatbot_memory_opt_out是否关闭了长期记忆 - 用户是否发过“关闭长期记忆”一类命令,后端会在当前 scope 写入 opt-out 控制记录
- SQLite 是否存在
chatbot_memory_items表;首次使用由MemoryStore懒加载创建 - 如果开启了
CHATBOT_MEMORY_USE_CHROMA=true,确认 embedding 和 Chroma 可用;不可用时系统会降级到 SQLite 关键词检索
正常导出时后端应看到:
POST /export/pdf
如果导出的是已保存行程,后端也可能看到 GET /export/{trip_id}/pdf。如果请求没有到达后端,优先检查前端是否已重启以及浏览器控制台是否有网络错误。
说明目录错了。前端命令必须在 frontend/ 目录执行:
cd frontend- ✅ 后端能力:快速行程生成、深度规划任务、Report 转 itinerary、浮动聊天助手、智能编辑、保存查询、历史列表、删除、天气查询、Markdown 导出与 PDF 导出接口
- ✅ AI 与数据能力:LangGraph/LangChain 行程生成链路、Destination Intelligence 深度攻略、聊天助手意图路由与联网检索、Report 结构化抽取、5 个目的地攻略 RAG 检索、Chroma 入库检索、高德地图地址/坐标/路线补充
- ✅ 聊天记忆系统:已接入 session/trip 作用域、短期摘要、TravelerProfile 合并、长期 SQLite 记忆表、显式记住/查询/删除/清空/统计/关闭保存、过期归档、敏感记忆过滤和可选 Chroma 语义索引
- ✅ RAG 在线优化:规则级 Query Rewrite(含目的地过滤)、多层 Rerank 降权、检索调试脚本与 15 条评估样例集
- ✅ 前端能力:规划页、结果页、深度规划报告页、历史列表页、浮动聊天助手,以及地图/天气/预算展示、导出与历史管理主流程
- ✅ 缓存与持久化:SQLite 持久化存储 + Redis 缓存层(覆盖天气、地图与 RAG 检索)
- ✅ 验证情况:核心链路稳定跑通,Redis 缓存 key 可在本地容器中验证写入
- ✅ 缓存与工程化能力(已完成基础版) 已完成 Redis 基础缓存层,当前已覆盖天气查询、地图查询与 RAG 检索结果缓存;后续可以继续扩展到热点目的地复用、异步任务状态保存与更细粒度的缓存命中统计。
- ✅ 实时信息增强(已完成基础版) 已接入 Tavily / SearXNG 联网搜索、位置建议、天气和可选 12306 MCP;后续可继续扩展景点票务、预约状态、演出展览和节假日限流信息。
- ✅ 聊天长期记忆(已完成基础版) 已实现 SQLite 权威存储、管理命令和可选 Chroma 语义索引;后续可继续补充用户登录后的 user scope、多设备同步、可视化记忆管理页、更细粒度的隐私策略和后台补索引任务。
- 🚧 RAG 检索增强
- ✅ 已完成第一轮在线阶段优化,接入轻量化 Query Rewrite、轻量 Rerank 与检索调试脚本。
- ✅ 已完成 RAG 知识库扩充至 5 个目的地,评估样例集扩充至 15 条。
- ✅ 已完成规则级 Rerank 多层降权(行程降权、简介降权、目的地不匹配降权)与 Query Rewrite 目的地过滤,消除跨目的地污染。
- 🚧 后续引入 LLM-based Query Rewrite(用 qwen-max 改写检索 query,替代手写规则)。
- 🚧 后续引入 Cross-encoder Rerank(用 bge-reranker-base 等模型做语义相关性打分,替代关键词规则)。
- 🚧 后续继续推进检索结果压缩、去冗与混合检索,减少冗余上下文和弱相关片段干扰。
- 🚧 更高阶方向可尝试 GraphRAG,用图结构表达城市、景点、路线与主题标签之间的关系,增强多地点联动推荐和行程合理性约束。
- 🚧 Agent 与工作流编排 快速规划、深度规划、Report 转换和聊天助手已分别使用 Agent / Graph 结构;后续可以把地图 enrich、天气补充、编辑、导出和记忆维护进一步统一成可观测的状态流。
- 🚧 外部工具与 MCP 化 当前已预留 12306 MCP;地图、天气、联网搜索、POI 检索这类外部能力后续可以逐步抽成 MCP 工具层,便于和不同 Agent 或工作流复用,而主业务编排继续保留在服务层。
- 🚧 模型效果提升 可以补充 prompt evaluation、输出质量打分、自动回归样例集,并进一步尝试旅行场景的指令微调或偏好对齐。
- 🚧 质量评估体系 后续可以建立旅行方案质量指标,例如结构完整性、预算合理性、地图命中率、天气一致性和用户指令满足度。
- 🚧 性能与稳定性 可以加入异步任务队列、请求限流、失败重试、日志追踪与监控告警,提升真实部署场景下的稳定性。
- 🚧 产品能力延展 可以继续增强地图路线连线、单日筛选、移动端适配、用户登录、多用户隔离和更正式的旅行手册式导出。




