使用内存层映射以减少LLM超载
如果你要求RidgeText生成一个叠加有小径的火灾周界地图,现在的响应包括一个带有火灾周界和你的步道路线的地图,所有内容都渲染成一张图片并通过短信发送。火灾周界(阴影多边形)叠加有步道路线。每个这些都是一个独立的层,在地图渲染之前排队。在开发这个分层特性时,我们意识到一件事:不能通过LLM工具调用传递GeoJSON,因为数据量实在太大,无法有用。 背景:RidgeText被构建为LLM之上的一个编排层。用户通过短信进行互动——没有应用程序,没有用户界面——LLM处理自然语言理解,决定调用哪些工具,并组合出清晰的响应返回。它不是一个规则引擎;LLM在每一步都做出判断。这种非确定性是对话的一个特性,但为功能创造了约束:LLM涉及的任何事物都需要对变化具有韧性。如果一个工具返回的数据量过大,LLM可能会截断、虚构摘要或无声失败。如果一个工具的接口模糊,LLM可能会错误调用。良好的工具设计意味着塑造LLM所见的内容,以便合理响应的范围都能导致正确的结果。地图生成是一个显而易见需要关注的例子。 幼稚的方法(以及为什么它失败)明显的实现是让一个工具获取火灾数据并将其返回给LLM,然后第二个工具接受这些数据并渲染地图。类似于:LLM调用get_wildfire_data() → 接收到2,000个火灾多边形作为GeoJSON,LLM调用render_map(geojson: ...) → 传递该GeoJSON。 实际上,一个适度的火灾数据集是50–500KB的原始GeoJSON。一个token大约是4字节,所以500KB大约是125,000个tokens——大于许多上下文窗口,即使适合也很昂贵。LLM成为一个无法推理的数据管道。它无法简化GeoJSON,无法验证它,并且每次都要支付完整的上下文成本。 层优先模式:我们的解决方案反映了Mapbox本身的工作方式:层是独立添加并在渲染时合成的。每个获取数据的工具在服务器端存储其结果,只返回一个轻量级的确认:LLM调用retrieve_wildfire_layer(location: "Cascades") → { status: "queued", layerId: "wildfires-0", featureCount: 847 },LLM调用retrieve_trail_layer(trailName: "PCT Section J") → { status: "queued", layerId: "trail-1", featureCount: 1 },LLM调用generate_map() → { mapUrl: "https://storage.../map-abc123.jpg" }。 LLM的上下文永远只看到确认——微小的JSON对象。GeoJSON存储在服务器内存中,直到generate_map排空队列并合成图片。 层堆栈:每个retrieve_*调用都附加到请求上下文中按顺序排列的层数组:interface MapLayer { type : 'wildfire-perimeters' | 'fire-hotspots' | 'trail' | 'heatmap' | ...; data : GeoJSON.FeatureCollection; style : LayerStyle; } // 处理中的队列——在一次LLM回合的生命周期内存在const layerQueue : MapLayer [] = []; generate_map按插入顺序渲染它们——就像Mapbox的层堆栈,较早的层位于较晚的层之下。LLM通过调用工具的顺序隐式控制排序:如果在retrieve_trail之前调用retrieve_satellite_base,步道将绘制在卫星图像的顶部。 我们的实现使用了一个以会话ID为键的进程内Map,具有30分钟的TTL,因此排队但未渲染的层会自动逐出,而不是积累。具体机制并不是重点——Redis、数据库或请求范围的上下文对象都可以工作。重要的是数据存在于LLM的上下文窗口之外。 为什么这与Mapbox相似:Mapbox的核心模型是:源提供数据,层定义如何渲染数据,层根据声明顺序进行组合。我们的服务器端队列是相同的抽象,只是没有浏览器。 值得精确说明“Mapbox”在我们的渲染器中的意思。我们获取Mapbox静态API图像作为基础瓦片——地形、道路、标签——然后使用画布在其上合成数据层。Mapbox本身从未看到GeoJSON;它只提供背景。我们存储的层描述符遵循Mapbox的格式并不是因为渲染器需要它,而是作为一个深思熟虑的前瞻性选择。如果我们将来超越静态瓦片——用于3D地形、复杂混合或动画层——我们可以将渲染器替换为在Playwright浏览器中运行的无头Mapbox GL JS实例。该渲染器将消耗完全相同的层队列,而无需对工具或LLM的接口进行任何更改。成本和速度的特征也会发生变化:基于JavaScript的渲染器可以跨请求缓存瓦片和GL资产,潜在地降低每张地图的成本并改善冷启动延迟,与每张地图都进行一次新的静态API调用相比。
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡