写在前面

PineFlow 是我的本科毕业设计项目。这个过程中,Codex 给了我很多帮助。项目构思、架构设计、代码编写,都有它深度参与。不过,不过,PineFlow 仍然只是一个本科毕设阶段的探索项目,距离成熟产品还有不少差距。它更适合自动化许多目标明确、可以被结构化为工具调用的 GIS 处理任务。

项目演示视频我放在了 B 站:
https://www.bilibili.com/video/BV1N6Jg6xEYT

如果你想直接看效果,可以先看视频;项目已开源,GitHub 地址在文末。
请添加图片描述

从一个普通 GIS 任务说起

很多 GIS 分析任务,从原理上看并不复杂。

比如:

给学校图层做 500 米缓冲区,统计缓冲区内医院数量,并导出结果。

这个任务大概包含缓冲区分析、空间统计和结果导出。学过 GIS 的人一般都知道这些操作是什么。

但真正打开 QGIS 去做时,问题往往不只在“会不会空间分析”。

用户需要确认学校图层和医院图层是否已经加载,图层名字是什么,几何类型是否正确,坐标系能不能直接按米计算距离,缓冲区结果会不会为空,统计字段叫什么,输出文件放在哪里,是否会覆盖已有结果。

PineFlow 想解决的就是这个中间层问题。

用户仍然表达自己的分析目标,底层仍然使用成熟的 QGIS Processing / PyQGIS 能力。PineFlow 位于两者之间,负责把自然语言目标转成结构化工具调用,并在执行过程中持续检查状态、记录结果和处理风险。

为什么不直接让 AI 写 PyQGIS 脚本

一开始做这个项目时,一个很自然的方案是:让大模型根据用户需求生成一段 Python 脚本,然后直接运行。

这个方案看起来很直接。用户说要缓冲区,就生成缓冲区代码;用户说要裁剪,就生成裁剪代码;用户说要导出,就生成导出代码。

但 GIS 任务里有很多问题,不是代码语法问题,而是数据状态和空间语义问题

比如:

  • 用户说“500 米缓冲”,但输入图层可能是地理坐标系;
  • 用户说“按名称字段筛选”,但图层里可能没有这个字段;
  • 两个图层 CRS 不一致,空间关系判断可能不可靠;
  • 输入图层本身为空,后续结果自然也会为空;
  • 输出路径已经存在,直接执行可能覆盖旧结果;
  • 模型生成的图层名、字段名、文件路径可能只是猜的。

这些问题即使脚本语法正确,也可能让最终结果不可信。

更麻烦的是,GIS 分析里的错误有时不会表现成明显报错。系统可能成功生成了一个图层、一个文件、一组数字,但它的空间意义已经不对了。比如在地理坐标系下直接做缓冲,结果看起来有输出,但并不一定可靠。

所以 PineFlow 没有把“让模型临时写脚本”作为核心执行方式。

PineFlow 选择的是工具调用。

也就是说,先把常见 GIS 操作封装成结构化工具,例如加载数据、CSV 转点、缓冲区、裁剪、空间连接、重投影、结果导出等。模型负责根据任务目标和当前状态选择下一步工具,真正的空间处理仍然交给 QGIS Processing / PyQGIS。

这样做会牺牲一部分自由度,但换来的是更好的可控性。 工具的输入输出更明确,规则层可以提前检查风险,运行结果可以被记录,失败后也更容易保留上下文继续处理。

Claude Code 给我的启发

PineFlow 的设计参考了 Claude Code 这类 agentic coding tools 的工程思路,但参考的不是“让模型写代码”这件事本身。

我参考的是它背后的 agent harness 思路。

Claude Code 好用的地方在于,模型不是孤立回答问题,而是被放进一个有工具、有上下文、有反馈的执行环境里。它可以读文件、改文件、跑命令、看结果,再继续下一步。

这个执行环境通常可以理解为 agent harness

简单说,agent harness 就是给智能体搭的一套工作台。大模型本身擅长理解语言、判断意图、选择下一步,但它不能只靠一句回答完成真实任务。要让模型真正参与工作,就需要在模型外面提供工具、上下文、执行权限、运行反馈、错误信息和状态记录。

如果没有 harness,大模型面对用户请求时,通常只能生成一段文字、一份计划,或者一段代码。

有了 harness,模型才可以进入一个真实环境里行动:它知道当前环境是什么,知道自己能调用哪些工具,知道工具执行后发生了什么,也知道下一步应该如何根据反馈调整。

在 Claude Code 里,这个真实环境是代码仓库。

模型需要知道项目有哪些文件,哪些文件可以读写,能运行哪些命令,测试结果是什么,改动了哪些内容,哪里还报错,下一步应该继续修哪里。

PineFlow 想做的是把类似思路放到 GIS 场景里。

也就是说,把代码文件换成 GIS 图层,把测试结果换成工具运行结果,把命令行反馈换成 CRS、字段、要素数量(feature count)、输出文件和风险提示。两者表面上不一样,但都需要一套“模型可以行动、系统可以校验、过程可以追踪”的执行环境。

请添加图片描述

所以,PineFlow 不是简单地“把 LLM 接到 QGIS”。它更像是围绕 QGIS Processing / PyQGIS 搭建了一个面向 GIS 的 agent harness。

从 coding agent 到 GIS agent:PineFlow 的 harness 映射

如果把 PineFlow 和 Claude Code 放在一起看,它们处理的对象完全不同:一个面对代码,一个面对地理数据。

但它们背后的 agent harness 结构是相通的。

在 coding agent 里,模型要处理的是代码仓库里的文件、函数、依赖、命令、测试和错误信息。用户说“帮我修这个 bug”,模型不能只解释 bug 可能在哪里,它需要读文件、改代码、运行测试、根据报错继续修改。

在 GIS agent 里,模型要处理的是工作区里的图层、字段、坐标系、几何类型、空间关系、处理工具和输出结果。用户说“筛选河流附近的景点”,模型也不能只解释应该用缓冲区和空间筛选,它需要知道当前有没有河流图层和景点图层,距离是多少,图层 CRS 是否适合米制距离计算,执行后结果是否为空,以及这个结果能不能继续作为后续输入。

所以,PineFlow 参考 Claude Code 的地方,不是具体功能,而是下面这种映射关系:

在这里插入图片描述

类似方向给 PineFlow 的启发

在做 PineFlow 的过程中,我也看了一些自然语言 GIS、geospatial agent 和 autonomous GIS 相关的项目与研究。它们路线不同,但共同指向一个趋势:GIS 场景里的 AI 应用,正在从“回答问题”走向“调用工具、执行任务、观察结果、继续修正”。

有些工作更偏向 autonomous GIS,尝试让大模型自动完成数据获取、分析和可视化;有些工作更偏向代码执行,让模型生成或组织 Python 地理分析代码;也有一些工作关注结构化工具调用、多智能体协作和动态工具集。

这些方向对 PineFlow 都有启发,但 PineFlow 选择的路线更聚焦。

它没有追求一开始就覆盖完整 GIS,也没有把重点放在自由代码生成上,而是先围绕 QGIS Processing / PyQGIS,把一部分结构化程度较高的 GIS 处理任务整理成可调用、可检查、可追踪的工具流程。

也就是说,PineFlow 更关注的是:自然语言任务如何被约束成可靠的 QGIS 工具调用。

从这个角度看,PineFlow 不是单纯接入几个 QGIS API。它更像是在 QGIS Processing / PyQGIS 之上,搭建一个面向 GIS 任务的 agent harness:模型负责理解目标和选择下一步,工具负责执行,规则负责校验,状态负责记录上下文,运行结果再反馈给下一轮决策。

PineFlow 是怎么工作的

PineFlow 的执行流程可以概括为:

请添加图片描述

用户输入自然语言目标后,系统不会直接把所有步骤一次性写死,也不会把用户每一句话都交给模型去执行。

它首先要做的是判断这句话到底属于哪一类。

有些请求只是普通交流,比如“你好”;有些请求是状态查询,比如“当前有哪些图层”“上一步输出在哪里”“这个图层有哪些字段”;还有一些请求才是真正的 GIS 执行任务,比如“把这个 CSV 转成点图层”“筛选河流 500 米范围内的景点”“导出最终结果”。

这层请求分流很重要。

因为一个 GIS agent 不应该看到自然语言就盲目执行。如果用户只是查询当前状态,系统直接读取工作区信息就可以了;如果用户只是问一个 GIS 概念,也不需要启动完整的工具调用流程。只有当请求会改变工作区状态、生成新图层或导出结果时,才需要进入执行型流程。

进入执行流程后,PineFlow 会围绕当前 GIS 工作区一步一步推进。

它会读取当前有哪些图层、字段、坐标系和输出产物;根据用户目标选择一个合适的工具;在执行前检查参数、CRS、几何类型、字段和输出路径;执行工具后读取结果;再把新的图层、输出、风险和运行记录写回当前会话。

然后,系统再根据新的状态决定下一步。

这就是 PineFlow 的核心执行方式:边执行、边观察、边调整。

这个循环也是 agent harness 在 GIS 场景里的核心。模型不是一次性给出一个完整脚本,而是在一个有状态的环境里持续行动。每一次行动都不是凭空发生的,而是基于当前工作区、当前可见工具、规则检查和上一步返回的 observation,也就是工具执行后的运行观察。

之所以这样设计,是因为 GIS 任务里很多关键信息只有执行到某一步之后才能知道。

CSV 加载后,系统才知道里面到底有哪些字段;图层读进来后,系统才知道 CRS、几何类型和要素数量;缓冲区跑完后,系统才知道结果是不是为空;空间统计完成后,系统才知道输出字段和统计结果是否符合预期。

如果一开始就让模型把完整流程规划好,后面的步骤很容易建立在不确定甚至错误的假设上。计划里可能写着“使用 name 字段筛选”,但实际图层里没有这个字段;计划里可能写着“直接做 500 米缓冲”,但实际图层是地理坐标系;计划里可能写着“导出最终结果”,但前一步输出已经为空。

所以 PineFlow 更适合采用持续反馈的方式。系统每走一步,就把真实工具结果写回状态,再根据新的状态决定下一步。

PineFlow 的核心设计

理解 PineFlow 时,不能只看“模型能调用 QGIS 工具”这一点。

如果只是把几个 QGIS API 接到大模型后面,模型确实可以调用工具,但这个系统未必可靠。真正让 PineFlow 更接近一个 GIS agent harness 的,是它在模型外面组织了一整套执行环境。

这个执行环境大致包括:请求分流、语义工具、工具集按需暴露、领域指导、规则校验、工作区状态、等待恢复、运行生命周期,以及必要的前端展示和 QGIS 执行隔离。

请添加图片描述

它们分别解决不同问题,但目标是一致的:让模型不是凭空回答,而是在一个可约束、可观察、可恢复的 GIS 环境里完成任务。

请求分流:不是所有自然语言都进入执行流程

PineFlow 首先需要判断用户这句话到底要做什么。

如果用户问“现在有哪些图层”,这属于状态查询,系统应该读取当前工作区,而不是让模型随便调用一个 GIS 工具。

如果用户问“缓冲区是什么”,这属于普通 GIS 知识解释,也不需要进入完整的执行流程。

如果用户说“把这个 CSV 转成点图层”,这才是执行型任务,需要生成工具调用,检查字段和坐标系,并写回输出结果。

Semantic tools:把 QGIS 算法封装成可调用工具

QGIS Processing 里有大量算法,它们有自己的算法 ID 和参数结构,比如 native:buffernative:clipnative:joinattributesbylocation 等。

这些算法 ID 对程序来说很清楚,但和用户的自然语言目标之间还有一层距离。用户通常不会说“调用 native:joinattributesbylocation”,而是说“统计每个学校周边有多少医院”“筛选边界内的点”“把 CSV 经纬度转成点图层”。

PineFlow 的做法不是把底层算法列表原样丢给模型,而是在 QGIS Processing 之上封装一层 semantic tools。模型看到的是更接近任务动作的工具,例如 buffer_layercsv_to_pointsextract_by_locationjoin_by_location

semantic tool 是一层面向任务的工具接口。

模型可以看到更贴近任务语义的工具接口。比如“给道路图层做 500 米缓冲”更容易对应到 buffer_layer,而不是让模型直接理解 QGIS Processing 里的底层参数。

在模型侧,这层接口主要表现为工具名、工具说明和参数 schema;在后端侧,它对应的是参数校验、风险检查、算法映射和结果写回。完整的执行规则不需要都塞进模型上下文里。

这样一来,模型选择工具时面对的是“任务动作”,而不是一堆底层算法名。比如用户说“筛选边界内的点”,模型更容易对应到 extract_by_location,而不是在多个空间选择、空间查询和叠加分析算法之间猜。

同时,后端可以在 semantic tool 和 QGIS Processing 算法之间做稳定映射。模型只需要表达任务意图和必要参数,真正的算法 ID、参数转换、默认值、输出路径和结果登记,都由工具层完成。

也就是说,semantic tools 是自然语言目标和 QGIS 底层算法之间的接口层。它既让模型更容易理解工具,也让系统更容易做参数校验、风险控制和结果追踪。

ToolKit:工具不是一次性全部暴露

GIS 工具数量很多。如果一次性把所有工具都放进模型上下文里,模型不一定会更强,反而可能更容易混乱。

它可能在一大堆相似工具里选错,也可能因为上下文里工具太多而抓不住当前任务重点。

所以 PineFlow 采用了 ToolKit 按需暴露的思路。

可以把 ToolKit 理解成一组能力包。比如数据加载是一组能力,矢量分析是一组能力,空间叠加是一组能力,栅格处理又是另一组能力。系统不需要一开始就把所有工具都给模型,而是根据当前任务逐步打开相关工具集。

比如,用户刚开始只是上传数据,系统可能只需要暴露数据加载和图层检查相关工具。等用户提出“做缓冲区”“筛选边界内对象”“空间连接”这类任务时,再打开矢量分析或空间叠加相关工具。

这样做的目的不是限制能力,而是减少模型面对的噪声。

对 agent harness 来说,工具可见性本身就是一种控制。模型能调用什么,不应该是无限开放的,而应该和当前任务、当前阶段、当前工作区状态有关。

Skills:把 GIS 经验做成可加载的提示

除了 semantic tools 和 ToolKit,PineFlow 还整理了一层 GIS 领域经验提示,也就是 Skills。每个 Skill 是一个带 frontmatter 的 Markdown 文件。

这些 Skill 是给模型看的任务备忘录:当前任务应该关注哪些工作区信息、可能有哪些 GIS 风险、优先使用哪些工具策略、什么时候可以默认假设、什么时候必须向用户追问。

比如项目里有 meter_buffercsv_to_pointsboundary_filterspatial_joinraster_basicsexport_output 等 Skills。meter_buffer 会提示模型在米制缓冲前关注输入 CRS、图层范围和投影坐标系推荐;csv_to_points 会提示经纬度字段候选和 x/y 字段混淆风险;boundary_filter 会提示边界图层应是面图层、要检查 CRS 和空间范围是否重叠;spatial_join 会提示连接方向、字段冲突和一对多导致的要素数量膨胀。

PineFlow 并不会把所有 Skill 内容一次性塞进模型上下文。运行时会先根据用户请求、当前 workspace、可见工具和历史步骤做 skill suggestion;模型如果确实需要详细经验,再通过 load_skill 加载对应 Skill。Skill 还可以声明 requires_toolkits,例如米制缓冲会关联 vector_transformvector_analysis,栅格分析会关联 raster

这样做的好处是:**GIS 经验不用全部写死成硬规则,也不完全依赖模型自己记住。**Skills 负责提供领域提示;ToolKit 负责控制工具可见性。

规则校验:让模型行动有边界

GIS 自动化不能只看工具有没有跑成功,还要看这一步是否应该执行、参数是否完整、数据条件是否满足。

PineFlow 在模型和 QGIS runtime 之间放了一层 RulesGateway。模型可以通过 native tool calling 选择下一步工具,但这个 tool call 不会直接进入 QGIS 执行。系统会先检查它是否符合工具定义、语义约束和当前工作区状态。

这层检查大致分成几类。

第一类是 semantic validation。它关注工具调用本身是否成立:必填参数有没有缺失,参数类型是否正确,枚举值是否有效,工具 schema 是否匹配。比如缓冲区必须有输入图层和距离,按属性筛选必须有字段名和筛选条件,导出结果必须知道要导出哪个图层。

第二类是 preflight check。它关注当前 GIS 工作区是否支持这一步执行。比如用户说“500 米缓冲”,系统需要检查输入图层 CRS 是否适合米制距离计算;用户说“按名称字段筛选”,系统需要确认这个字段是否真的存在;用户要求空间连接,系统需要检查两个图层是否存在、几何类型是否合理、CRS 是否一致。

第三类是 resume rules。真实任务里经常会缺参数、需要确认,或者用户在中途补充信息。PineFlow 不会把这类情况简单当成失败,而是进入 pending / awaiting 状态,保存当前任务现场。用户补充距离、字段、目标图层或确认操作后,系统再把这些信息合并回原来的 run 继续执行。

如果没有这些边界,模型很容易为了完成任务而过度猜测。它可能猜一个字段名、猜一个图层名、猜一个输出路径,最后得到一个看起来完成、但实际不可靠的 GIS 结果。

所以,RulesGateway 的作用不是让系统显得复杂,而是把 GIS 分析里那些“看不见但很重要”的风险提前暴露出来。

能确定的,就继续执行;缺少必要信息的,就进入 pending 等待用户补充;存在明显风险的,就先提示或等待确认;工具真正执行失败时,失败 observation 也会被保留下来,作为下一轮修复或解释的依据。

工作区状态:让模型知道当前任务进行到哪里

一个 GIS 任务往往不是一句话就结束。用户可能先加载几个数据文件,然后问“这个图层有哪些字段”;接着说“用这个字段筛选一下”;再继续说“把刚才的结果和另一个图层做空间连接”;最后说“导出最终结果”。

如果系统每一轮都把请求当成全新的任务,就很难理解“这个字段”“刚才的结果”“最终结果”到底指什么。

所以 PineFlow 会维护当前会话的工作区状态。这个状态记录了当前有哪些图层、每个图层的来源路径、CRS、几何类型、字段、要素数量、哪些是原始输入、哪些是中间产物、哪些是最终输出,以及每一步工具调用产生了什么结果。

在执行时,PineFlow 会把这些信息整理成 GISStateTree,作为模型决策时的重要上下文。模型不是只看用户当前这一句话,而是结合当前 workspace state、可见 ToolKit、历史 observation 和 run context 来判断下一步应该调用什么工具。

这里还包括 artifact lineage,也就是产物来源关系。一个输出图层不只是一个文件路径,它还应该知道自己来自哪些输入图层、由哪个工具生成、关键参数是什么、输出要素数量是多少、后续还能不能继续作为输入。

这对 GIS 工作流很重要。因为流程一长,系统很快会产生多个中间图层和输出文件。如果没有状态记录,模型就容易把“刚才那个结果”“最终结果”“缓冲后的图层”混在一起,后续工具调用也会变得不可靠。

PineFlow 的 session/run 机制也是为了解决这个问题。session 记录一次对话和工作区的持续上下文;run 记录一次具体执行的生命周期、事件流、快照和输出结果。这样即使任务中途等待用户确认、执行失败,或者用户切换会话再回来,系统也能从已有状态继续推进,而不是重新开始。

所以,工作区状态就是 GIS agent 的上下文底座。它让模型知道当前任务走到了哪里,也让系统能够追踪每个图层和结果是怎么来的。

Pending / Resume:任务可以暂停、补充和继续

真实 GIS 任务里,缺参数和待确认情况很常见。

用户可能说“筛选河流附近的景点”,但没有说“附近”是多少米;用户可能说“用边界筛选”,但当前工作区里有多个边界图层;系统可能发现输出路径已经存在,需要确认是否覆盖;也可能发现当前 CRS 不适合距离分析,需要提示用户是否先重投影。

这个时候,任务不应该直接失败,也不应该让模型自己猜。

PineFlow 会把这类情况组织成 pending 状态,保留当前任务现场:原始请求是什么,已经识别出了哪些参数,缺少什么信息,有哪些候选对象,下一步需要用户确认什么。

用户补充信息后,系统再把新信息合并回原任务继续执行,而不是重新开始一段完全新的对话。这就是 resume 的意义:它让自然语言 GIS 任务不再是一次性成败,而是可以暂停、补充、确认和继续的过程

Run 生命周期:一次 GIS 执行不是普通聊天消息

PineFlow 把一次 GIS 执行看成一个有生命周期的 run,而不是一条普通聊天消息。

因为 GIS 执行可能运行一段时间,也可能中途等待用户确认,可能完成,可能失败,也可能被暂停或取消。所以一个 run 需要有状态,比如 running、awaiting_user、awaiting_confirmation、completed、failed、paused 或 cancelled。

这样前端才能展示真实进度,后端也能保存和恢复执行现场。对 GIS 任务来说,执行状态本身就是用户需要知道的信息。

前端展示:渲染结构化事实

PineFlow 的前端不应该只是一个聊天窗口。对于 GIS 任务来说,用户需要看到数据源、工具调用、风险提示、中间结果和最终输出,否则很难判断结果是否可信。

所以前端尽量展示后端记录的 run event、snapshot 和 artifact,而不是从模型最后的文字回答里猜测发生了什么。

QGIS runtime worker:把空间处理隔离出来

QGIS 的 Python 环境和普通 Python 服务环境并不完全一样。PineFlow 把 API 服务、会话管理、模型调用和规则校验放在常规 Python 环境里,真正需要 PyQGIS 的操作再交给 QGIS runtime worker 执行。

这样 harness 负责组织任务、管理状态和控制工具调用,QGIS runtime 负责真正处理空间数据。

PineFlow 目前能做什么

回到实际能力上,PineFlow 目前还不是一个成熟的 GIS Agent 产品。它的目标是把 QGIS Processing 中一批常用能力组织成可以由大模型调用、由规则系统校验、由工作区状态持续反馈的 GIS agentic workflow。

目前,PineFlow 已经封装了多类 GIS 工具能力,并按任务类型组织成 ToolKit。

ToolKit 主要能力
data_io 加载 vector/raster/CSV、CSV 转点、图层摘要、结果导出
vector_transform 重投影、几何修复、质心、面内点、多部件转单部件、几何简化
vector_analysis 缓冲区、融合、图层合并、属性筛选、空间连接、最近邻连接、面内点计数、字段计算
vector_overlay 裁剪、相交、差集、联合、对称差分、按空间关系提取
raster 栅格重投影、掩膜裁剪、范围裁剪、栅格计算、分区统计、栅格采样、矢量栅格化、栅格转面
qgis_generic 发现 QGIS Processing algorithms、查询算法帮助、必要时使用通用算法入口

所以,PineFlow 并不是只围绕少数几个固定工具写死流程。它更像是在 QGIS 之上加了一层 agent harness:模型负责根据用户目标选择下一步工具,ToolKit 控制当前可见能力,RulesGateway 和 preflight 检查参数、图层、字段、几何类型、CRS 和执行风险,QGIS runtime 负责真正处理数据,执行结果再作为 observation 回到下一轮决策。

例如,同样是“找出地铁站 500 米范围内的小区”,PineFlow 不只是调用一次缓冲区工具。它需要先理解任务目标,确认相关图层是否存在,检查距离分析是否适合按米计算,必要时重投影,然后生成缓冲区,再用空间关系提取或空间连接得到目标小区,最后导出结果。

又比如,用户想整理一批边界数据,系统可能会组合使用几何修复、重投影、裁剪、融合、字段计算和结果导出。用户想做栅格相关分析时,系统也可以进入 raster ToolKit,围绕裁剪、重投影、分区统计或栅格采样组织处理流程。

因此,PineFlow 目前更适合处理目标明确、步骤可以结构化、结果可以用图层或文件表达的 GIS 工作流。它还不能替代完整的 GIS 专家判断,也不是一个成熟的商用 GIS Agent 产品,但已经具备了一个 agentic GIS workflow 原型所需要的基本要素:工具集合、工具分组、领域 Skills、规则校验、QGIS runtime 执行、session/run 状态和 observation feedback。

PineFlow 和 QGIS

QGIS 提供成熟的空间数据处理能力,尤其是 QGIS Processing 和 PyQGIS 里的大量算法;PineFlow 则在这些能力之上,增加自然语言理解、工具选择、规则校验、工作区状态和执行反馈,让一部分 GIS 处理流程可以通过自然语言组织起来。

这并不意味着 PineFlow 要覆盖 QGIS 的全部能力。

QGIS 本身是一个完整的桌面 GIS 软件。它不仅包含空间处理算法,还包含地图浏览、图层管理、符号化、标注、版面布局、制图输出、交互式编辑、插件生态和人工检查流程。这些能力很多都依赖人的视觉判断和交互操作,很难简单地用一次或几次工具调用完全替代。

PineFlow 关注的是其中更适合自动化的一部分:那些目标明确、步骤可以结构化、参数可以检查、结果可以通过图层或文件表达的 GIS 处理任务。

比如,缓冲区、裁剪、空间连接、按属性筛选、按空间关系筛选、字段计算、重投影、几何修复、栅格裁剪、栅格计算、分区统计、结果导出等,都可以通过 QGIS Processing 或 PyQGIS 执行。PineFlow 做的事情,是把这些能力封装成模型可以调用的工具,并在工具调用前后加入工作区状态、规则校验、风险检查和执行反馈。

从用户角度看,PineFlow 可以自动化一部分“打开 QGIS、找到处理工具、选择输入图层、填写参数、运行算法、检查结果、继续下一步”的流程。

例如:

  • “把 CSV 经纬度转成点图层”适合 PineFlow;
  • “给道路图层做 500 米缓冲区”适合 PineFlow;
  • “筛选城市边界内的 POI”适合 PineFlow;
  • “统计每个社区内的医院数量”适合 PineFlow;
  • “把处理结果导出为 GeoPackage”适合 PineFlow。

但它目前不适合替代完整的 QGIS 桌面交互。

例如:

  • “设计一张漂亮的专题地图版面”更适合在 QGIS 中人工完成;
  • “根据审美调整符号颜色、标注位置和地图布局”更适合使用 QGIS 的可视化界面;
  • “人工检查遥感影像、手动编辑复杂边界、判断制图表达是否美观”也不是 PineFlow 当前重点解决的问题。

这个边界很重要:PineFlow 可以自动化一部分 GIS 处理分析任务,但不试图完整替代 QGIS 桌面软件。

当前不足和后续方向

PineFlow 目前已经具备了 agentic GIS workflow 原型的基本结构。但它离成熟产品还有明显距离。后续重点不只是“多接几个工具”,而是让执行链路更稳定、更可验证、更容易扩展。

第一是工具覆盖和工具质量。

PineFlow 已经按 ToolKit 封装了一批常见能力,但 QGIS Processing 的工具数量很多,目前覆盖的仍然只是常用子集。

后续扩展工具时,重点不应该是简单把更多 QGIS algorithm ID 暴露给模型,而是继续整理成 semantic tools。每个工具都需要有清楚的参数 schema、输入要求、输出策略、规则绑定和前端展示方式。

第二是结果验证。

现在 PineFlow 会记录 observation、输出图层、要素数量、CRS、路径和风险信息,但这还不等于系统真的理解“结果是否正确”。

后续需要加强 step-level verification。每类工具执行后,都应该更明确地检查输出是否为空、几何类型是否符合预期、feature count 是否异常、字段是否包含关键结果,以及是否产生了需要用户知道的质量风险。

第三是上下文管理。

GIS 工作流一长,图层、字段、历史步骤、输出文件和风险信息都会变多。PineFlow 已经开始做 context budget 和 step context pack,但这还只是第一步。

后续需要更明确地区分:哪些信息必须进入模型上下文,哪些信息只需要保存在 session/run snapshot 里,哪些信息可以在需要时再通过 inspect_workspace 读取。这样才能降低 token 消耗,也减少无关历史对模型决策的干扰。

第四是 pending / resume。

真实 GIS 任务里经常会出现缺参数、多个候选图层、CRS 风险、输出覆盖、字段不确定等情况。PineFlow 已经有 pending / awaiting 和 resume 机制,但后续还需要让这些状态更结构化。

比如要更清楚地区分:缺少必填参数、需要用户选择候选对象、存在风险但可确认继续、工具失败后需要修复、用户主动暂停或取消。这样用户补充信息后,系统才能更稳定地回到原任务继续执行。

第五是前端工作流展示。

PineFlow 的前端已经有会话列表、数据源、对话区、处理详情、结果和审查信息,但后续还可以进一步强化结构化事实展示。

GIS 用户关心的不只是模型最后说了什么,还包括调用了哪个工具、输入输出图层是什么、哪一步产生了风险、哪个结果是中间产物或最终产物、当前 run 是完成、等待确认还是失败。

这些后续方向其实都围绕同一个目标:让自然语言 GIS 自动化更稳定、更透明、更可控。

总结

PineFlow 的核心不是普通 GIS 问答,也不是让大模型生成一段 PyQGIS 脚本。

它更像是一次把 AI Agent 思路放进 GIS 场景里的尝试:在 QGIS Processing / PyQGIS 之上,构建一个有工具、有上下文、有校验、有反馈、有状态记录的自然语言执行环境。

在这个环境里,模型负责理解任务和选择下一步;工具负责真正执行 GIS 操作;规则负责检查参数、字段、CRS 和输出风险;工作区状态负责记录图层、中间产物和来源关系;run 生命周期负责支撑等待、确认、失败和恢复;前端则负责把过程展示给用户。

它还不成熟,也不能替代完整的 QGIS。但它验证了一件事:很多结构化的 GIS 处理任务,确实可以被组织成“自然语言目标 → 工具调用 → 状态反馈 → 结果输出”的执行流程。

这也是这个毕设项目最想表达的东西。

对我来说,PineFlow 最有价值的地方不在于它现在已经实现了多少 GIS 功能,而在于它验证了一种可能性:未来的 GIS 软件,也许不再只是一个工具集合,而会逐渐变成能够理解任务、组织工具并协助完成分析的智能系统。PineFlow 只是一次很小的尝试,但它让我们看到了这个方向的可能性。

参考链接:

项目开源地址:

songguo1/PineFlow

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐