公司动态
LLM空间推理能力差?从提示词到函数调用的工程纠正路径
在 Hacker News 上“How do you correct spatial reasoning of LLMs?” 这个讨论所反映的问题很多做 LLM 应用的团队都遇到过。文本摘要、意图识别、检索问答做得不错一旦进入导航指令、室内布局、CAD 辅助、自动排版等场景模型就可能把“左边”和“右边”搞混在坐标换算上给出错误结果甚至对简单二维网格里的移动路线都算不明白。空间推理能力弱不是某一类模型独有的缺点。它更接近大语言模型的基本短板模型通过文本 token 预测进行生成内部没有连续的坐标轴、没有视觉渲染器也没有可靠的几何计算引擎。它依赖训练数据中的语言模式来推断空间关系这种推断在简单情形下可以蒙对在稍微复杂或视角多变的情形下就会崩塌。这篇文章的目标不是推荐某种“万能模型”而是给出一条可复现的工程纠正路径。你会看到如何用少量测试题判断模型到底错在哪里如何用提示词、JSON 结构和确定性工具把空间推理从“让模型硬猜”变成“让模型调用代码计算并验证”以及在实际项目中接入校验、重试和权限控制时应该注意哪些坑。阅读前最好已经了解 LLM API 的基本调用方式和 function calling 的概念。1. 先理解 LLM 空间推理问题的本质才能决定该纠正什么1.1 空间推理出错时一般会出现哪些现象LLM 空间推理出问题通常表现为几类现象第一类是方向关系颠倒。比如“苹果在梨的右边梨在苹果的哪一边”模型可能直接回答“右边”。这个问题在二维平面上属于基础方向判断但模型如果没建立坐标系就只能靠语言模式猜测。第二类是坐标计算错误。比如“物体起点在坐标 (2,3)向右走 4 步再向下走 2 步最终坐标是多少”正确答案是 (6,1)。模型可能把“向下”误认为 y 坐标增加输出 (6,5)也可能把 x 和 y 搞混。第三类是二维或三维布局混淆。当问题同时包含多个物体、多层嵌套关系、前后关系时模型经常丢失约束。例如“书架一共有三层第一层有 5 本书第二层比第一层多 2 本第三层是第二层的 2 倍”这种问题已经接近数值推理但空间版本会变成“物体 A 在物体 B 的左前方物体 C 在物体 A 的右侧C 相对于 B 在哪里”此时模型需要同时维护多个坐标关系。第四类是信息不足时强行回答。现实空间问题经常缺少距离、尺寸或视角信息模型却倾向于给出一个确定答案而不是识别出“无法唯一确定”。这种问题的危害比算错坐标更隐蔽因为在生产环境里一个自信但错误的布局结果会直接导致后续决策错误。1.2 LLM 为什么会在这类任务上失效LLM 本质上是自回归语言模型每生成一个 token 都在做条件概率采样。它在生成“左”和“右”时不是在读取一张空间地图而是在训练数据形成的文本分布中选择更可能的词。训练语料里出现“A 在 B 左边C 在 A 右边”这种句式时模型会利用共现模式推断但共现模式不等于几何运算。空间推理高度依赖中间状态。人类解决这类问题会先在脑内建立坐标系把每个物体的位置记录成坐标再根据约束更新坐标。LLM 没有显式工作记忆上下文里即使已经写了“A 的坐标是 (-1,0)”后续生成也可能忽略这个状态。这是模型在路径规划和多物体排序中频繁出错的主要原因。另一个容易被忽略的因素是观察者视角。中文里“左边”可能指观察者的左边也可能指图中人物的左边。模型没有图像或实时环境只能依赖上下文猜测。如果不固定视角任何纠正策略都没有稳定基础。模型还会在 token 化过程中丢失数值结构。坐标“12”可能被拆成两个 token整数加减运算对 LLM 来说是概率任务而不是计算任务。即使参数量很大模型也只是在模仿“看起来像计算”的文本并不具备可验证的算术引擎。这也是为什么单纯把模型变大空间推理能力不一定同步提升。1.3 模型部署精度和空间推理能力不是一回事关于 LLM 的精度问题fp16、fp32、bf16开发者在部署模型时经常遇到。这些参数影响张量的存储精度、显存占用和推理速度但不改变模型的空间关系理解能力。一个在 fp16 下左右判断混乱的模型换成 bf16 或 fp32 加载后大概率还是左右混乱。因为问题不出在权重数值精度而在于任务没有被分解成可验证的步骤。fp16 与 bf16 在指数位和尾数位上的差异可能导致极端数值场景下的微小偏差例如很长坐标累加时结果不稳定但这和“模型是否理解左右相对关系”是两个维度。实际项目里要注意一个现象同一模型在不同推理引擎或不同精度下输出可能有细微波动尤其在 temperature 大于 0 时更明显。如果判断空间推理是否被修复必须固定精度、固定采样参数使用同一套测试集做批量回归否则很容易误判为“换精度后变好了”。注意不要看到模型在某个精度下答对了几道题就认为是精度修复了空间推理。先跑一轮至少 20 条测试题再下结论。2. 先做诊断用一组可量化的测试题找出模型的空间推理短板2.1 建议建立一个小型空间推理评测集纠正空间推理第一步不是改代码而是建立评测集。没有可重复的评估后续所有调整都无法判断是变好还是变坏。建议准备 5 个难度层每层准备 4 到 6 道题初期 20 到 30 条足够发现问题。测试题要覆盖方向、坐标、路径、多物体关系、信息不足五种情况。第一层基础方向判断“桌上有苹果和梨苹果在梨的右边梨在苹果的哪一边”这类题可以快速看模型是否掌握左右语义。第二层多物体排序“A 在 B 的左边C 在 B 的右边三个物体从左到右的顺序是什么”。第三层坐标换算“物体起点在坐标 (2,3)向右走 4 步再向下走 2 步最终坐标是多少”。第四层路径约束“在一个 5x5 网格中从 (0,0) 移动到 (4,4)每次只能向右或向上移动给出一种路径”。第五层信息不足题“物体 P 在 Q 的左前方Q 的坐标是 (3,3)P 的坐标是否唯一说明理由”。这类题用来判断模型是识别不确定性还是强行给答案。评分不必只判对错可以给错误分类例如方向反了、坐标计算错、输出格式错、信息不足判断失败。每个错误类型对应不同的修复策略。2.2 用最小脚本批量跑模型拿到测试集之后需要一个小脚本来批量调用 LLM。下面是通用接口调用示意不同服务商需要替换 endpoint、model 和鉴权方式。建议把 API key 存在环境变量里不要硬编码进代码。import os import requests def call_llm(prompt, model, endpoint_url, api_key): # endpoint_url 是服务商提供的 API 地址model 是模型名称 # api_key 建议从环境变量读取 resp requests.post( f{endpoint_url}/chat/completions, headers{Authorization: fBearer {api_key}}, json{ model: model, messages: [ { role: system, content: 你是一个空间推理助手回答要简洁并且严格按用户要求输出。, }, {role: user, content: prompt}, ], temperature: 0, }, timeout30, ) resp.raise_for_status() return resp.json()[choices][0][message][content]调用时设置temperature为 0是为了减少随机采样带来的输出波动。空间推理是确定性问题随机性越强越难评估真实能力。如果模型支持 JSON mode 或其他结构化输出参数可以在这一阶段先不开启因为你要看的是模型在自由输出下的原始水平。检查点很简单脚本能拿到回答并且每条输出都记录到结果表里定位到具体题目。先不急着优化把第一次结果整理成错误分类清单。2.3 结果记录与错误分类推荐用表格记录每一轮评测结果而不是只记录模型回答。留一条手工复核列因为模型可能答对了最终结果但中间推理完全错误。空间推理项目里中间过程往往比最终答案更重要。题目编号难度层模型输出是否通过错误类型人工备注01方向判断右边否左右反转没有定义视角02坐标换算(6,5)否坐标计算错误向下移动方向理解错03信息不足P 在 (2,2)否强行给出唯一答案缺少距离信息如果错误集中在“左右反转”修复重点是固定观察者视角如果集中在“坐标计算错误”修复重点是接入外部工具如果集中在“强行给出唯一答案”修复重点是让模型把问题转换为坐标系并识别约束不足。错误分类决定了后面每一步的重心。3. 不改模型也能改善空间推理提示结构与输出约束3.1 强制把空间问题转成坐标和步骤空间推理最常见的错误是模型跳过中间计算直接猜答案。一个有效的提示词策略是要求模型先定义坐标系再把每个空间描述转换成坐标约束。下面是一个提示词示例你是一个空间推理助手。对于