--- title: RouteOpt Agent emoji: 🧭 colorFrom: blue colorTo: green sdk: gradio python_version: 3.11 app_file: app.py pinned: false short_description: Tool-calling route optimizer --- # RouteOpt Agent 基于公开大模型 API + 轻量工具调用的小规模路线优化智能体。它把用户自然语言转成路线优化任务,调用地理编码和路径矩阵工具,再用本地算法求解访问顺序,并自动生成 PDF 报告。 ## 一键运行 ```bash chmod +x run.sh ./run.sh ``` 启动后打开: ```text http://localhost:7860 ``` 首次运行会创建 conda 环境 `routeopt-agent` 并安装依赖。脚本会先尝试使用 `environment.yml` 创建标准环境;如果 conda 镜像下载不稳定,会自动克隆本机 base 环境,再用 pip 安装 `requirements.txt`。 ## LLM 配置 默认配置不需要你注册任何网站,也不需要提供 API token: - LLM:Pollinations OpenAI-compatible API,无需 token。失败时系统自动切换到本地解析和本地报告模板。 - 地理编码:OpenStreetMap Nominatim 公共接口,内置缓存并限制请求频率。 - 路径矩阵:OSRM public demo server。失败时自动切换到直线距离近似矩阵。 - 部署:Hugging Face Spaces 免费 Gradio Space。 如果本机出现 `ProxyError('Unable to connect to proxy')`,说明 Python 请求走了不可用代理。默认 `LLM_IGNORE_PROXY=1` 会让 LLM 请求忽略系统代理;如果你的网络必须使用代理访问外网,可在 `.env` 中改成: ```bash LLM_IGNORE_PROXY=0 ``` 更稳定的做法是使用正规 API key 服务,并把 key 放到 `.env` 或 Hugging Face Secrets。老师访问公开页面时不需要知道 token。 复制配置模板: ```bash cp .env.example .env ``` 推荐方案: ```bash # Groq:国际网络通常较稳,OpenAI-compatible LLM_PROVIDER=groq GROQ_API_KEY=gsk_xxx GROQ_MODEL=openai/gpt-oss-20b ``` ```bash # SiliconFlow:国内网络通常更友好,OpenAI-compatible LLM_PROVIDER=siliconflow SILICONFLOW_API_KEY=sk-xxx SILICONFLOW_MODEL=THUDM/GLM-Z1-9B-0414 ``` ```bash # Gemini:Google 官方免费额度,国内网络可能需要代理 LLM_PROVIDER=gemini GEMINI_API_KEY=AIza... GEMINI_MODEL=gemini-2.5-flash ``` 也可以用 `LLM_PROVIDER=auto`,程序会按已配置的 key 自动选择:Groq -> SiliconFlow -> Gemini -> OpenRouter;没有 key 时退回 Pollinations。 ## 推荐演示输入 自然语言需求: ```text 我从上海交通大学闵行校区出发,想一天内逛完徐家汇、人民广场、外滩、陆家嘴,最后回到起点,尽量总时间短。 ``` 起点: ```text 上海交通大学闵行校区 ``` 目的地: ```text 徐家汇 人民广场 外滩 陆家嘴 ``` 这个样例的上海地点内置了离线坐标兜底,所以即使 Nominatim 临时限流,也能完成演示。 也可以使用北京样例: ```text 我从北京邮电大学出发,想一天内逛完国家大剧院、鼓楼、北海、国家植物园,最后回到起点,尽量总时间短。 ``` ## 输入失败时如何处理 页面不会直接抛出 Python 错误;如果任务无法完成,会说明失败发生在哪个工具,以及应该如何修改输入。 常见原因: - 起点或目的地为空。 - 目的地里只有起点,或者重复地点过多。 - 地点不在内置演示坐标中,同时在线地理编码服务超时、限流或找不到结果。 - 地名太泛,例如只写“鼓楼”“植物园”,在某些城市可能有多个匹配。 当前内置演示城市:上海、北京。 如果要演示其他城市,建议把地点写得更完整,例如“南京夫子庙”“广州塔”“深圳大学粤海校区”。如果在线地理编码仍然失败,可以直接输入坐标: ```text 某景点@39.9042,116.4074 ``` ## Agent Workflow 1. `LLM tool_call: submit_route_task`:把自然语言和表单提示抽取成结构化任务。 2. `geocode_places`:把地点转换为经纬度。 3. `build_route_matrix`:调用 OSRM 获取距离/时间矩阵。 4. `solve_route`:用 Held-Karp 动态规划精确求解小规模 TSP。 5. `LLM compose_summary`:生成中文解释。 6. `generate_pdf_report`:输出包含问题定义、工具调用轨迹、算法和结果的 PDF。 ## 公开部署到 Hugging Face Spaces 1. 打开 Hugging Face,新建一个 Space。 2. Space SDK 选择 `Gradio`。 3. Visibility 可选 `Public`。 4. 上传本仓库所有文件,或把仓库推送到 Space。 5. Space 会根据 `requirements.txt` 自动安装依赖,入口文件是 `app.py`。 老师访问 Space 链接即可运行,不需要知道任何 token。 ## 文件结构 ```text app.py # Gradio 页面入口 routeopt_agent/agent.py # Agent 编排和工具调用轨迹 routeopt_agent/geo_tools.py# 地理编码、OSRM 矩阵、兜底矩阵 routeopt_agent/solver.py # Held-Karp 路线优化 routeopt_agent/report.py # PDF 报告生成 routeopt_agent/parsing.py # 本地自然语言解析兜底 routeopt_agent/viz.py # SVG 路线示意图 environment.yml # 本地 conda 环境 requirements.txt # Hugging Face Spaces 依赖 run.sh # 一键运行脚本 ```