
AI 智能体如何把「一句话」变成一张分析图目录1 引言空间分析的能力供给与使用门槛1.1 问题的工程化表述1.2 解法把「人话」翻译成「地图操作」2 总体架构从对话到成图的四层链路3 核心技术拆解3.1 意图理解与工具调用3.2 字段语义层翻译与防臆造校验3.3 低代码场景引擎能力注册与编排3.4 空间计算内核3.5 数据链路与持久化3.6 状态与反馈模型4 端到端链路县域企业影响分析平度市案例5 代码示例HeatmapAgent 的「感知—决策—执行—汇报」模式6 与常规 GIS 二次开发的对比7 工程取舍与可观测的边界8 结语产业分析真正的难点不在数据而在「从数据到地图」之间的那道鸿沟。本文从技术视角拆解——一个以 AI 智能体与低代码场景引擎为核心的空间分析它如何把一句句自然语言需求解析为可执行的图层、样式、分析与组件操作并实时呈现在地图上。全文以一次真实的县域产业分析为例覆盖意图理解、字段校验、能力编排、空间计算、数据持久化等关键链路。1 引言空间分析的能力供给与使用门槛1.1 问题的工程化表述「做业务的人不懂 GIS懂 GIS 的人不懂业务」是政务、园区、招商团队中常年存在的分工困境。从工程视角看一次空间分析交付至少包含五类环节数据准备、坐标基准对齐、图层组织、空间分析与统计、结果表达每一环都对应独立的专业工具与技能要求。以「龙头企业影响圈覆盖了多少上下游企业」这类问题为例完整链路包括坐标转换、图层叠加、缓冲区分析、覆盖统计与结果汇总。在常规工作流中这些环节需要数据工程师、GIS 工程师与业务人员多轮协作找数据、导出 Excel、提交开发、等待排期、反复沟通样式与口径最终拿到的往往还是一张可能已经过时的图。1.2 解法把「人话」翻译成「地图操作」不要求业务人员学习 GIS也不依赖开发排期而是把空间分析能力封装为可编排的能力原子由 AI 智能体将自然语言需求翻译为能力调用序列在低代码场景引擎中逐一执行并实时呈现。用户的核心动作只有一个——像聊天一样把分析需求说出来。2 总体架构从对话到成图的四层链路不是把 GIS 操作搬上对话框而是一套「会干活」的智能体。整体架构可抽象为四层交互层对话输入与地图画布双通道。用户以自然语言下达指令所有操作结果实时呈现在地图上发现偏差时用一句话即可纠正。意图理解层将中文需求解析为结构化操作指令包括意图识别、槽位抽取与参数映射输出标准化的工具调用序列。能力编排层按需组合图层、样式、分析、组件等十余项开箱即用能力复杂需求自动拆解为多步操作序列。数据与执行层低代码场景引擎执行操作支撑图层入库、字段查询、空间计算与数据库访问支持对话生成 SQL直接查询业务数据。四个层面共同保证一条设计原则每一步操作都可解释、可纠正、可持久化——工具调用过程在对话面板中可见操作结果即时上图最终成果可保存为场景与图层资产。3 核心技术拆解3.1 意图理解与工具调用将 GIS 操作封装为一组带参数的工具智能体通过工具调用完成「一句话 → 操作序列」的翻译。以界面中可见的调用为例修改图层样式update_layer_style参数包括 fullColor、borderColor、borderWidth、opacity多条件过滤filter_layer_data参数为图层 ID 与 conditions 数组多个条件以 AND 连接覆盖分析analyze_buffer_coverage可指定统计字段完成汇总。对于「过滤出注册资本大于 500、2025 年以后成立的企业」这类需求智能体将其拆解为两个条件注册资本大于 500 且成立日期不早于 2025以 AND 组合后调用 filter_layer_data。条件中的字段名与比较符由字段语义层提供而非模型自由生成。3.2 字段语义层翻译与防臆造校验自然语言中的业务字段如「注册资本」「成立日期」与数据表中的真实字段如 REGCAP、idate并非一一对应。若让模型直接生成字段名极易出现「臆造字段」。智能体的应对方式是字段先翻译、再校验解析上传文件时识别字段清单维护字段元数据工具调用前先经 list_layer_fields 预取目标图层的字段编码将需求中的业务字段映射为真实字段并在调用前校验参数合法性杜绝臆造字段名。这一机制同时服务两类场景过滤条件的构建以及覆盖分析中统计字段sumFields的指定。3.3 低代码场景引擎能力注册与编排低代码场景引擎沉淀了四类能力见表1。表1智能体核心能力清单能力类包含能力图层类图层列表、创建图层入库、向已有图层追加数据、字段清单翻译样式类属性修改、图标与位图替代、数据标签、分级分类着色地理分析类缓冲区分析、面转点、坐标系转换、缓冲区覆盖分析筛选与组件多条件过滤、属性框组件、图层数据过滤引擎按「能力注册表 组合编排」工作每条指令被解析为一个或多个能力调用能力之间可串联。例如覆盖分析并非单次调用需要先获取字段编码list_layer_fields再执行 analyze_buffer_coverage 并指定统计字段复杂分析因此可以被逐步执行、逐步确认。3.4 空间计算内核空间计算内核提供基础几何算子与分析算子两类能力坐标系转换支持 GCJ02 与 WGS84 等坐标系互转。企业坐标从 GCJ02 转成 WGS84 后点位与底图精准对齐解决「漂移」问题缓冲区分析以指定要素为中心、按半径生成缓冲区如 10 千米影响圈并支持保存为独立图层缓冲区覆盖分析统计缓冲区覆盖范围内的要素数量与字段汇总覆盖几个乡镇、多少企业、注册资本合计面转中心点将面要素如乡镇行政区划转换为中心点图层供后续分析使用分级分类着色按字段值分档映射色阶如按注册资本分 5 档绿、黄、蓝、橙、紫也支持按行政区编码分档着色热力渲染将点要素渲染为热力分布直观呈现区域密度差异。3.5 数据链路与持久化文件解析与入库上传 CSV 或 Excel 后智能体解析数据条数、识别要素类型点或面与字段清单数据量较大时地图预览仅渲染部分点位入库时以后端解析的全量数据为准保证统计口径完整。图层资产操作生成的临时图层如影响圈、中心点不会自动入库经用户确认后可保存为正式图层入库并返回图层 ID成为可复用的图层资产。场景存档场景记录图层集合、初始视图经纬度与层级与配置保存后整体复用下次分析从「继承」开始。对话式 SQL智能体可直接生成 SQL 查询数据库打通「数据—地图—分析—决策」整条链路。3.6 状态与反馈模型「前端暂存 显式持久化」的状态模型样式、过滤等配置暂存于前端点击「保存场景」后才持久化到后端。这一设计让操作具备即时的可逆性与可见性——每一步操作都在地图上即时呈现发现偏差可以用一句话纠正最终成果经确认后统一落库。4 端到端链路县域企业影响分析平度市案例以平度市为例将企业数据导入完整演示一次企业影响分析。全过程由对话驱动九步的指令、底层动作与呈现效果见表2。表2 九步分析的技术链路映射步骤用户指令节选底层动作地图呈现1 数据一键上图「把上传的文件生成新图层图层名称平度企业」文件解析4096 条点数据、字段识别、创建图层入库企业点位图层叠加行政底图2 数据真实叠加「企业坐标从 GCJ02 转成 WGS84」坐标系转换算子点位与底图精准对齐3 企业热力分布「生成热力图」热力渲染热力图层密度分布一目了然4 资本格局「按注册资本分 5 档上色」分级分类着色5 档色阶资本集聚格局一眼看清5 重点企业画像「注册资本大于 500、成立日期 ≥ 2025」filter_layer_data 多条件过滤AND 组合新设重点企业被单独圈出6 点选看详情点击任意企业属性框组件绑定要素查询工商信息卡片随点随看7 龙头企业影响圈以龙头公司为中心生成影响圈缓冲区分析示例半径 10 千米辐射圈瞬间生成8 龙头带动能力量化「统计影响圈覆盖几个乡镇、多少企业汇总注册资本」list_layer_fields analyze_buffer_coverage覆盖统计结果量化呈现9 成果固化复用「保存影响圈为正式图层」「面转中心点」「保存场景」临时图层转正式图层入库、面转点、场景序列化图层资产与场景存档步骤1 数据一键上图上传企业数据后智能体解析并识别为点数据同时列出字段清单一句「把上传的文件生成新图层图层名称平度企业」即完成图层创建与上图再上传乡镇行政区划行政底图就位。图1 数据解析与图层管理步骤2 数据真实叠加上传数据的坐标若为 GCJ02与 WGS84 底图存在偏移一句「企业坐标从 GCJ02 转成 WGS84」完成坐标系转换点位与底图精准对齐不再漂移。步骤3 企业热力分布「生成热力图」将点位渲染为热力分布企业密集区与稀疏区一眼看清图中右侧可见 update_layer_style 工具调用的参数fullColor、opacity 等。图2 热力分布与样式工具调用步骤4 资本格局「按注册资本分 5 档上色」绿、黄、蓝、橙、紫五档色阶呈现资本规模集聚格局乡镇层面再按行政编码分档着色区域差异一目了然。步骤5 重点企业画像通过多条件过滤「注册资本大于 500」且「成立日期 ≥ 2025」新设重点企业被单独圈出。条件以 AND 组合由 filter_layer_data 执行。图3 多条件过滤步骤6 点选看详情点击任意企业属性框自动弹出名称、注册资本、成立日、经营范围工商信息随点随看无需翻库。图4 点选详情步骤7 龙头企业影响圈以龙头公司为中心生成指定半径影响圈缓冲区分析瞬间给出辐射范围。步骤8 龙头带动能力量化「统计影响圈覆盖几个乡镇、多少企业汇总注册资本」覆盖分析自动统计并给出结果——覆盖多少家、分布在哪些乡镇、注册资本合计多少龙头带动能力被量化成一张可汇报的图。图5 覆盖分析步骤9 成果固化复用「把影响圈保存为正式图层」「乡镇面转中心点」「保存场景」分析结果沉淀为图层资产并随场景存档下次分析从「继承」开始。图6 场景保存与图层入库5 代码示例HeatmapAgent 的「感知—决策—执行—汇报」模式热力渲染是分析链路中最常用的能力之一。下面以一个基于高德地图AMap的 HeatmapAgent 为例说明智能体代码的组织方式run() 作为总入口内部按「感知取数—决策统计与分级—执行渲染—汇报日志与状态」四段式组织与智能体智能体的执行范式一致。class HeatmapAgent { constructor(){ this.map null; // AMap 实例 this.markers []; // 散点覆盖物 this.heat null; // 热力层 this.mode scatter; // scatter | heat | both this.radius 5; // 基础点半径 this.seed 20261013; this.stats null; } /* —— 总入口 —— */ async run(count, seed, fit){ const t0 performance.now(); this.setPill(running, 运行中); this.log(感知, 读取数据源 fmtNum(count) 个点位 CLUSTERS.length 个聚类中心, ); const points this.perceive(count, seed); this.log(决策, 强度归一化 → 5 级分档绿/黄/紫/蓝/深紫, ); const plan this.decide(points); this.log(执行, 模式 this.modeLabel() 基础半径 this.radius px (fit ? 自适应取景 : ), ); const err await this.act(plan, fit); const cost Math.round(performance.now() - t0); if(err){ this.setPill(fail, 失败); this.log(汇报, 执行失败 err.message, err); return { ok:false, error: err.message }; } this.stats Object.assign(plan.stats, { cost }); this.report(); this.renderStats(); this.setPill(done, 完成); this.log(汇报, 已完成 fmtNum(points.length) 点 / 聚类 plan.stats.clusterUsed / 耗时 cost ms, ok); return { ok:true }; } /* —— 感知取数此处为模拟数据可替换真实数据源 —— */ perceive(count, seed){ this.seed seed; return generatePoints(count, seed); } /* —— 决策统计 分级 —— */ decide(points){ const levelCount [0, 0, 0, 0, 0]; let minLng Infinity, maxLng -Infinity, minLat Infinity, maxLat -Infinity; const clusters new Set(); for(const p of points){ const lv levelOf(p.intensity); levelCount[lv.idx]; clusters.add(p.cluster); if(p.lng minLng) minLng p.lng; if(p.lng maxLng) maxLng p.lng; if(p.lat minLat) minLat p.lat; if(p.lat maxLat) maxLat p.lat; } const cLng (minLng maxLng) / 2, cLat (minLat maxLat) / 2; const kmPerDegLng 111.32 * Math.cos(cLat * Math.PI / 180); const rangeKm Math.round(Math.hypot((maxLng - minLng) * kmPerDegLng, (maxLat - minLat) * 111.32) / 2); return { points, stats: { count: points.length, clusterUsed: clusters.size, rangeKm, center: [cLng, cLat], levelCount, bounds: { minLng, maxLng, minLat, maxLat }, }}; } /* —— 执行渲染到高德地图演示模式走 Canvas —— */ async act(plan, fit){ try{ if(this.demoMode){ this._demoDraw(plan); return null; } if(!this.map) await this._initMap(); this.clearLayers(); if(this.mode ! heat) this._addScatter(plan); if(this.mode ! scatter) this._addHeat(plan); if(fit) this._fitView(plan.stats.bounds); return null; }catch(e){ return e; } } async _initMap(){ await loadAMap(); this.map new AMap.Map(map, { zoom: 10, center: [120.10, 36.60], mapStyle: amap://styles/whitesmoke, // 浅色底图贴近原图米色风格 }); this.map.addControl(new AMap.Scale()); this.map.addControl(new AMap.ToolBar({ position: { right: 10px, top: 10px } })); } clearLayers(){ if(this.markers.length){ this.map.remove(this.markers); this.markers []; } if(this.heat){ try{ this.heat.destroy(); }catch(e){ try{ this.heat.hide(); }catch(e2){} } this.heat null; } } _addScatter(plan){ const arr []; for(const p of plan.points){ const lv levelOf(p.intensity); const r Math.max(2.5, this.radius * (0.85 lv.idx * 0.22)); arr.push(new AMap.CircleMarker({ center: [p.lng, p.lat], radius: r, fillColor: lv.color, fillOpacity: 0.82, strokeColor: #ffffff, strokeWeight: 0.8, strokeOpacity: 0.65, zIndex: 40 lv.idx, })); } this.map.add(arr); this.markers arr; } _addHeat(plan){ this.heat new AMap.HeatMap(this.map, { radius: 26, opacity: [0, 0.72], gradient: { 0.0: #1fae62, 0.25: #f2b31a, 0.5: #9c5fb8, 0.75: #2e86de, 1.0: #5e2f8e, }, }); const data plan.points.map(p ({ lng: p.lng, lat: p.lat, count: Math.round(1 p.intensity * 9) })); this.heat.setDataSet({ data, max: 10 }); } _fitView(b){ const sw new AMap.LngLat(b.minLng, b.minLat); const ne new AMap.LngLat(b.maxLng, b.maxLat); this.map.setBounds(new AMap.Bounds(sw, ne), false, [48, 48, 48, 48]); } /* —— 汇报写日志与状态徽标 —— */ report(){ const s this.stats; $(mapBadge).innerHTML bHeatmapAgent/b · fmtNum(s.count) 个点位 / s.clusterUsed 个聚类 br覆盖半径约 s.rangeKm km · 模式 this.modeLabel() · 耗时 s.cost ms; } renderStats(){ const s this.stats; if(!s) return; $(stCount).textContent fmtNum(s.count); $(stCluster).textContent s.clusterUsed; $(stRange).textContent ~ s.rangeKm km; $(stCost).textContent s.cost ms; } modeLabel(){ return { scatter: 散点, heat: 热力, both: 混合 }[this.mode] || this.mode; } /* —— UI 辅助 —— */ setPill(state, text){ const pill $(agentPill); pill.classList.remove(running, done, fail); if(state ! idle) pill.classList.add(state); $(agentState).textContent text; } log(tag, msg, cls){ const ln document.createElement(div); ln.className ln (cls ? cls : ); const t new Date().toTimeString().slice(0, 8); ln.innerHTML span classtag tag /span span classtime t /span span classmsg/span; ln.querySelector(.msg).textContent msg; $(log).appendChild(ln); $(log).scrollTop $(log).scrollHeight; } }代码要点perceive 负责数据源读取本示例使用模拟数据可替换为真实数据源decide 完成强度归一化、5 级分档与范围统计act 根据模式散点、热力、混合渲染到地图支持自适应取景report 输出点位数量、聚类数、覆盖半径与耗时形成可观测的执行结果。6 与常规 GIS 二次开发的对比表3 常规 GIS 二次开发与智能体模式对比对比维度常规 GIS 二次开发智能体模式需求到成图需求评审—设计—开发—联调—发布对话直出实时成图技术门槛需 GIS 与开发技能自然语言即可变更成本需求变更重新排期一句话调整空间分析能力需自行集成算法与算子引擎内置缓冲区、覆盖分析、坐标转换等算子成果复用项目内定制复用成本高图层资产 场景存档随取随用数据接入ETL、服务发布文件上传解析、对话式 SQL适配对象开发团队业务、规划、招商一线人员7 工程取舍与可观测的边界从实现细节可以观察到几处明确的工程取舍渲染与入库解耦大数据量下地图预览采用抽样渲染入库与统计以后端全量数据为准取舍在于交互流畅性与数据完整性的平衡前端暂存、显式持久化操作配置先落前端保存场景后才写后端换取操作的即时可逆性代价是需要显式提交字段校验兜底通过预取字段清单约束模型输出降低大模型幻觉对数据语义的影响属于以确定性约束非确定性的典型做法歧义依赖对话澄清当指令存在多义性如多个同名图层实例时智能体需要选择或向用户确认说明自然语言驱动在复杂指令下仍有交互成本。在演进方向上值得关注更大数据量下的空间索引与聚合渲染、多轮任务的执行状态管理、图层与场景的权限与数据安全治理本节为作者基于可观测实现的分析不代表产品承诺。8 结语这场企业影响分析从上传数据到保存场景全流程由对话驱动完成。当「做图」不再依赖开发排期、不再要求 GIS 技能空间分析这件事就从「工程」变成了「对话」。门槛的降低并非能力的降级——专业能力被封装进可编排的场景引擎由智能体按需调用这正是 AI 低代码的核心价值。延伸阅读让 AI 写地图代码装个官方技能包值不值