资讯动态

大模型赋能三维地球:中文自然语言交互与工具调用实战

发布时间:2026/10/14 11:26:52 来源:尧图企业网站定制
最近几周我把一直在维护的三维地球可视化项目 Gods Eye View下文统一叫 GEV搭上了一条大模型链路用蓝耘平台上的 GLM-5.3 作为中文理解和推理中枢用 TRAE Work 工作台把所有地球操作编排成一套可被模型随时调用的工具。改完以后GEV 不再是一个只能点按钮、翻图层的“视觉玩具”你可以直接用中文问它“华东哪些城市空气质量小于50”“把人口密度最高的几个区域标出来”它不止会执行操作还会把公开数据背后的含义当场解释清楚。这篇文章不聊虚的我把整个改造过程从动机拆到架构再拆到具体配置和翻车记录。规划做数据可视化、GIS 平台或者正在折腾智能体Agent应用的同学应该能从中找到可以直接抄走的部分。1. 改造前的痛点与方案选型逻辑1.1 GEV 原本的交互瓶颈GEV 是我自己维护的一个浏览器端三维地球项目底层就是常见的那套 WebGL 地球渲染方案叠加了 GeoJSON 图层、飞行动画、标点、热力图这些模块。功能说多不多但也不算少可真正用起来一直有个尴尬所有操作都被塞进了传统 GUI 里。用户想看某项数据得先在图层列表找到对应的数据源再去右侧面板调时间范围、选统计口径最后地图上还不一定直接给出结论。我做过几轮用户反馈调查大部分人的反应是“地球很酷但不知道能干嘛”。这就是典型的“能力藏在交互后面”的问题。如果一个三维地球系统希望被非技术用户接受就必须把操作变成自然语言让人用提问的方式直接拿到结果。这也是我决定引入大模型的最初动机。1.2 为什么直接用大模型而不是传统 NLU在没上大模型之前我也认真考虑过传统 NLU 方案意图分类加槽位填充。比如定义“查询空气质量”的意图定义“城市”“指标”“阈值”这几个槽位再写规则去抽取。设计完就放弃了原因特别实际可扩展性太差。每加一种查询方式就要重写一轮意图和槽位还要准备大量训练语料碰上用户换一种说法比如“哪儿的空气比较好”和“帮我看看 AQI 低于 50 的城市”规则几乎要从头调。大模型方案完全绕开了这个问题。GLM-5.3 这类模型本身有很强的中文语义理解能力我只需要把 GE V 的操作能力声明成工具Tool模型就能自己判断该调用哪个、该传什么参数。更让我放心的是它不需要我维护一个庞大的意图树而是靠自然语言指令和工具描述动态完成映射。对于 GEV 这种“工具多、逻辑杂、但每个操作都相对独立”的系统这条路明显更合适。1.3 选型蓝耘 GLM-5.3 TRAE Work 的搭配理由模型我选择接蓝耘平台提供的 GLM-5.3 接口。原因有三第一接口是 OpenAI 兼容格式代码改造量小我本地已经有很多基于这种格式封装好的客户端第二GLM-5.3 的中文能力足够稳我在之前的几个文本处理项目里已经验证过它对中文长句和模糊表达的理解水平第三蓝耘平台在推理速度上比较适合这种“多轮工具调用”场景每轮对话可能要经历模型返回工具请求、执行工具、再回传结果的过程响应太慢会让整个体验崩掉。工作台我选了 TRAE Work。它的核心价值是把“模型、工具、会话、数据源”串成一个可视化的工作流我不需要自己从头写一个 Agent 循环。你可以把它理解成一个中间调度层前端把用户问题发给 TRAE WorkTRAE Work 调用 GLM-5.3 完成推理如果模型决定调工具TRAE Work 再转发到 GEV 暴露出来的 HTTP 接口拿到结果后继续交回模型生成最终回答。我自己的需求是快速迭代函数和提示词而不是重复造轮子所以 TRAE Work 这种编排型工具比让我手写一套 Agent 框架高效得多。2. 系统架构、公开数据与工具层设计2.1 整体调用链路改造后的 GEV 一共分成四个逻辑层前端展示层、工作台编排层、模型推理层、数据服务层。前端展示层就是 GEV 本身负责三维渲染和用户交互工作台编排层是 TRAE Work负责维护会话历史、决定何时执行工具、何时把结果交回模型模型推理层是蓝耘平台上的 GLM-5.3数据服务层则是 GEV 后端的一组 REST API负责返回地理边界、统计指标、标记点等实际数据。一条典型的链路长这样用户在页面输入中文问题TRAE Work 收到消息后把当前会话历史拼好连同工具定义一起发给 GLM-5.3。GLM-5.3 根据问题判断需要调用哪些工具返回一个结构化的工具调用请求比如“调用 search_region参数是华东”。TRAE Work 收到请求后调用 GEV 后端对应的 HTTP 接口得到结果。TRAE Work 把工具结果作为新的消息回传给 GLM-5.3。GLM-5.3 根据真实数据生成一段中文解释并且有可能再次请求调用 fly_to 或 add_markers 这类渲染工具。TRAE Work 执行完最终的渲染工具后把文本回答返回给前端展示。这一步跑通的关键在于模型不会主动去“碰”地球它只会提出“我想执行什么操作”真正动手的是 TRAE Work 和 GEV 后端。整个过程很像给模型装了两只手一只手查数据一只手操作地图。2.2 公开数据的接入与标准化要让地球“解释公开数据”首先得保证数据确实公开、口径统一。我目前接进来的主要是三类人口与经济统计数据、空气质量数据、基础地理边界数据。数据来源分散在开放统计网站、开放 API、以及一些现成的 GeoJSON 仓库里格式千奇百怪所以接入后第一步是标准化。我做了三层处理。第一层是字段名统一比如不管原始数据里叫 “AQI”、“aqi”、“空气质量指数”全部映射成aqi第二层是坐标系统一统一转到 WGS84 经纬度坐标避免在地球上偏移第三层是缺失值处理统计类数据遇到空值就先不加载等下次更新再补。标准化后的数据被整理成一张张简单的表存在 GEV 后端的内存缓存里每次启动时从静态文件加载总共也就几十 MB对这个项目来说完全够用。这里有个容易被忽略的小细节数据要有“时间戳”。同一个城市的空气质量指数每天都会变如果不带时间字段用户问“今天的情况”和“上周的情况”就会得到同一份结果非常不严谨。我在所有数据表的元信息里加了一个data_date字段模型回答时也会带上这个日期避免口误。2.3 工具函数到底怎么定义如果说模型是大脑工具就是手。手好不好用直接决定大脑能不能顺利完成动作。我给 GEV 设计了一批最小工具集第一批上线的是这几个search_region(region_name)按名称查区域返回中心坐标和边界范围。fly_to(latitude, longitude, altitude)让地球视角飞到指定坐标。add_markers(markers)在指定位置批量添加标记点。query_stat(region_list, indicator, condition)查询区域列表在某个指标上的数值支持条件过滤。explain_stat(indicator, values)对一组统计结果做口径解释返回适合展示的文本摘要。每个工具在 TRAE Work 里都用 JSON Schema 描述。以query_stat为例参数会被声明成下面的结构{ name: query_stat, description: 查询指定区域列表在某个统计指标上的数值支持按条件过滤。, parameters: { type: object, properties: { region_list: { type: array, items: {type: string}, description: 区域名称列表例如[\某市A\, \某市B\] }, indicator: { type: string, enum: [aqi, population, gdp], description: 统计指标代号aqi代表空气质量指数population代表人口gdp代表经济总量 }, condition: { type: string, description: 过滤条件例如\50\ 表示小于50 } }, required: [region_list, indicator] } }注意description一定要写得非常具体。模型不会读代码它只能通过这段文字理解参数含义。刚开始我偷懒写了一句“区域列表”结果模型经常把region_list传成一个字符串而不是数组排查了半天才发现是描述不够清晰。2.4 让模型“看懂”工具的描述工具定义写好了不意味着模型就会正确使用。我花在“工具说明书”上的时间比想象中多得多。核心原则有两个第一描述里要写清楚“什么时候用这个工具”第二要写清楚“这个工具不做什么”。比如fly_to如果只写“飞到指定坐标”模型可能会看到任何地理问题都想先调用它。我后来把描述改成了“当用户表达出希望改变视角、查看某个区域全貌时调用不要在执行查询前默认调用”。这个“负面约束”对准确率提升特别明显。另外工具之间要有关联逻辑。比如用户问“华东哪些城市空气质量低于 50”模型必须先调用search_region(华东)拿到城市列表再把列表传给query_stat。为了让模型理解这种顺序我在 TRAE Work 的提示词里叠加了一个 few-shot 示例把完整的“先查区域、再查指标、最后渲染”流程演示了一遍。模型对示例的模仿能力很强多给两三个高质量示例工具链路的稳定性会明显提高。3. 实操接入从模型配置到中文闭环3.1 配置 GLM-5.3 模型节点在 TRAE Work 里接入蓝耘的 GLM-5.3配置文件如下我用环境变量统一管理密钥import os model_config { base_url: os.getenv(LANYUN_BASE_URL), # 蓝耘平台提供的模型服务地址 api_key: os.getenv(LANYUN_API_KEY), model: glm-5.3, temperature: 0.1, max_tokens: 4096 }temperature我设置得比较低固定为 0.1。因为这种工具调用场景需要的是稳定、准确的输出不需要模型发挥创造力。如果温度太高模型可能会产生一些奇怪的工具参数比如把坐标写成“大约在100度附近”。在 TRAE Work 里我创建了一个“大模型节点”把上面的配置填进去同时把工具列表绑定到这个节点上。TRAE Work 会自动完成一件事每当模型返回tool_call类型的消息时工作台会解析出工具名和参数调用我已经注册好的工具节点然后把工具结果以tool角色的消息追加进会话再继续请求模型。这个循环不用我手动写代码但前提是工具节点返回的数据格式必须是干净的{ status: ok, result: ... }结构否则模型很容易被脏数据带偏。3.2 编写系统提示词和示例系统提示词是整个项目里改动最频繁的部分。我先写了一个基础版本规定了模型的角色、能力边界和回答风格再逐步叠加上下文要求。下面这个版本基本定型了你是 GEV 三维地球系统的中文数据助手。用户会通过中文向你询问地理分布、统计数据或空间变化问题。你必须根据用户意图调用提供的工具获取真实数据不得根据记忆编造统计数值。每次回答尽量简洁先给结论再补一句数据口径说明。如果用户要求查看地图调用 fly_to 或 add_markers如果用户想比较数值调用 query_stat如果用户只问概念性问题直接回答不必调用工具。这段提示词里最有用的是“必须根据用户意图调用提供的工具获取真实数据不得根据记忆编造统计数值”。有了这一句模型在遇到不太确定的数值时会倾向于先查工具而不是凭训练记忆猜一个数字。对于“解释公开数据”这个目标来说真实性是底线。除了系统提示词我还给 TRAE Work 准备了几个少样本对话示例。这些示例是调试工具调用顺序的关键。我选了三种最常见的情况单区域查询、多区域对比、条件筛选加地图标记。每个示例都展示完整的用户问题、模型应产生的工具调用序列、工具返回内容、最终回答。示例的质量决定了模型能不能举一反三。3.3 一次中文查询的完整流转用一个实际例子说明整体闭环。用户输入“华东哪几个城市空气质量在 50 以下帮我在地图上标出来。”第一步GLM-5.3 收到问题后发现需要先确定“华东”包含哪些城市于是返回{ tool_calls: [ { name: search_region, arguments: {\region_name\: \华东\} } ] }第二步TRAE Work 执行search_region从 GEV 后端拿到华东地区的城市概览列表包含城市名和经纬度回传给模型。第三步模型根据城市列表再次生成工具调用{ tool_calls: [ { name: query_stat, arguments: {\region_list\: [\某市A\, \某市B\, \某市C\], \indicator\: \aqi\, \condition\: \50\} } ] }第四步GEV 后端返回 AQI 数据模型筛选出低于 50 的城市接着生成add_markers调用把筛选结果对应的城市坐标传进去。第五步TRAE Work 执行add_markers地球视角自动飞向目标区域并落点。第六步模型生成最终文字回答“华东地区目前有 3 个城市空气质量指数低于 50分别是……地图上已经帮您标记出来了。”到这里一次完整的中文指令闭环就结束了。这个流程最让我意外的是模型并不需要我硬编码“华东到底包含哪些城市”它会主动通过工具去查。换句话说地理知识被解耦成了数据问题而不是模型记忆问题这大大降低了维护成本。3.4 多轮对话的上下文处理工具调用链路跑通之后另一个问题浮出水面多轮对话时上下文太长。比如用户连续问了好几个城市的数据每一轮工具返回的结果都会塞进历史消息里很快就把窗口占满。我在 TRAE Work 里加了一个轻量级的上下文压缩策略当历史消息超过一定长度时保留系统提示词、最近两轮用户问题、最近两轮工具结果把中间较早的工具结果替换成摘要。摘要由模型自己生成比如“用户之前查过华东和华南的AQI数据”。这个策略听起来简单实测效果却很不错既保住了最近会话的连续感又不会在长时间对话中越跑越慢。4. 实测效果与踩坑记录4.1 完整对话实测记录跑通流程之后我做了一轮接近真实用户习惯的测试。下面表格记录了几组典型问题、模型动作和最终表现用户输入模型动作结果“帮我看看华东哪些地方空气质量不错”search_region → query_stat → add_markers准确标出 3 个低 AQI 城市并解释筛选口径“飞到我上次看的那个城市”fly_to从会话历史里提取坐标视角正确飞向历史城市“人口和 GDP 有什么关系”explain_stat query_stat生成一段相关性说明地图上叠加两类数据“不用标点直接说结论”query_stat 但不调用 add_markers模型正确理解了“不渲染”的指令第四组尤其有意思。用户明确说了“不用标点”模型就没有调用渲染工具只返回了文本结论。这说明提示词里的“根据用户意图调用工具”起到了作用模型不再机械地一股脑把所有操作都执行一遍。4.2 踩坑一坐标参数类型错位第一次联调时模型调用fly_to返回的参数常常是{latitude: 31.23, longitude: 121.47}字符串类型的数字。GEV 后端收到字符串后直接报类型错误。查了半天发现是我在函数定义里把latitude和longitude的类型标成了string模型自然就按字符串传了。解决办法很简单把参数类型改成number并在描述里加了一句“经纬度为十进制度数数字类型”。从那以后模型再也没传过字符串。这个坑的经验是函数的 JSON Schema 就是模型看到的“API 文档”类型定义写错了模型一定会跟着错别指望它能自己纠错。4.3 踩坑二工具结果撑爆上下文有一次用户问“全国所有城市的空气质量”query_stat一次性返回了三百多行数据。TRAE Work 把这些数据原封不动塞给模型结果模型直接不知所措回答质量急剧下降而且后续对话明显卡顿。后来我给所有查询类工具加上了两个默认行为第一除非用户明确要求“全部”否则最多返回 50 条结果第二查询类接口默认返回统计摘要而不是原始明细只有在调用add_markers时才会返回带坐标的明细列表。这个调整既保证模型有足够信息生成回答又不会让上下文被原始数据淹没。4.4 踩坑三中文地名与普通名词歧义中文里有很多词既是普通词又是地名。测试时用户问“高山上的空气质量怎么样”模型第一反应是把search_region的参数传成了“高山”试图搜索一个地区但实际上用户可能只是在问字面意义上的高海拔山区。我尝试在提示词里加了一条规则当工具搜索词存在歧义时模型必须先向用户确认而不是直接执行。为了配合这条规则我给search_region增加了一个返回字段is_ambiguous当后端无法确定匹配对象时会返回多个候选模型会把候选列给用户选择。这个机制虽然多了一次交互但避免了很多误操作。4.5 踩坑四工具循环调用顺序失控还有一类问题是模型连续调用工具的顺序不稳定。比如它可能先调用add_markers再调用query_stat导致地图上已经标了标记但数据还没查完。原因是少样本示例里没有强调顺序模型自由发挥的空间太大。我在系统提示词里加了一句话“如果要同时完成查询和渲染必须先完成所有数据查询类工具再调用渲染类工具”这才稳定下来。这类顺序约束用大模型实现起来非常自然不需要写任何流程控制代码但必须在提示词里明确声明。5. 常见问题排查与优化清单5.1 问题排查速查表把这次改造中遇到的典型问题整理成一张表方便后续排查。症状可能原因解决办法模型不调用任何工具没在模型节点绑定工具列表或工具描述语义不清检查 TRAE Work 工具绑定重写工具 description工具参数类型总是错JSON Schema 类型定义错误或描述不具体按实际类型修正在描述里加参数格式说明模型回答内容与工具结果不一致工具结果格式不规范模型无法解析统一返回{status, result}结构加上单位字段连续对话越来越慢历史消息太长工具结果全量塞入上下文启用上下文压缩限制查询类工具返回条数地图位置偏移数据坐标系不一致统一转 WGS84并在加载时做坐标校验模型调用了不合适的工具提示词缺少“什么时候不调用”的负面约束在工具 description 里补充不适用场景加 few-shot 示例这张表是我后来做技术支持时的核心参考资料。大多数问题其实都不是模型能力问题而是工具定义或数据格式问题。5.2 性能、成本与稳定性的优化模型接入之后的性能问题主要集中在两个点接口响应速度和 token 消耗。响应速度上我用了两个手段一是把高频查询结果做本地缓存比如华东、华南这些常见区域的城市列表GEV 后端可以直接返回不需要每次都查库二是 TRAE Work 里给模型节点设置了超时重试避免单次请求卡死。Token 消耗上最大的开销来自工具定义本身。每个工具描述都要随每次请求发送给模型工具多了 token 占用就很可观。我做了两点优化合并功能相近的工具比如把add_markers和fly_to的触发条件写得更有区分度减少误调用另外对于用户没有主动要求的数据明细工具只返回摘要大幅降低回传 token。这个优化之后单次对话的 token 开销降到了原来的三分之一左右。5.3 下一步可以怎么扩展这次的改造解决的是“中文提问 数据解释 地图操作”这三件事但往后的扩展空间还很大。我下一步想做的有四个方向一是接入实时数据源让模型能解释当下正在发生变化的数据比如实时空气质量站点二是把语音识别加进来用户可以直接对地球说话三是做自定义图层模板用户用中文描述样式模型生成图层配置四是把工具调用权限细化不同角色只能调用部分工具避免误操作核心数据。每个方向其实都是在既有架构上加数据和加工具模型层的改动不会太大。这也是我觉得这套设计最值的地方一旦“模型 工具”的底座搭好了后续的功能扩展就是不断往工具层加新能力而不是推翻重来。最后分享一点我的个人体会这次改造里真正决定体验上限的并不是模型参数而是工具函数的设计。模型就像一位能力很强的实习生它不会用错工具但前提是你交给它的“工具说明书”足够清楚。千万别嫌写 description 麻烦描述里多写一句“什么时候不要用”比你在提示词里强调十句“请谨慎调用”都管用。另一个体会是数据口径一定要让模型在回答里展示出来。用户问空气质量光说“某个城市 AQI 是 35”是不够的带上“数据更新于某日某时”会让人更信服。GEV 现在回答每一个数据类问题时都会附带时间和来源说明这个小改动让整个系统的可信度上了一个台阶。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑