Skip to content

Repository files navigation

Trip Planner

融合大模型、RAG、本地攻略与高德地图能力的智能旅行规划系统

Trip Planner 是一个面向中文旅行场景的 AI 旅行规划项目。用户输入目的地、日期、预算、人数和偏好后,系统可以走两条链路:快速生成可编辑的结构化 itinerary,或进入深度规划模式,由 Destination Intelligence Agent 联网检索、反思补查并生成带来源的 Markdown 攻略。

相比只输出一段文本的 LLM Demo,这个项目更强调“研究、规划、追问、修改”的完整闭环:深度规划负责把旅行前的信息收集和判断过程沉淀成报告,浮动聊天机器人负责在结果页继续问答、联网检索和自然语言改行程。地图、天气、预算、历史与导出能力围绕这两个核心流程提供支撑。

🖼️ 项目展示

展示素材统一维护在 assets/showcase/,覆盖规划表单、行程结果、深度规划研究过程、历史行程和浮动聊天助手等核心界面。

规划页 行程生成结果
Trip Planner 规划界面 Trip Planner 行程生成界面
深度规划研究过程 历史行程
Trip Planner 深度规划研究过程 Trip Planner 历史行程界面
浮动聊天助手
Trip Planner 浮动聊天助手界面

📝 最近更新

  • 2026-07-03
    • 聊天记忆系统:浮动旅行助手接入长期记忆框架,支持 session_id 作用域、memory_opt_out、显式记住/查询/删除/清空/统计/关闭长期记忆等管理命令。
    • 记忆存储:新增 chatbot_memory_items SQLite 表作为权威元数据层,按 semantic / episodic / perceptual 分类保存偏好、行程事件与实时查询观察;Chroma 语义索引可通过 CHATBOT_MEMORY_USE_CHROMA=true 开启,默认降级为关键词与元数据排序。
    • 聊天链路:MemoryManagerChatbotIntentRouter 前完成记忆操作检测和上下文检索,并把 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
Loading

快速规划数据流:前端收集用户输入 → 后端调用 LLM + RAG 生成结构化行程 → 地图服务补充地址、坐标和路线 → 前端展示地图、天气、预算和每日行程 → 用户可保存、编辑、查看历史并导出文档。

深度规划数据流:前端提交深度规划任务 → 后台 Destination Intelligence Agent 制定搜索计划、联网检索、分章节总结和反思补查 → 生成带来源的 Markdown 深度攻略 → 历史页展示任务状态与研究来源 → 用户可查看深度报告,也可把报告转换为结构化 itinerary 并进入结果页继续追问、编辑和导出。

聊天助手数据流:结果页把当前 itinerary、聊天历史、traveler profile、session_idmemory_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:前端维护最近 historyconversation_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
Loading

关键约束:

  • 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_idmemory_opt_out、profile、summary 和 history 的聊天请求。
  • backend/scripts/debug_rag_retrieval.py 负责调试 RAG 在线阶段,输出检索 query、top-k 召回片段、rerank_scorererank_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 | sh

1. 启动后端

cd 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

2. 启动前端

cd Trip_Planner
cd frontend
npm install
# 手动复制 .env.example 为 .env,并填写你的配置
cp .env.example .env
npm run dev

启动后访问:

http://127.0.0.1:5173

🔐 环境变量

后端 backend/.env

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=

前端 frontend/.env

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 后需要重启对应服务

🧠 RAG 数据初始化

首次使用 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 查询天气

🧪 测试与验证

后端 API 测试

cd backend
uv run pytest tests/test_api_trip.py -q

运行全部后端测试:

cd backend
uv run pytest -q

高德服务测试

cd backend
uv run python scripts/test_map_service.py

真实行程生成测试

cd backend
uv run python scripts/test_trip_service_real.py

📊 评测体系

项目把“测试”和“评测”分开处理:测试主要验证接口、服务和模型代码是否按预期工作;评测用于观察 RAG 检索质量、Agent 路由稳定性、工具调用边界和真实 LLM 输出质量。涉及 RAG、Prompt、聊天路由、记忆、实时查询或行程修改的改动,建议在普通测试之外补跑对应 eval。

RAG 检索评测

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.pybackend/app/rag/retriever.pybackend/app/rag/vector_db.py、攻略 Markdown 数据、embedding 模型或 rerank 规则后,都应该重新跑这一组评测并记录指标变化。

Chatbot Agent 评测

聊天助手评测覆盖普通问答、联网搜索、Research、行程修改、确认流、记忆、SSE 事件和越界拒识。评测样例维护在 backend/eval/chatbot_cases.yaml,按 smokeregressionrelease 分层,并用 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.md

Chatbot 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.mddocs/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 导出

点击导出 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/.envVITE_API_BASE_URL 是否正确
  • 修改 .env 后是否重启前端
  • 浏览器控制台是否有网络错误

地图不显示

优先检查:

  • VITE_AMAP_JS_KEY 是否配置
  • 高德 JavaScript API key 是否可用
  • itinerary 中是否有经纬度字段
  • 后端 ENABLE_AMAP_ENRICHMENT 是否为 true

深度规划一直生成中或失败

优先检查:

  • DESTINATION_INTELLIGENCE_AGENT_API_KEYDESTINATION_INTELLIGENCE_AGENT_MODEL_NAME 是否配置
  • TAVILY_API_KEYSEARXNG_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 关键词检索

PDF 导出空白页

正常导出时后端应看到:

POST /export/pdf

如果导出的是已保存行程,后端也可能看到 GET /export/{trip_id}/pdf。如果请求没有到达后端,优先检查前端是否已重启以及浏览器控制台是否有网络错误。

npm run dev 找不到 package.json

说明目录错了。前端命令必须在 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、输出质量打分、自动回归样例集,并进一步尝试旅行场景的指令微调或偏好对齐。
  • 🚧 质量评估体系 后续可以建立旅行方案质量指标,例如结构完整性、预算合理性、地图命中率、天气一致性和用户指令满足度。
  • 🚧 性能与稳定性 可以加入异步任务队列、请求限流、失败重试、日志追踪与监控告警,提升真实部署场景下的稳定性。
  • 🚧 产品能力延展 可以继续增强地图路线连线、单日筛选、移动端适配、用户登录、多用户隔离和更正式的旅行手册式导出。

About

融合大模型、RAG、本地攻略与高德地图能力、支持AI聊天助手实时规划修的智能旅行规划系统

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages