用1B小模型打造黄金时刻散步规划器:让AI只负责语言,代码负责计算

用1B本地模型做语言解析、确定性代码做路径计算,输出可打印散步路线卡,让屏幕退出户外体验。
这个散步规划器的核心工程思路是严格划分职责边界:本地1B-3B小模型只负责解析用户自然语言请求和撰写路线卡文案,所有数值计算(日落时间、路网下载、环线评分)全部交给`astral`、`osmnx`、`networkx`等确定性工具完成。系统通过JSON Schema强制结构化输出防止格式错误,通过"双括号地名校验"机制在事后比对OSM真实地名以拦截幻觉。模型对比测试显示三款模型内存均低于0.5GB,qwen2.5:3b在配速理解和卡片精准度上表现最佳。最终交付物是一张大字号单页路线卡和一个GPX文件,产品哲学是"让屏幕输掉"——用最短的屏幕时间换取最快的出门速度。
一个运行在本地1B模型上的散步规划器,核心设计理念出人意料地克制:让屏幕成为整个体验中最短的一环。开发者的目标很明确——花几分钟敲键盘,最终得到一张可打印的单页路线卡和一个GPX文件,然后把手机揣进口袋出门,赶在日落前走进被低角度阳光穿透的树林。

这个项目最值得关注的地方,不在于它用了多强的模型,而在于它如何用一个只有1B参数的小模型,稳定产出不会"胡编乱造"的结果。答案是一条清晰的职责边界:模型只做语言,确定性代码做所有数值计算。
要解决的真实痛点
大多数"我该去哪散步"的工具都要求你盯着屏幕。你打开地图应用、拖来拖去、查看日照、挑一条环线——等你终于出门,光线早已移动。开发者想要的恰恰相反:键盘前几分钟的操作,换来一张大字号、带小地图的单页路线卡,外加一个可导入 Organic Maps 或 OsmAnd 的 GPX 文件。
作者在实测中给出了具体场景:17:27 打印出单页卡片出门,日落在 18:07,路线把他引向附近的绿地,低角度阳光恰好在卡片预言的位置穿过树木。这种"离屏"的产品哲学,是整个项目的出发点。
让系统成立的铁律:模型永远不负责路径规划
这是整篇文章最核心的工程洞见。一个1B到3B的模型根本无法在真实街道网络中规划环线——它会凭空发明一条路、漏掉一个死胡同,或者交给你一条横穿河流的路线。因此作者做了明确切分:
- 模型负责语言。 它把你的请求("天黑前45分钟,要有树、要安静")解析成结构化参数,并负责撰写最终卡片。
- 确定性代码负责所有数值。
astral计算日落与黄金时刻窗口,osmnx下载步行路网与绿地数据,networkx构建并对环线打分。
整个流程是一个小型 LangGraph 管线:intake → sun → weather → map_fetch → route_builder → critic → card_writer → render。其中 critic 节点可以把路线退回重试,如果达不到目标长度就适当放宽约束。这种设计把LLM的不确定性关进了一个很小的笼子里。
这里提到的几个工具值得简要说明。osmnx 是一个 Python 库,专门用于从 OpenStreetMap(OSM)下载和分析街道网络数据,它可以把真实城市的路网转化为可计算的图结构。networkx 则是 Python 生态中最主流的图计算库,负责在路网图上执行最短路径、环线搜索等算法。astral 专门处理天文计算,输入地理坐标和日期就能精确返回日出、日落、黄金时刻(golden hour)的时间——黄金时刻通常指日落前后约一小时,此时太阳角度极低,光线呈橙红色且方向性强,是摄影和户外散步的理想时段。LangGraph 是 LangChain 生态提供的一个有向图工作流框架,允许开发者把多个 LLM 调用和工具调用串联成可带分支、可回退的管线,critic 节点能把路线退回重试正是利用了这种有状态的循环能力。
用JSON Schema读取用户请求
intake 节点通过本地 Ollama 模型请求结构化输出,确保即使是小模型也能返回合法JSON:
resp = llm.chat_structured(
model=state["model_name"],
system="Extract walk parameters. Return JSON only.",
user=state["user_input"],
schema=IntakeParams.model_json_schema(),
temperature=0.0,
keep_alive="10m", # 保持模型热态直到卡片写完
)
intake = IntakeParams.model_validate_json(resp)
一个关键的健壮性设计:如果模型无法访问或返回垃圾数据,节点会回退到默认值并记录一条警告。应用永远能产出一张卡片——这是面向最终体验而非技术炫技的典型思路。
JSON Schema 是一种描述 JSON 数据结构的规范,通过定义字段名称、类型和约束来限定合法的输出格式。在 LLM 调用中,将 Schema 附加到提示词并设置 temperature=0.0(即完全确定性输出),可以显著降低模型返回格式错误或字段缺失的概率。Ollama 在本地运行开源模型时支持"结构化输出"模式(structured output),底层通过语法约束(grammar-constrained decoding)强制模型的 token 采样始终符合指定 Schema,而非依赖模型自觉遵守指令——这是小模型能在 intake 环节稳定返回合法 JSON 的技术基础,而非单纯靠提示词工程。keep_alive="10m" 则告诉 Ollama 在本次请求结束后继续将模型权重保留在内存中十分钟,避免后续 card_writer 节点调用时重新加载模型带来的延迟。
只用事实写卡片,并逐一核验地名
card_writer 的提示词被刻意收紧:模型只能使用已验证的事实,而且每个地名都必须用 [[双括号]] 包裹,以便事后核查。
Use ONLY these facts. Do not invent places, landmarks, or plants.
Wrap every place name in [[double brackets]].
Start: ... | Distance: 3.4 km (~45 min) | Sunset: 2026-10-11 18:08
Golden light comes from the 271° . Weather: 29 C, 20% rain
Green spaces on the route: Allah Rakha Park, Bagh-e-Lyari
随后一段校验代码把所有 [[name]] 抽出来,与 OSM 的真实地名列表比对:
unknown = unknown_names(card_text, state["place_names"])
if unknown:
warnings.append(f"unknown place names: {', '.join(unknown)}")
用作者的话说,这段校验正是"模型写了一张漂亮卡片"和"模型写了一张漂亮卡片、却把你送往一个根本不存在的公园"之间的分水岭。这其实是一套对抗幻觉的轻量级护栏,而非依赖模型本身的可靠性。
这套"双括号校验"机制在 LLM 应用工程中属于一种轻量级的"可审计输出"模式(auditable output)。核心思路是:与其在生成阶段阻止幻觉(极难),不如在生成后对高风险字段做事实核对。地名是典型的高风险字段——模型容易把相似的真实地名混淆,或基于训练数据中的模式凭空补全一个听起来合理的名字。通过要求模型用特殊符号标记所有地名,校验逻辑得以用正则表达式自动提取并与 OSM 数据做精确比对,整个过程不需要再调用一次 LLM 做二次判断,成本极低。这种"标记-提取-比对"的范式可以推广到任何需要验证模型输出中特定实体的场景,例如药品名称、法律条款编号或产品型号。
踩过的坑
真实工程记录往往比成功案例更有价值。作者坦诚列出了几个问题:
- 1B模型确实发明了地名。 在某一次运行中,
llama3.2:1b写出了一个 OSM 数据里不存在的名字。双括号校验捕捉到了它,记录警告而非直接交付——并非每次都发生,诚实的数字见下方表格。 - OSMnx 保存投影图时会丢失经纬度。 GPX 导出一度全是空坐标,直到加载器把节点的
x/y属性反投影回 WGS84 才解决。 - weasyprint 无法在 Windows 上安装。 作者改用 Edge 无头模式打印 HTML,把 PDF 当作尽力而为的输出。
模型对比:小模型到底够不够用
同样的请求、同样的起点、同样的地图,只换模型。由于路由器不含LLM,路线质量完全一致——真正有看点的是幻觉次数和卡片长度。
| 模型 | 配速理解 | 字数 | 幻觉地名 | 长度误差 | 峰值内存 | 耗时 |
|---|---|---|---|---|---|---|
qwen2.5:3b | 正常 | 36 | 0 | 0.3% | 259 MB | 106 s |
qwen2.5:1.5b | 偏快 | 69 | 0 | 4.4% | 260 MB | 16 s |
llama3.2:1b | 偏慢 | 56 | 0 | 9.5% | 274 MB | 76 s |
| 模板(无模型) | 正常 | 55 | 0 | 0.3% | 273 MB | 65 s |
三个模型都把模型内存控制在 0.5 GB 以下。3B 模型正确理解了配速,产出最短、最贴合目标的卡片;更小的模型会误读配速,从而影响目标长度和长度误差。这组数据说明:对于语言改写这类任务,小模型配合严格的事实约束完全可用,关键在于不要把它放在它不擅长的位置上。
整个项目的要义可以用作者的一句话概括:屏幕应该输掉这场比赛。 技术的终点不是更多的交互,而是让你更快地走进那片恰到好处的夕阳里。
相关推荐

Workbuddy零基础入门:桌面AI智能体如何落地工作流
Workbuddy桌面AI智能体零基础教程解读:从安装、积分领取到文件管理与自动化工作流搭建,对比CodeX的适用场景与成本差异,帮助职场人完成从AI提问者到AI管理者的思维转变。

OpenAI智能体新栈:计算机操作、决策API与超速工作流
OpenAI Dev Day发布智能体新栈:Computer Use操作速度超越普通人,Decisions API基于Luna实现极低延迟分类,Agents API开放同源计算机操作能力,GPT-6.1 Sol成本仅为Astra七分之一。本文梳理核心更新、实测数据与开发者落地要点。

梁文峰开源推理框架DeepInfo,硬刚美国禁令
DeepSeek在开源模型后再开源推理框架DeepInfo,包含GPU/CPU交叉流水线、小模型预判大模型复核、华为昇腾与英伟达芯片全面适配等技术,直面美国联邦禁令。本文解析其对AI产业落地的意义与开源策略。