Agent Workflow 学习向:Code 节点,比模板更强的变量加工

上一篇:浏览器联调台:编辑图 JSON、一点运行、看 events

相关:02 最小工作流 API

示例仓库:flow-forge

本篇讲:工作流里新增第四种节点 Code------在图里写一小段 Python 逻辑加工变量,比 Template 的「填空成句」更灵活。


先说结论

前三篇已经能:存图 → 跑图 → 在浏览器里看 events。但 Template 节点只能做字符串插值 (把 {name} 换成输入值),做不了「转大写、算长度、拼列表」这类小逻辑。

本篇补的是 可编程变换

对比 Template 节点 Code 节点
能做什么 固定句式 + 占位符填空 短 Python 片段加工变量
配置字段 data.template data.code
输出约定 写入 text 必须 赋值 result = ...;若是字符串,也会写入 text 方便接 End
典型路径 start → template → end start → code → end,或与 template 串联

一句话:Code 节点让工作流里能写「几行小逻辑」,而不是只能拼句子;本仓是学习向受控执行,不是生产级沙箱。

HTTP 接口形状不变 :仍是 create → run → events。变的是图里多了一种 data.type: "code"


1. 为什么需要 Code 节点?

想象你要把用户输入的名字转成大写,或根据两个数字算和。Template 只能写 Hello, {name}!,没法写 name.upper() 这种运算。

对照 Dify 一类产品,Code 节点就是专门干这个的:在图上挂一小段代码,读当前运行里的变量,算完写回,交给下游。

本仓 change code-node 在现有 Runner 上扩展,不新加接口、不改 Web 联调流程------你在联调页把图 JSON 换成含 code 的版本即可。

术语 是什么 本仓怎么用
Code 节点 执行用户提供的短代码 data.type: "code" + data.code
变量表 这次运行里「名字 → 值」的对照 start 的 inputs 进来;每个节点可读可写
result Code 节点必须赋值的输出名 例如 result = name.upper()
受控执行 只允许有限能力,禁 import / 读文件等 学习向;文档会写明不是真沙箱

2. 功能一:图里怎么配 Code 节点

在 nodes 里增加一类,和 start / template / end 并列:

json 复制代码
{
  "id": "code_1",
  "data": {
    "type": "code",
    "code": "result = name.upper()"
  }
}

含义(不必先会 Python 语法):

片段 在干什么
"type": "code" 告诉 Runner:这一步要跑代码
"code": "..." 用户写的短脚本
name 来自运行 inputs 的变量名(本例输入 "name": "forge"
name.upper() 把字符串转成大写(.upper() 是字符串自带的方法)
result = ... 固定约定 :必须把最终结果赋给 result,Runner 才认

最小整图(start → code → end):

json 复制代码
{
  "nodes": [
    { "id": "start_1", "data": { "type": "start" } },
    {
      "id": "code_1",
      "data": { "type": "code", "code": "result = name.upper()" }
    },
    { "id": "end_1", "data": { "type": "end" } }
  ],
  "edges": [
    { "id": "e1", "source": "start_1", "target": "code_1" },
    { "id": "e2", "source": "code_1", "target": "end_1" }
  ]
}

创建图时还会校验:

  • data.code 不能为空
  • 源码不超过 4KB
  • 静态拒绝 importopen(__import__ 等危险模式

非法图在创建阶段就会被拒绝,和 Template 缺字段一样。


3. 功能二:跑起来会发生什么

inputs 示例:{"name": "forge"}

Runner 走到 Code 节点时(白话顺序):

  1. 把当前变量表(含 name)交给执行器
  2. 受控环境 里跑 data.code 里的脚本
  3. 检查是否出现了 result
  4. result 写回变量表;若是字符串,同时写入 text,End 节点能直接输出
  5. 照常写 node_started / node_succeeded 事件

成功时 outputs 大致是:

json 复制代码
{
  "text": "FORGE",
  "result": "FORGE"
}

失败时(语法错、没写 result、用了禁止的 import 等):Run 为 failed,事件里有 node_failederror 字段可读------和 Template 缺变量失败同一套观测方式。

和 Template 怎么选?

场景 更合适的节点
固定问候语 + 填名字 Template
大小写、简单运算、列表拼接 Code
两者都要 start → template → code → end(先拼句,再加工)

4. 功能三:安全边界(学习向,不是真沙箱)

Code 节点会执行用户写的 Python 片段,因此必须有硬边界。本仓当前做法:

限制 目的
禁用 import / open / exec / eval 等模式 避免读文件、拉库、嵌套执行
只开放少量内置函数(如 lenstrint 允许常见小运算,不开放整台 Python
源码长度上限 4KB 避免超长脚本拖垮请求
在受控命名空间里 exec 学习演示够用;不能当生产隔离方案

仓库 code.py 顶部注释和 api/README.md 都写明:这是学习向受控命名空间,不是 Docker 级沙箱。

你若对照 Dify 生产环境,应假设那边还有更强隔离;本系列先学会「节点类型怎么扩展、Runner 怎么调度、失败怎么落事件」。


5. 你怎么跟跑?

方式 A:浏览器联调页(推荐)

  1. 按第三篇起好 api + web
  2. 打开 http://localhost:3000
  3. 把左侧图 JSON 换成上面的 start → code → end(或从 web/lib/sample.ts 里的 SAMPLE_CODE_GRAPH 复制)
  4. 右侧 inputs 填 {"name": "forge"},点「运行」
  5. status: succeededoutputs 里的 FORGE

联调页默认仍预填 Template 示例;换 Code 图只需改文本框,不必改前端代码。

方式 B:curl

api/README.md 有完整的 Code 节点 curl 示例:创建含 code 的图 → POST .../runs → 查 events。

自动化

bash 复制代码
cd api
uv run pytest

新增用例会覆盖:合法 code 图、缺 code 拒绝、禁止 import、运行成功/语法失败等。


6. 仓库里改动了哪几块?(地图,不是语法课)

位置 本篇新增职责
core/workflow/graph.py 允许 data.type: "code",校验 data.code
core/workflow/nodes/code.py 受控执行 + result 约定
core/workflow/runner.py 调度循环里多一个 code 分支
web/lib/sample.ts 可选示例图 SAMPLE_CODE_GRAPH
api/README.md Code 示例与安全说明

读代码建议顺序:

  1. 先看 README / 联调页跑通(本节第 5 节)
  2. 再看 graph.py:多了一种节点类型意味着什么
  3. 最后看 code.py:「受控」具体禁了什么

Runner 其它节点(start / template / end)逻辑与第二篇相同;Code 只是在循环里多插一个分支------这是以后加 LLM 节点等同理可扩的模式。


本篇顺带认识的 Python(仍只钉词)

词 / 写法 先怎么记 和 Code 节点的关系
result = ... 给名为 result 的格子赋值 输出约定,缺了就算失败
name.upper() 对字符串 name 调「转大写」 示例图里的典型一行
exec(...) 把字符串当代码跑(危险,故本仓受限使用) 实现细节在 code.py,你知道「会被关进受控环境」即可
import 引入外部库 本仓 Code 节点禁止,创建图时就会拦

和前作怎么接

补哪一段
02 最小工作流 API Template 与 Runner 主路径
03 浏览器联调台 页面触发 create → run → events
本篇 第四种节点 Code:可编程变换 + 受控边界

下一篇更可能落在 LLM 节点、并行边或其它产品能力;本切片停在「一种新节点类型如何接入现有 Runner」。


你可以从这里带走什么?

  1. Template 管填空,Code 管小逻辑------节点类型是按能力切的,不是越堆越多 UI。
  2. Code 节点的契约很简单:读变量 → 跑 data.code → 必须写出 result
  3. 加新节点类型时,HTTP 往往不用改;改的是图校验 + Runner 分支 + 文档示例。
  4. 任何「用户可写代码」的能力都要写清安全边界;学习向受控 exec ≠ 生产沙箱。
  5. 联调页仍够用:换 JSON 就能试 Code,说明前后端契约稳定。

仓库与相关文档

欢迎 Star、Issue 和 PR。


_本文基于 Flow Forge code-node:覆盖 Code 节点配置、受控执行与 result 约定。

相关推荐
讲温控就好了1 小时前
从医疗影像到能源存储——芯片冷却温控技术的跨行业赋能
人工智能·python·能源
snowfoootball1 小时前
在vs code里使用deepseek harness:我做的插件又更新啦!
ai·开发·deepseek·dsh
Rain的Java大神之路1 小时前
短信接口被狂刷怎么处理
java·运维·后端·web安全·面试·架构·xss
DeepVisionary1 小时前
从 Qwen3.8-27B 把原生多模态、原生 FP8、桌面级 Agent 三件事一次集齐,看开源大模型的“工业化拐点“
python·自动化
Xuanzang Road2 小时前
第 40 届学习强企玄奘路戈壁挑战赛:在绝境中重塑自我
学习
Lost of 程序猿2 小时前
AOP 实战:面向切面编程从理论到落地
后端·asp.net·aop·面向切片变成
固定资产管理系统软件2 小时前
商务局RFID固定资产管理系统的应用价值与落地要点解析
大数据·python
Lost of 程序猿3 小时前
ASP.NET Core 认证授权实战:从 JWT 到 Policy,设计一套企业级 RBAC 权限系统
后端·asp.net