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_categoryprice,open_time,close_time,popularity_scorelat,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 | 城市名称;如果为null,解析器+LLM从中推断 query |
data_source | "offline" | "google" | 选择POI提供商 |
max_places_per_day | int(可选) | 每天戴硬帽(例如,放松时戴3个,打包时戴6个) | |
pace | string(可选) | "relaxed", "standard",或 "packed" (用于UX+LLM解释) |
后端工作流程
- 启发式解析器 提取物
city,days,categories从query
- LLM解析器优化 将查询转换为结构化JSON
(city, total_days, categories, budget, crowd_preference)
- 合并显式
days从请求(如果存在)解析total_days
- 检索POI
- 自 离线CSV,或 - 自 Google Places API
- 贪婪得分 (人气+品类匹配)
- 应用
max_places_per_day在跨天分发POI时
- 维基百科丰富 POI描述
- LLM解释层 生成:
- 行程概述 - 日复一日的叙述和节奏 - 备选建议 - 旅行提示(预算、人群、时间)
- 返回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.贡献者
- 尹伯涵
- 陈文政
- 徐逸飞
