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
  • 静态拒绝 import、open(、__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_failed,error 字段可读------和 Template 缺变量失败同一套观测方式。

和 Template 怎么选?

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

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

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

限制 目的
禁用 import / open / exec / eval 等模式 避免读文件、拉库、嵌套执行
只开放少量内置函数(如 len、str、int) 允许常见小运算,不开放整台 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: succeeded 与 outputs 里的 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 约定。

相关推荐
笨笨饿13 小时前
140_AI新手村MCP与Skills是干嘛的
开发语言·人工智能·python·stm32·单片机·嵌入式硬件·物联网
青柠之夏cc13 小时前
AI与教育:个性化学习助手让“因材施教“成为现实,但代价是隐私?
人工智能·学习
hsfxuebao13 小时前
Loop Engineering 保姆级教程 + 项目实战
人工智能·后端
for_ever_love__14 小时前
机器学习入门——手写线性回归与梯度下降
人工智能·python·学习·机器学习·线性回归
打工仔折腾 AI14 小时前
从 Demo 到生产级 Agent:8 个关键设计机制与 Python 实现拆解
java·jvm·人工智能·后端·python·langchain·ai agent 实战
在猴站学算法14 小时前
(SQL注入学习)无回显的报错注入(Error-Based)
学习·网络安全·sql注入·ctf竞赛
I Am a robert girl14 小时前
当传感器学会“说谎“:拆解可靠性门控的稀疏惯性动捕融合
python·姿态估计·传感器融合·惯性动捕·imu传感器·可靠性门控·可穿戴计算
架构技术专栏14 小时前
交叉熵:AI 怎样给概率预测打分
后端
李航198314 小时前
AI定制柜建模,需要详细的建模规范和标准流程
人工智能·python·计算机视觉·ai·ai编程
沙漠之主15 小时前
Python 教学设计资料:从入门到实战的完整课程方案
爬虫·python