智能旅行规划服务

TripWeaver是一款基于自然语言处理和LLM的智能旅行规划服务,支持离线数据集和Google Places API的POI检索,提供个性化行程安排和解释。

  • by Hans-Yin
  • Python
  • 本地部署
  • 2 星标
  • 更新于
在 GitHub 查看 Hans-Yin/TripWeaver

使用说明

TripWeaver

现场演示

  • 前端(React):https://tripweaver-ai.vercel.app/
  • 后端(FastAPI):https://tripweaver.onrender.com
    • Swagger用户界面: https://tripweaver.onrender.com/docs
    • 健康: https://tripweaver.onrender.com/health

MCP编排的多上下文 出行计划:

自然语言→ 启发式解析器→ LLM解析器优化 → POI检索(离线/谷歌)→ 贪婪得分→ 维基百科丰富→ LLM解释层 → React前端。

后端(FastAPI)目前支持:

  • 自然语言查询解析
    • 基于规则的启发式解析器
    • LLM精炼结构化解析(OpenAI)
  • 两个POI数据源
    • 离线CSV数据集 (data/global_poi_dataset.csv)
    • Live Google Places API网站
  • 评分+贪婪POI选择
  • 维基百科描述丰富
  • 日常起搏控制 (宽松/标准/包装+定制 max_places_per_day)
  • LLM行程说明 (日复一日的推理、替代方案、旅行提示)
  • JSON行程输出与React前端兼容

1.安装

1.1克隆存储库

git clone https://github.com/Hans-Yin/TripWeaver.git
cd TripWeaver

1.2放置离线POI数据集

您的离线数据集必须放置在:

TripWeaver/data/global_poi_dataset.csv

必填(或可自动规范化)列:

  • city_name, place_name, country, place_category
  • price, open_time, close_time, popularity_score
  • lat, lon

列别名,如 price_usd, poi_category, latitude, longitude 自动映射。


1.3安装依赖项

推荐一个虚拟环境:

pip install -r requirements.txt

1.4环境变量

Google Places API密钥(可选)

对于实时POI检索:

export GOOGLE_PLACES_API_KEY="YOUR_GOOGLE_PLACES_API_KEY"

OpenAI API密钥(LLM解析器+LLM解释层需要)

export OPENAI_API_KEY="YOUR_OPENAI_API_KEY"

没有这些键,离线模式仍然可以工作(没有LLM功能/实时谷歌位置)。


2.运行后端服务器

从项目根:

uvicorn backend.app.main:app --reload

本地API终结点:

CORS被启用以支持React前端(本地开发和Vercel)。

已部署后端:

  • 基本URL: https://tripweaver.onrender.com
  • Swagger用户界面: https://tripweaver.onrender.com/docs
  • 健康: https://tripweaver.onrender.com/health

3.请求架构(POST /plan)

请求示例:

{
  "query": "3 days in New York, love museums and parks, low budget, avoid crowds",
  "days": 3,
  "city": null,
  "data_source": "offline",
  "max_places_per_day": 4,
  "pace": "standard"
}

字段摘要

字段 类型 描述
query string 免费自然语言旅行查询(城市、天数、偏好、预算、人群)
days int(可选) 显式天数;覆盖解析器/LLM(如果提供)
city string null
data_source "offline" "google"
max_places_per_day int(可选) 每天戴硬帽(例如,放松时戴3个,打包时戴6个)
pace string(可选) "relaxed", "standard",或 "packed" (用于UX+LLM解释)

后端工作流程

  1. 启发式解析器 提取物 city, days, categories 从 query

  2. LLM解析器优化 将查询转换为结构化JSON (city, total_days, categories, budget, crowd_preference)

  3. 合并显式 days 从请求(如果存在)解析 total_days

  4. 检索POI

    • 自 离线CSV,或
    • 自 Google Places API
  5. 贪婪得分 (人气+品类匹配)

  6. 应用 max_places_per_day 在跨天分发POI时

  7. 维基百科丰富 POI描述

  8. LLM解释层 生成:

    • 行程概述
    • 日复一日的叙述和节奏
    • 备选建议
    • 旅行提示(预算、人群、时间)
  9. 返回JSON用于前端渲染


4.示例响应

4.1离线数据集模式

{
  "city": "New York",
  "days": [
    {
      "day": 1,
      "places": [
        {
          "name": "Central Park",
          "category": "park",
          "description": "Central Park is an urban park..."
        },
        {
          "name": "The Metropolitan Museum of Art",
          "category": "museum",
          "description": "The Metropolitan Museum of Art..."
        }
      ]
    },
    {
      "day": 2,
      "places": [
        {
          "name": "Brooklyn Bridge",
          "category": "landmark",
          "description": "The Brooklyn Bridge is..."
        }
      ]
    }
  ],
  "explanation": "This itinerary balances museums and parks while keeping each day at a manageable pace..."
}

4.2实时谷歌位置模式

{
  "city": "New York",
  "days": [
    {
      "day": 1,
      "places": [
        {
          "name": "Central Park",
          "category": "park",
          "description": "..."
        },
        {
          "name": "The Metropolitan Museum of Art",
          "category": "museum",
          "description": "..."
        }
      ]
    },
    {
      "day": 2,
      "places": [
        {
          "name": "Brooklyn Museum",
          "category": "museum",
          "description": "..."
        },
        {
          "name": "American Museum of Natural History",
          "category": "museum",
          "description": "..."
        }
      ]
    }
  ],
  "explanation": "This two-day New York itinerary highlights major museums while keeping walking distances reasonable..."
}

确切的POI可能因Google Places API的响应而有所不同。


5.反应前端

React前端(Vite)提供了一个简单的UI:

  • 输入自然语言旅行查询

  • 选择 数据源:离线/谷歌

  • 选择 每日速度:

    • 🧘 放松的 (约3个景点/天)
    • 🚶 标准 (约4个景点/天)
    • ⚡ 拥挤的 (约6个景点/天)
  • 可选覆盖 最大斑点/天 通过数字输入

  • 切换 显示LLM解释

  • 将生成的行程可视化为每日时间表

已部署前端:

前端发送 POST /plan 请求到FastAPI后端(本地或部署的渲染端点)。

如果你想 在本地FastAPI后端上运行前端,您需要更新API端点。

编辑 src/api.ts

// src/api.ts

import axios from "axios";

// Use this for deployed backend (default)
const API_BASE = "https://tripweaver.onrender.com";

// Use this for local backend (uncomment when running FastAPI locally)
// const API_BASE = "http://127.0.0.1:8000";

何时更改此设置

场景 API_BASE
使用已部署的后端(渲染) https://tripweaver.onrender.com
在本地运行FastAPI http://127.0.0.1:8000

更改端点后,重新启动前端开发服务器:

npm run dev

这允许相同的前端代码库与 本地后端或部署的后端.


6.贡献者

  • 尹伯涵
  • 陈文政
  • 徐逸飞