惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
The Last Watchdog
The Last Watchdog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
T
Troy Hunt's Blog
L
LINUX DO - 最新话题
C
Check Point Blog
T
Threat Research - Cisco Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
罗磊的独立博客
V
Vulnerabilities – Threatpost
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
J
Java Code Geeks
Apple Machine Learning Research
Apple Machine Learning Research
大猫的无限游戏
大猫的无限游戏
S
Security @ Cisco Blogs
IT之家
IT之家
T
The Exploit Database - CXSecurity.com
The GitHub Blog
The GitHub Blog
D
Docker
Engineering at Meta
Engineering at Meta
AWS News Blog
AWS News Blog
S
Security Affairs
U
Unit 42
P
Palo Alto Networks Blog
V
Visual Studio Blog
Y
Y Combinator Blog
D
DataBreaches.Net
Forbes - Security
Forbes - Security
阮一峰的网络日志
阮一峰的网络日志
美团技术团队
Security Latest
Security Latest
aimingoo的专栏
aimingoo的专栏
Simon Willison's Weblog
Simon Willison's Weblog
A
Arctic Wolf
博客园_首页
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
H
Hacker News: Front Page
博客园 - 司徒正美
博客园 - Franky
宝玉的分享
宝玉的分享
TaoSecurity Blog
TaoSecurity Blog
Latest news
Latest news
Scott Helme
Scott Helme
MongoDB | Blog
MongoDB | Blog
量子位
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
C
Cisco Blogs
P
Privacy International News Feed
Application and Cybersecurity Blog
Application and Cybersecurity Blog

博客园 - 我才是银古

第16章:常见问题、排错与最佳实践 第15章:扩展生态、MCAD 与外部集成 第12章:实战案例:机械结构与 3D 打印零件 第14章:构建、测试、调试与贡献流程 第13章:OpenSCAD 源码架构与核心执行流程 第11章:预览、渲染、网格精度与性能优化 第09章:列表推导、递归与算法建模 第08章:参数化零件库与复用设计 第10章:导入导出、命令行与自动化 第06章:CSG 布尔建模方法 第07章:二维图形、拉伸、旋转与投影 第05章:基础几何、坐标系与变换 第04章:参数、变量、函数、模块与作用域 OpenSCAD 教程目录 第03章:OpenSCAD 语言基础 第02章:安装、环境配置与开发工作流 第01章:OpenSCAD 项目全景与学习路线 第02章:源码获取、编译与开发环境配置 第01章:OCCT项目全景与学习路线 第18章:二次开发实战与综合案例 第18章:综合实战案例 第17章:数据交换与协同 第16章:源码架构与二次开发 第15章:插件与自定义工作台开发 第14章:Python脚本宏与自动化 第13章:FEM仿真分析 第12章:CAM数控加工 第11章:SurfaceMesh与逆向工程 第10章:Draft二维绘图与BIM建筑 第09章:工程图TechDraw 第07章:参数化表达式与Spreadsheet 第08章:装配设计Assembly 第06章:Part工作台与几何内核 第05章:PartDesign实体特征建模 第04章:草图Sketcher约束建模 第02章:安装版本与工作环境配置 第03章:界面工作台与基础操作 第01章:项目全景与学习路线 第十二章:插件开发、研究功能与最佳实践 第十章:定时任务与自动化(Cron) 第七章:技能、记忆与自学习闭环 第八章:MCP 集成与上下文文件 第六章:工具系统与终端后端 第五章:模型供应商与配置体系 Hermes Agent 教程目录 第十一章:语音、视觉、浏览器与子代理协作 第四章:CLI/TUI 与会话管理 第十二章:学习路线、实战方案与最佳实践 第十一章:源码结构、开发调试与插件开发 第十章:自动化、远程访问、日志与排障 第九章:Control UI、节点、Canvas 与语音能力 第七章:工具、技能、插件与能力扩展 第八章:安全模型、访问控制与沙箱实践 第六章:Agent 工作区、会话与多智能体路由 第五章:多通道消息接入与聊天平台配置 第四章:配置体系、模型接入与认证管理 第三章:Gateway 架构、协议与运行机制 第二章:安装、环境准备与快速上手 第一章:OpenClaw 项目概览与核心定位 oh-my-openagent 教程目录 09-命令模型回退与配置参考 10-实战案例最佳实践与故障排除 05-工作模式-Ultrawork-Prometheus-Atlas 08-Hooks与MCP系统 06-Category与Skill系统 07-核心工具链 04-智能体全景详解 03-安装与环境配置 02-整体架构与多模型编排机制 01-项目简介与核心理念 01-项目概览与学习路线 02-安装部署与工具适配 03-Skill机制与using-superpowers 05-TDD系统化调试与完成前验证 04-需求澄清方案设计与计划编写 07-并行智能体子智能体与Git-Worktree 第六章:代码审查、反馈处理与分支收尾 08-中国特色Skills与本土团队落地 09-MCP构建工作流执行与自定义Skill 第23章:FreeCAD-Python-API Clipper2 C# 源码解读教程 第19章:PolyTree 多边形树结构 第20章:实际应用与最佳实践 第18章:Minkowski 和与差 第17章:RectClip 矩形裁剪优化 第16章:ClipperOffset 偏移类详解 第15章:填充规则详解 第14章:布尔运算执行流程 第13章:ClipperD 浮点裁剪类 第11章:OutRec 与 OutPt 输出结构 第9章:Active 活动边结构 第10章:Vertex 顶点与 LocalMinima 局部极小值 第12章:Clipper64 裁剪类详解 第7章:高精度运算与128位整数 第8章:ClipperBase 基类详解 第5章:枚举类型与常量定义 第6章:InternalClipper 内部工具类 第2章:核心数据结构 - Point64、PointD 第3章:路径与多边形表示 - Path64、PathD、Paths64、PathsD 第4章:矩形边界 - Rect64、RectD
第五章:变量系统与步骤引用
我才是银古 · 2026-06-21 · via 博客园 - 我才是银古

第五章:变量系统与步骤引用

GeoPipeAgent 流水线中有两种核心数据传递机制:变量替换${var})和步骤引用$step-id)。本章深入解析这两种机制的工作原理和使用技巧。


5.1 变量替换:${var_name}

5.1.1 基本用法

pipeline.variables 中定义变量,在步骤 params 中用 ${变量名} 引用:

pipeline:
  variables:
    input_path: "data/roads.shp"
    buffer_dist: 500
    output_crs: "EPSG:4326"

  steps:
    - id: load
      use: io.read_vector
      params:
        path: "${input_path}"          # → "data/roads.shp"

    - id: buffer
      use: vector.buffer
      params:
        input: "$load"
        distance: "${buffer_dist}"     # → 500 (数值类型)

    - id: reproject
      use: vector.reproject
      params:
        input: "$buffer"
        target_crs: "${output_crs}"    # → "EPSG:4326"

5.1.2 类型保留

当整个参数值是单一 ${var} 引用时,变量的原始 Python 类型被保留:

variables:
  buffer_dist: 500          # int
  tolerance: 0.001          # float
  auto_fix: true            # bool
  fields: ["name", "type"]  # list

# 传入步骤时类型不变
params:
  distance: "${buffer_dist}"    # → 500 (int)
  tolerance: "${tolerance}"     # → 0.001 (float)
  auto_fix: "${auto_fix}"       # → True (bool)
  required_fields: "${fields}"  # → ["name", "type"] (list)

5.1.3 字符串插值

${var} 嵌入字符串中时,变量被转为字符串拼接:

variables:
  project: "highway-2024"
  suffix: ".geojson"

params:
  path: "output/${project}${suffix}"   # → "output/highway-2024.geojson"
  layer: "buffer_${project}"           # → "buffer_highway-2024"

5.1.4 通过 --var 在命令行覆盖

--var 参数以 key=value 格式传入,值始终是字符串。框架会尝试进行类型转换(字符串→数字/布尔):

# 整数
geopipe-agent run pipeline.yaml --var buffer_dist=1000

# 浮点数
geopipe-agent run pipeline.yaml --var tolerance=0.005

# 布尔值("true"/"1"/"yes" 转为 True)
geopipe-agent run pipeline.yaml --var auto_fix=true

# 字符串路径
geopipe-agent run pipeline.yaml --var input_path=data/new_roads.shp

# 多个变量
geopipe-agent run pipeline.yaml \
    --var input_path=data/new.shp \
    --var buffer_dist=200 \
    --var output_path=output/new_buffer.geojson

注意:通过 --var 传入的值优先于 YAML 文件中 variables 的定义,且会修改 PipelineDefinition.variables 字典,影响所有引用该变量的步骤。


5.2 步骤引用:$step-id$step-id.attr

5.2.1 步骤引用基础

步骤引用用于将一个步骤的输出传递给后续步骤的参数。格式:

语法 等价形式 含义
$step-id $step-id.output 步骤的主输出(StepResult.output
$step-id.output 显式写法 同上
$step-id.stats 步骤的 stats 字典整体
$step-id.feature_count stats 中的 feature_count
$step-id.issues_count stats 中的 issues_count 值(QC 步骤)
$step-id.issues_gdf QC 步骤的问题要素 GeoDataFrame
steps:
  - id: load-data
    use: io.read_vector
    params:
      path: "data/roads.shp"

  - id: buffer
    use: vector.buffer
    params:
      input: "$load-data"           # 等价于 $load-data.output
      distance: 500

  - id: save
    use: io.write_vector
    params:
      input: "$buffer"              # 等价于 $buffer.output
      path: "output/result.geojson"

5.2.2 访问统计属性

每个步骤执行后,StepResult.stats 字典的键可直接作为引用属性访问:

steps:
  - id: load-data
    use: io.read_vector
    params:
      path: "data/roads.shp"

  - id: check-geometry
    use: qc.geometry_validity
    params:
      input: "$load-data"
      auto_fix: false

  - id: auto-fix
    use: qc.geometry_validity
    params:
      input: "$load-data"
      auto_fix: true
    # 只有当几何问题数 > 0 时才执行
    when: "$check-geometry.issues_count > 0"

outputs:
  # 在 outputs 中引用统计数据
  total_features: "$load-data.feature_count"   # stats.feature_count
  bad_geometry:   "$check-geometry.issues_count"

5.2.3 StepResult 结构

理解步骤引用需要了解 StepResult 的数据结构:

@dataclass
class StepResult:
    output: Any = None          # 主输出(GeoDataFrame、文件路径等)
    stats: dict = {}            # 统计信息(feature_count、crs 等)
    metadata: dict = {}         # 元数据(driver、bands 等)
    issues: list[QcIssue] = []  # QC 问题列表(仅 QC 步骤填充)

属性访问规则

  • $step.outputresult.output
  • $step.statsresult.stats(返回整个 stats 字典)
  • $step.feature_countresult.stats["feature_count"](先查 stats)
  • $step.crsresult.stats["crs"](然后查 metadata)
  • 若以上都找不到,抛出 VariableResolutionError

5.2.4 各类步骤的输出结构

IO 步骤(io.read_vector)

StepResult(
    output = GeoDataFrame,      # 读取的地理数据
    stats = {
        "feature_count": int,
        "crs": str,
        "geometry_types": list,
        "columns": list,
    }
)

引用示例:

  • $load.output → GeoDataFrame(传给下一步的 input
  • $load.feature_count → 要素数量
  • $load.columns → 属性字段列表

矢量步骤(vector.buffer)

StepResult(
    output = GeoDataFrame,      # 缓冲区结果 GeoDataFrame
    stats = {
        "total_area": float,    # 缓冲区总面积
    }
)

IO 写入步骤(io.write_vector)

StepResult(
    output = str,               # 输出文件路径(字符串)
    stats = {
        "feature_count": int,
        "output_path": str,
        "format": str,
    }
)

QC 步骤(qc.geometry_validity)

StepResult(
    output = GeoDataFrame,      # 原始输入数据(透传)
    stats = {
        "issues_count": int,
        "valid_count": int,
        "issues_by_severity": dict,
    },
    issues = [QcIssue, ...]    # 问题列表
)

QC 步骤专有属性:

  • $check.issues_count → 问题数量
  • $check.issues_gdf → 包含问题要素的 GeoDataFrame
  • $check.issues → QcIssue 对象列表(不可直接序列化,一般不在 YAML 中引用)

5.3 引用解析顺序与规则

context.py 中的引用解析逻辑:

参数值处理顺序:
1. 非字符串值 → 直接返回(保持原类型)
2. 以 "$" 开头且非 "${" → 步骤引用
   2a. "$step-id"       → 查找 step-id 的 output
   2b. "$step-id.attr"  → 查找 step-id 的 stats/metadata 中的 attr
3. 包含 "${" → 变量替换
   3a. 整个值是 "${var}" → 返回原始类型
   3b. "${var}" 嵌入字符串 → 字符串插值
4. 其他 → 原样返回

注意事项

  • 步骤引用只能引用已执行步骤的输出,不能向前引用
  • 步骤 ID 中的连字符 - 在引用中需要保留($load-roads,不能写成 $load_roads
  • $step-id.attr. 只分割第一个,因此 $step-id.stats.feature_count 会尝试访问 stats 中的 stats.feature_count 键(通常不存在),正确写法是 $step-id.feature_count(直接访问 stats 键)

5.4 在 when 条件中使用引用

when 表达式也支持步骤引用和变量替换:

steps:
  - id: check-issues
    use: qc.geometry_validity
    params:
      input: "$load-data"
      auto_fix: false

  # 条件1:基于步骤 stats 属性
  - id: fix-issues
    use: qc.geometry_validity
    params:
      input: "$load-data"
      auto_fix: true
    when: "$check-issues.issues_count > 0"

  # 条件2:基于变量
  - id: simplify
    use: vector.simplify
    params:
      input: "$fix-issues"
      tolerance: 10
    when: "${enable_simplify} == true"

  # 条件3:复合条件
  - id: strict-fix
    use: qc.geometry_validity
    params:
      input: "$load-data"
      auto_fix: true
      severity: "error"
    when: "$check-issues.issues_count > 10 and ${strict_mode} == true"

5.5 在 outputs 中使用引用

outputs 声明支持完整的引用语法:

outputs:
  final_result: "$save-result"            # 输出文件路径
  feature_count: "$buffer.feature_count"  # 缓冲区要素数
  total_area: "$buffer.total_area"        # 缓冲区总面积
  crs: "$reproject.crs"                   # 最终坐标系
  qc_issues: "$check-geo.issues_count"    # 质检问题数量

这些值出现在 JSON 报告的 outputs 节中,可供 AI 或下游系统提取。


5.6 嵌套参数中的引用

对于接受字典或列表类型参数的步骤,引用也可以出现在嵌套结构中:

# 假设某步骤接受字典参数
params:
  config:
    input: "$load-data"          # 嵌套字典中的引用
    crs: "${output_crs}"
  field_list:
    - "$load-data.columns"       # 列表中的引用(按实际步骤支持情况)

5.7 常见引用错误

错误 1:引用未执行的步骤

steps:
  - id: buffer
    use: vector.buffer
    params:
      input: "$load-data"   # ❌ load-data 在 buffer 之后,尚未执行

  - id: load-data
    use: io.read_vector
    params: { path: "data.shp" }

错误 2:引用不存在的属性

- id: process
  use: vector.buffer
  params:
    distance: "$load-data.record_count"  # ❌ io.read_vector 没有 record_count 属性
                                          # ✅ 应改为 feature_count

错误 3:ID 拼写不一致

steps:
  - id: load-roads       # ID 使用连字符

  - id: buffer
    params:
      input: "$load_roads"  # ❌ 使用了下划线,与 ID 不符
      input: "$load-roads"  # ✅ 正确

5.8 本章小结

本章深入讲解了 GeoPipeAgent 的两种核心数据传递机制:

  1. 变量替换 ${var}:引用 variables 中的值,整个值时保留类型,嵌入字符串时做字符串插值
  2. 步骤引用 $step-id$step-id$step-id.output 的简写,.attr 可访问 stats/metadata 键
  3. 类型保留:单一 ${var} 引用保留原始 Python 类型,确保步骤参数类型正确
  4. when 条件:支持完整的引用语法,通过 AST 白名单安全求值
  5. StepResult 结构:理解 output/stats/metadata/issues 各字段是正确使用引用的基础

下一章将讲解条件执行、自动重试和错误处理策略的详细用法。


导航← 第四章:YAML 流水线格式第六章:条件执行与错误策略 →