Files
gmTouringMiniApp/server/README.md
T
周瑞哲andClaude Fable 5 0a00cd5b3a feat(travel): 接入远端 AI 推荐服务,支持 GLM real 模式与本地静默回退
- createPlan 在配置 VITE_TRAVEL_ASSISTANT_API_BASE_URL 时调用 FastAPI 推荐服务
  做无坐标选点,路线/交通/时长仍由本机核算;远端不可用即静默回退本地规划
- 放开 loadPlan 对远端行程的回读限制(原 AI 冻结期禁用),行程页跳转不再丢行程
- planner/assistant 文案按是否启用远端如实切换,不再谎称「本期不调用 AI」
- 新增远端接通/回退/候选载荷单测;server/README 更新联调与 real 模式说明
- .env.development 默认指向已部署推荐服务;server/.env.example 补 GLM 示例

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 17:22:38 +08:00

3.0 KiB

Travel recommendation backend

This FastAPI service is the server-only AI boundary for the Guangming travel POC. It defaults to deterministic mock mode. Model credentials belong only in server/.env or the deployment environment and must never be added to the mini-program build.

The mini-program calls this service when VITE_TRAVEL_ASSISTANT_API_BASE_URL is set (.env.development points it at http://localhost:8000). If that variable is empty, or the service is unreachable or returns an error, the client silently falls back to its deterministic local planner — so the demo always works. The model only ever recommends POIs from a coordinate-free client whitelist; route geometry, transfer estimates, and final itinerary time remain client responsibilities. The itinerary page labels the result 真实 AI 推荐 (real), 远端演示规划 (mock), or 本地 POC 规划 (local fallback).

Contract

POST /api/v1/plans accepts a planning request and a coordinate-free POI whitelist:

{
  "mode": "custom",
  "preferences": {
    "destination": "深圳市光明区",
    "themes": ["亲子"],
    "pace": "moderate",
    "interests": ["自然风光"],
    "transport": "public_transport"
  },
  "durationMinutes": 240,
  "selectedPoiIds": ["poi_a", "poi_b"],
  "candidates": [
    {
      "id": "poi_a",
      "name": "Example A",
      "categoryCode": "urban_park",
      "tagCodes": ["family_friendly"],
      "summary": "Coordinate-free summary",
      "recommendationIndex": 4
    },
    {
      "id": "poi_b",
      "name": "Example B",
      "categoryCode": "cultural_venue",
      "tagCodes": ["indoor_venue"],
      "summary": "Coordinate-free summary",
      "recommendationIndex": 5
    }
  ]
}

The response contains only POI IDs, reasons, and suggested order. In custom mode all 2-8 user-selected IDs are retained. The model never receives origin, and never owns coordinates, route geometry, transfer estimates, or final itinerary time; those remain deterministic client responsibilities.

GET /api/v1/health reports mode (mock or real), whether real-model credentials are configured, and whether the selected mode is ready.

Run locally

cd server
python3 -m venv .venv
.venv/bin/python -m pip install -e '.[test]'
cd ..
corepack pnpm server:dev

Run tests from the repository root:

corepack pnpm server:test

Real model mode

Mock mode is deterministic and needs no credentials. To use a real model, set LLM_MODE=real in server/.env (gitignored) with any OpenAI-compatible endpoint — for example Zhipu GLM:

LLM_MODE=real
OPENAI_BASE_URL=https://open.bigmodel.cn/api/paas/v4
OPENAI_MODEL=glm-4-flash
OPENAI_API_KEY=<your key>

GET /api/v1/health then reports mode=real, configured=true, ready=true. With pnpm server:dev running, generate a plan from the mini-program (H5 dev server on :5173 is already in CORS_ORIGINS; for mp-weixin enable “不校验合法域名” in the devtools). To force the local planner again, unset VITE_TRAVEL_ASSISTANT_API_BASE_URL or stop the server.