☰
大语言模型驱动的城市规划决策支持:从可解释推理到合规审查实践
2026/10/19 3:30:26 网站建设 项目流程

1. 项目拆解:城市规划决策支持中的“推理”到底指什么

我最近在做的模拟项目X,核心路子就是拿大语言模型去做城市规划决策支持里的“推理应用”。听着有点抽象,拆开看就一句话:让模型面对一个真实规划问题,不光要会检索,还要会判断、会推导、会给依据。比如某个地块的限高、容积率、退线三条控规条件摆在那,同时来了一份建筑方案,模型得回答:这个方案合不合规?不合规的话是怎么不合规?卡在哪个指标上?如果放宽其中一个条件,其他约束会怎样连锁变化?这些才是决策支持的日常。

之前我做过不少传统规划辅助工具,当时最大的体验是:规则越多,越难塞进代码。控制性详细规划文本动辄几十页,里面全是自然语言表达——“沿城市主干道第一界面建筑高度不宜超过24米”“幼儿园同步建设并无偿移交”“地下面积不计入容积率,但须满足防空要求”。这些句子里的例外、边界、前提,用传统程序做规则引擎会把人写疯掉。大语言模型的语义理解能力适合啃这种非结构化文本,但它天生会一本正经地胡说八道,直接上会翻车。项目里真正花时间的,是把模型“能理解”转化成“能证明”。

1.1 规划决策支持的真实痛点在哪里

规划决策支持系统并不是新鲜东西,很早就有研究者把数学模型、GIS工具、人口预测模型接进去,帮规划师算人口承载力、交通流量、容积率平衡。这些工具强在数值计算,弱在“条文理解”。现实工作里,一个地块的规划条件不是纯数字,而是由控规图则、城市设计导则、专项规划、地方标准共同夹逼出来的。数字之外,还有大量“宜”“不宜”“应”“不应”“不得”这类带情态动词的条文,它们不像算法公式那么清晰,需要结合规则解释。

我印象最深的一次是在某新区的模拟地块测试:控规条文写“低层、多层建筑退让绿线不少于5米,高层建筑退让绿线不少于8米”,同时还写“沿绿线一侧形成连续开放界面”。模型很容易只记住“不少于5米”,把它当成所有建筑的退让要求,忽略了后面“高层退让8米”的附加条件。这不是模型笨,而是规则本身存在分类分级嵌套——建筑类型、高度分档、空间界面要求混在一段话里。传统工具很难处理这种嵌套,大语言模型能处理,但前提是你要教会它把复杂条文拆成“条件-对象-数值-例外”。

另一个痛点是方案比选。规划决策不是只有“合规”“不合规”两种状态,更多时候是多方案权衡:A方案绿地率高但容积率偏低,B方案容积率达标但公共空间退让不够宽,每个方案都有取舍。决策支持要产出的是“为什么值得采用这个方案”的论证,而不是一个生硬的分数。以前这类论证只能靠规划师逐条手写,耗时又容易遗漏条款。大语言模型介入后,可以把多目标拆解,逐项列出满足哪些约束、牺牲哪些约束,形成一份可以被人工复核的比选说明。

1.2 “检索答案”和“推理输出”是两码事

有朋友一听就问:是不是用向量数据库做个检索增强生成,把规划条文搜出来拼给模型,让它照着念?这是最朴素的用法,也是很多项目交差的手段,但它离“决策支持”还有不小的距离。检索增强擅长解决“哪条规则对我适用”,不擅长解决“这些规则合在一起,我的方案能不能通过”。搜出来的条款是静止的,推理则是把条款做变量,代入具体方案去推演结果。

举个例子,同样一句“建筑限高60米”,放在不同场景下含义不一样。如果用地性质是二类居住用地,60米限高可能对应20层住区;如果位处机场净空保护区,60米可能还要附加绝对海拔控制;如果地块恰好位于山体周边,限高还要换算成相对坡脚的视线分析。检索只能把“60米”所在条文找出来,推理要做的则是判断:在这个地块里,“建筑高度”这个指标到底怎么计算?从正负零算起还是从室外地面算起?是否排除屋顶楼梯间和机房?这些细节散落在规范注释、图则说明、技术管理规定里,必须跨条文组合后形成结论。

所以我在项目里把“推理应用”定义为模型主动拆解问题。它需要先识别当前场景的关键实体——地块、方案、指标、规则;再在规则库中找出所有可能相关的条文,而不是只找关键词匹配的那一条;然后按逻辑顺序做约束判断;最后生成一个带依据链的结论。如果中间某一环缺失,模型应该明确说“我缺少这方面的依据”,而不是硬编出一个答案。这种可解释性比准确率更重要。

1.3 我给“推理应用”划的三类典型任务

在模拟项目X里,我没有一上来就做一个包罗万象的智能规划大脑,而是把任务收敛成三类,每一类有明确的输入输出和检查办法。

任务类型输入示例输出示例使用场景
约束合规检查地块规划指标、建筑方案主要参数是否合规,违反哪些条文,建议调整幅度方案初筛、报批前自查
方案生成建议用地范围、开发需求、上位规划要求若干可行的指标组合和布局建议前期策划、多情景测试
方案比选论证多个方案关键数据、决策偏好每个方案的达标情况、取舍点、推荐结论专家评审材料、领导汇报支撑

这三类任务里,模型承担的角色不太一样。合规检查更像“理解+分类”,模型把条文拆成判断条件,逐条核对;方案生成建议更像“约束求解”,模型在给定边界内做创造性生成,但生成结果必须能被规则引擎验证;方案比选论证则最依赖完整推理链,因为结论是开放性的,需要列举正反依据。项目里我优先做第一类和第三类,因为这两类效果容易度量——对不对看得见,改了多少有数字。方案生成建议留到后面再做,因为它的候选质量波动太大,需要更精细的评测机制。

2. 核心设计:把推理链路做成可校验的流水线

理解了“推理应用”要解决什么,接下来就是系统设计。这一步我踩过最大的坑,是以为把问题丢给大语言模型就能得到答案。实际上,纯闲聊式的调用连“数值计算”都不一定可靠,更不用说处理几十页控规文本了。如果一个结论没有经过外部校验,它在规划决策里就没有说服力。所以整个系统的核心设计思路是:模型负责“软推理”,代码负责“硬校验”,两边各展所长。

2.1 为什么不能直接把问题丢给聊天模型

先说几个真实翻车现场。我在测试时问过一个很简单的问题:“某建筑单栋高度62米,地块限高60米,是否合规?”模型回答“合规,因为建筑高度62小于等于限高60”,这属于基础比较错误,明显是数字没看仔细。还有一次,模型把“容积率2.8”当成“限高28米”,然后一本正经分析日照间距。这类问题根源在于大语言模型不是计算器,它的token粒度会导致数值模糊,尤其是多位数字、单位混用、小数点位变化时,出错率会明显升高。

更麻烦的是“看似严谨实则虚构”。模型在举推理依据时,会自己编造条文编号,比如“根据第7.2.3条,建筑退线距离不应小于10米”,可实际上原文本里根本没有这一条。对规划师来说,这种错误比直接说“不知道”更危险,因为决策文件一旦引用错误条文,责任归属就说不清了。

因此我在设计里确定了一条铁律:任何涉及数值比较、面积计算、条文编号引用的环节,都不允许模型直接输出“最终答案”了事。模型要做的是把问题解析成结构化参数,把推理过程写到步骤里,但最后的数值判断交给Python计算函数,条文核对交给检索模块。简单说,模型是提出假设和解释假设的助手,不是背书人。这样即使模型某个步骤说错了,校验模块也能追着打脸,避免错误结论一路贯彻到底。

2.2 规则知识注入:让模型真正读懂控规文本

大语言模型没有读过某个城市的控规之前,它只懂通用的规划常识,不懂本地特殊规定。所以知识注入是推理链路的前置条件。我采用的方法不是把所有条文一次性塞进系统提示词,而是先做“条文拆解”,把自然语言转成结构化条目,再按需检索。

拆解时我让模型帮我做一遍粗拆,但最终会由人工核对。具体做法是:把每段条文按“适用对象—约束指标—边界条件—例外情况—违例后果”整理成一条条记录。例如:

{ "rule_id": "A-12-3", "source_text": "高层建筑沿城市主干道一侧退让道路红线不少于15米。", "objects": ["高层建筑"], "condition": "沿城市主干道一侧", "metric": "退让道路红线距离", "operator": ">=", "threshold": 15, "unit": "米", "exception": "经规划论证并经批复的市政设施除外" }

这样一条条整理出来以后,放进向量数据库做语义检索,同时也保留一份JSON用于规则引擎做数值判断。模型做推理时,先从向量库里找相关条文,再把这些条文的原始文本和结构化字段都写进提示词。有人可能觉得结构化之后直接用规则引擎跑不就行了?但现实是很多条文没法完全结构化,比如“形成连续开放界面”“体现滨水景观特色”这类主观描述,必须依赖模型做语义理解。所以我的知识注入方案是“结构化为主、语义检索为辅”,两套机制互补。

2.3 五段式推理链路:从任务解析到结论复核

模拟项目X的推理链路被我固定成五步,每一步都有独立输出,方便人工介入和错误定位。这五步分别是:任务解析、规则检索、多步推理、数值校验、结论生成。

第一步任务解析,是把用户问题里的关键信息抽出来。比如用户说“帮我看看这个方案在A-04地块能不能落地”,系统要提取地块编号、方案数据、分析目标。这里我让模型输出一个JSON结构,包含用地面积、建筑面积、建筑高度、绿地率、车位数量等字段,如果用户没提供就直接给默认空值,不猜。

第二步规则检索,是根据地块属性和指标从知识库中召回候选条文。这里不是把检索结果一股脑塞给模型,而是按相关性排序后取前10条左右。第三步多步推理,模型把这10条作为依据,读一遍方案参数,然后一步一步写“因为……所以……”。“因果链”必须明确写在输出里。第四步数值校验,是把模型推理过程中提到的关键数值提取出来,交给规则引擎做“大于/小于/满足/不满足”的硬判断,如果模型算错,这一步会直接返回差异。

第五步结论生成,把校验正确的推理过程和规则引擎结果合并成一份结构化结论,附上引用的条文编号、原文摘录、计算过程。输出格式我固定设为JSON,方便后续接入报告系统或GIS工具。整套链路跑下来,你会明显感觉系统的答案不像聊天模型那么“顺滑”,但每一句话都有出处,规划师拿去做复核也不需要从头猜。

3. 实操过程:一个单地块合规审查Demo的完整实现

光说设计不够,我拿一个简化版的地块合规审查来演示完整实现过程。这个Demo是模拟项目X的第一阶段,目标很简单:输入一个地块的基础数据和一个建筑方案,输出一份合规审查结论。所有代码和数据我都做过脱敏,换成虚构样例,但流程是完整的。

3.1 准备数据:从控规文本到知识库

我先假设手上有一份“某高新片区控制性详细规划导则”,里面包含了地块A-04的主要控制指标:容积率上限2.8,建筑限高80米,绿地率下限30%,其中商业地块配建机动车位每100平方米建筑面积不少于0.8个。这些条文形式比较典型,我拿来做了第一批知识库。

操作上分了四步:

  1. 从PDF里抽出文本,保留图则之外的文字说明,表格转成Markdown格式。
  2. 用拆解模板把每条条文填充成刚才那种JSON结构,人工校对一遍。
  3. 将每条文按“条文原文、条文编号、适用地块、指标类型”生成语义文本,用向量模型做嵌入,存进向量数据库。
  4. 把结构化规则另存为一个Python字典文件,供规则引擎调用。

这里要提醒一个细节:规划文本经常有“旧版”和“新版”叠加的情况,比如某条规则在新版导则里改了,但旧版条文还挂在同一章里。知识库必须给每条规则打上版本号和生效日期,推理时优先取最新生效版本。我一开始没做版本控制,结果模型引用了旧条文,把本来违规的方案判断成了合规,差点被带偏。

3.2 提示词设计:让模型输出可解析的推理步骤

提示词是整个推理链路质量的关键。我用的系统提示词大概长这样:

你是一位城市规划决策支持助手。你擅长对建设方案进行合规性分析。 工作原则: 1. 只依据用户提供的规划条文和地块数据进行分析,不得使用记忆中的规则。 2. 必须逐步推理,每步先写“依据”,再写“判断”。 3. 涉及数值比较时,统一输出为数字,不要带单位。 4. 如果某个依据在输入中找不到,明确回答“未找到相关依据”,不要编造。 5. 最终输出必须符合给定的JSON结构。

用户输入部分,我把“地块指标”“方案数据”“相关条文”都放进去。这里的关键是“相关条文”必须由系统检索模块提前给出,而不是让模型自己回忆。否则模型会把某高校附近通用规范里的条文混进来,产生严重幻觉。少样本示例我给了一个典型违规案例,让模型看到“先逐条列依据,再给结论”的写法,效果比只给系统提示词稳定不少。

为了降低解析成本,我还让模型在输出时把“推理链”和“结论”分开存成两个字段。例如:

{ "reasoning_chain": [ {"step": 1, "basis": "A-04地块地上总建筑面积不超过26800平方米", "calculation": "12000 * 2.8 = 33600"}, {"step": 2, "basis": "方案地上总建筑面积为37200平方米", "calculation": "37200"}, {"step": 3, "judgment": "超出限值", "actual": 37200, "limit": 33600} ], "conclusion": { "is_compliant": false, "violations": [ {"indicator": "总建筑面积", "actual": 37200, "limit": 33600} ] } }

这样做的好处是,如果规则引擎发现“actual值算错”,我可以精确到第几步去修正,而不是把整段答案当废稿。

3.3 规则校验模块:用代码拦截幻觉

模型输出推理链后,我不会直接相信,而是进入规则校验模块。这个模块逻辑非常简单,就是用实数比较做复核。我从推理链里提取“指标名、实际值、限制值、约束类型”,然后跑一个函数族。

def check_leq(actual: float, limit: float) -> bool: return actual <= limit + 1e-6 def check_geq(actual: float, limit: float) -> bool: return actual >= limit - 1e-6 # 示例:容积率核验 rate_plan = 37200 / 12000 # 3.1 rate_limit = 2.8 passed = check_leq(rate_plan, rate_limit) # False

这个小模块把“计算容积率”这种算术问题从模型那里彻底拿走。模型只负责判断“容积率这个指标要不要查”,而真正算容积率、比大小的是Python,误差率立刻降得比纯LLM调用低一个数量级。我实测发现,加入这个模块后,最常见的“少看一位小数点”“把小于等于当大于等于”问题全部被拦住,剩下真正需要优化的是推理判断是否找对指标,比如漏掉了绿地率或车位配建数。

3.4 测试集与评测:不能只盯着正确率说事

我搭建了一个一百条左右的测试集,分成三类:明显合规、明显违规、边缘案例。明显合规和明显违规各占四十条,边缘案例占二十条。边缘案例包括“刚好等于限值的80米”“绿地率30%但局部塔楼阳台突出形成灰空间”“容积率2.8但车库顶板覆土算入绿地”这类需要人工斟酌的题目。

评测时,我记录三个指标:合规判断准确率、规则引用准确率、推理链完整率。合规判断准确率看最终“是否合规”结论对不对;规则引用准确率看引用的条文编号和原文是否为知识库真实内容;推理链完整率看模型是否把每一步依据都写出来,有没有跳步。

实测结果起来后,合规判断准确率很容易做到九成以上,但规则引用准确率一开始只有八成左右,主要问题还是编造条文。后来我把检索结果限制成“只允许引用Prompt中给出的条文ID”,规则引用准确率才提高到百分之九十八。边缘案例依然是重灾区,待改进空间很大。所以在项目里,边缘案例我设置为人工复核队列,不让模型单独下结论。

4. 踩坑实录和避坑建议

做完这个项目,最有价值的不是“能跑通”,而是一串具体到能复现的坑。我按问题类别整理成一张速查表,每个坑都对应实际解决方式。

4.1 五个高频问题汇总

问题现象根因分析排查思路解决方式
模型把“不超过”判断成“超过”条文里“大于”“小于”和“不大于”这类方向词处理混乱把运算符从文本里抽取出来单独校验在提示词里强制模型输出“operator”字段,由规则引擎统一判断
把“80米”误读成“8米”数值和单位分开后,单位丢失检查解析结果里的数字是否保留原始文本提示词要求输出数值和单位两个字段,单位不参与计算
引用了不存在的“第7.8.9条”模型在自由发挥在结论里抽取所有引用编号,和知识库主键比对输出格式限定为只允许引用输入中已有的条文ID
把废止的旧版规则取出来知识库没有版本控制检索结果里出现两个版本同编号条文每条规则标版本号,按最新版本优先召回
边缘案例上一会儿说合规一会儿说违规模型对边界条件理解不稳定检查推理链里的前提假设是否清楚进入人工复核队列,取消自动结论

我特别想强调第四行“旧版规则”的问题。很多控规修订不会整篇重写,而是“原第X条废止,新第X条生效”,但文本导出时新旧条款可能都在。这时候知识库不做版本隔离,模型就会随机选一条。我后来在检索阶段加了“有效期范围”过滤,并在提示词里写明“只能使用当前有效版本”。这是一个会被人忽略但极其重要的细节。

4.2 防幻觉的实操办法

模型幻觉这个问题,我在项目里磨合出几个比较土但很管用的办法。第一,强制按证据说话。任何结论字段后面都要跟着“依据条文编号”和“原文摘录”,如果模型找不到条文,就让它输出“未找到依据”。这样即使错误,也错得很透明。第二,给模型画“知识边界”。用户输入里明确写了“这里只有10条条文,超出范围的规则你不需要考虑”。这个约束能显著减少模型把自己训练语料里的城市规划规范搬过来发挥的情况。

第三,把“判断”和“计算”分离。模型可以判断“该地块需要配建停车位”,但不需要自己算车位数量。计算留给代码,模型只负责生成中间结论。第四,用一致性测试抓幻觉。同一个问题换几种措辞问三遍,如果三遍结论不一致,就说明模型在这个样本上不稳定,自动转入人工。这些办法单独用效果有限,合在一起能把可控性拉高很多。

4.3 如果你也想做这类系统,我的建议

从我实际经验看,第一次触碰“大语言模型+城市规划决策支持”时,不建议直接追求一个覆盖全城的复杂系统。先拿一个地块、三条规则、五十条测试数据做Demo,把“解析-检索-推理-校验-生成结论”这条链路真正跑通,比任何华丽架构都重要。因为只有链路跑通,你才会意识到把大语言模型放进决策支持里真正要解决的,不是“会不会回答问题”,而是“回答完能不能负责”。

我一开始就是太着急,想同时覆盖住宅、商业、工业、绿地四种用地场景,结果被各种用地分类规则和过渡期条款拖垮。后来把范围砍到单一类型建设用地,反而在两周内做出了可演示版本。再往外扩,也是一类一类往里加,每加一类就补一批测试集,而不是让模型去读全城规划文件。

最后再补一句:这类项目的产出不要只盯着聊天框。当模型能给出可复核的推理链,能被规则引擎拆穿错误,能与指标库、GIS工具打通时,它就不再是玩具。你把它放在报告生成、方案比选、初步合规筛查里,省下的是规划师最值钱的注意力。我个人体会是,宁可让回答慢一秒,也要让每一步推理有据可查。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询