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).
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`.
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:
`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.