城北 · 2026-09-04
一条 Dify 工作流刚搭出来时,很容易给人一种错觉:节点已经连上,数据自然就会流过去;用户连续说了几句话,应用自然就知道这些话来自同一场对话。

地图上的每一条路径,最终都要汇进同一处地基。
可节点只负责执行,连线只负责指路。数据从哪里来、最后汇到哪里,要靠变量说明;哪些信息应该在一轮结束后留下来,也要靠变量决定。
没有变量的工作流,像一栋已经装好门窗、却没有铺设水电的房子。远看结构完整,真正住进去以后才会发现:每个房间都各自为政,水流不到该去的地方,灯一关,刚才发生过什么也全忘了。
这一集,我们来铺这栋房子的管线。
前情提要 EP2 结尾说过,Start、LLM、Answer 连在一起,只说明谁先运行;变量引用才说明数据具体从哪里来、交给谁。EP3 给"国家信息小助手"装出了四条各自独立的分支,却还没有回答数据怎样收拢、怎样留住。想看完整讲解,可以回看 EP2《从零搭出第一个 Dify 应用:用云版完成一次 Chatflow 上线》 的「一次最小案例,真正应该学会什么」一节,以及 EP3《给 Dify 应用装上"分岔路"》 里刚建好的四条分支——不看也不影响读完这一集。
| 1 | AI 应用平台通识与选型 | 认知/选型判断力:这个领域是什么、要不要学、怎么定位 | 已发布 |
| 2 | 云版搭第一个 Chatflow 应用 | 5 种应用类型、Start/LLM/Answer、Prompt 分层、发布分发 | 已发布 |
| 3 | 给应用装上"分岔路" | If/Else、问题分类器:写死的规则 vs 交给模型判断 | 已发布 |
| 4 | 变量,这个系列真正的地基 | 会话变量、环境变量、变量聚合器/赋值器 | ← 你在这里 |
| 5 | 把外部世界接进来 | HTTP Request、Code 节点、参数提取器 | 未发布 |
| 6 | 知识库与 RAG 实战 | 文档处理/分段/检索策略/Rerank | 未发布 |
| 7 | 批量处理与循环 | Iteration、Loop、列表操作 | 未发布 |
| 8 | 工具与 Agent | 工具市场、自定义工具、Function Calling/ReAct、双向 MCP | 未发布 |
| 9 | 从 Demo 到生产:运维篇 | DSL 版本管理、执行日志、标注、可观测性、权限 | 未发布 |
| 10 | 私有化部署实战 | Docker Compose、.env、报错排查 | 未发布 |
01前三集的变量,都只是匆匆过客
"国家信息小助手"其实早就在使用变量。
用户输入"法国"时,Dify 把本轮消息放进系统变量 sys.query。问题分类器读取它,判断这句话属于"国家名称""问候或闲聊"还是"无法识别";If/Else 也读取它,检查内容是否为空;LLM 再接收这份输入,生成"法国的首都是巴黎"之类的回答。
模型生成的文字同样是变量。LLM 节点产生 text 输出,直接回复节点引用它,用户才真正看到答案。
这条链路可以简化成:
sys.query → 问题分类器/If/Else/LLM → LLM.text → 直接回复
这里的变量都属于一次运行中的临时数据。
sys.query 代表这一轮用户说的话。下一轮用户再发"日本",流程会重新运行,sys.query 也会变成"日本"。LLM 的 text 输出则属于本次模型调用,它被直接回复节点引用后,这一轮任务也就结束了。
这并没有问题。绝大多数中间结果本来就只需要活一轮。
问题在于,一旦工作流出现分支,或者产品需要跨轮保存状态,临时变量就不够用了。
EP3 结束时,应用有四条互斥路径:
- 国家名称 → 空输入兜底;
- 国家名称 → LLM 回答;
- 问候或闲聊 → 问候引导;
- 无法识别 → 无法识别兜底。
它们每次只会运行一条,却各自通向自己的出口。应用能够决定"这轮往哪里走",却不能把分散的结果重新收回来。
与此同时,用户这一轮问"法国",下一轮问"日本",应用也没有保存查询历史。两次输入发生在同一个聊天窗口里,对工作流来说却依然像两次互不相干的运行。
所以,这一集要解决两个不同的问题:
前一个问题交给变量聚合器,后一个问题交给会话变量和变量赋值器。
02第一次改造:先把岔路重新收回来
先看"国家名称"分支。
EP3 留下的结构是:
- IF:sys.query 为空 → 空输入兜底直接回复;
- ELSE:sys.query 不为空 → LLM → 直接回复。
两个出口都能把文字交给用户,功能上没有错误。真正的问题是,它们把同一种下游责任复制了两遍。
假设以后希望每条国家查询回复前都加一句:
以下信息由 AI 生成,请以权威资料为准。
现在至少要修改两个直接回复节点。
如果接下来还要统一记录日志、进行内容审核、包装输出格式,所有操作都得在两个出口分别配置。分支越多,重复越多;漏改其中一条,用户在不同路径上就会得到不一致的体验。
这类问题不能靠"记得同步修改"解决。更可靠的做法,是让不同分支只负责产生各自的结果,再把结果汇入同一个下游出口。
这正是变量聚合器的职责。
03先让固定文案变成可以流动的变量
目前,ELSE 路径上的 LLM 会产生 text 输出变量,但 IF 路径上的"空输入兜底"是一个直接回复节点。
直接回复节点的任务是把内容展示给用户。它不是一个适合继续向下游提供中间结果的处理节点。如果想让两条分支在后面重新汇合,就要先把兜底文案变成一个可以被后续节点引用的变量。
因此,把原来的"空输入兜底"直接回复节点改造成模板转换节点。
这个节点只做一件很简单的事:输出固定字符串。
我没有收到有效内容,请输入一个国家名称,例如"法国"。
模板转换节点的完整能力远不止输出一句固定文字,但那是另一个话题。这里使用它,只是因为我们需要把固定文案包装成一个字符串变量,让它能够像 LLM.text 一样继续流向下游。
改造之后,两条路径都会产生同一类型的结果:
- IF 路径:模板转换节点输出字符串;
- ELSE 路径:LLM 节点输出 text 字符串。
这一步很关键。变量聚合器不是把任意节点强行粘在一起,而是从不同互斥分支中选择一组同类型变量,再对外提供一个统一输出。

IF 和 ELSE 走的是两条完全不同的路,但都要在这里交出一个字符串。
04用变量聚合器建立统一出口
接下来,在模板转换节点和 LLM 节点之后添加变量聚合器。
把下面两个变量加入同一组:
- 空输入兜底模板转换节点的字符串输出;
- LLM 节点的 text 字符串输出。
它们都属于字符串类型,符合变量聚合器要求输入变量类型一致的规则。
Dify 的变量聚合器支持字符串、数字、对象、布尔值、数组和文件等类型,但同一组里不能混合不同数据类型。如果一条分支交出字符串,另一条分支交出对象,聚合器无法假装它们是同一种下游数据。
节点运行时也不是把两个字符串拼在一起。
因为 If/Else 的两条路径互斥,每次运行只会有一条真正执行。sys.query 为空时,模板转换节点产生值,LLM 不运行;sys.query 非空时,LLM 产生 text,模板转换节点不运行。
所以,聚合器配置了两个候选输入,实际每轮只有其中一个有值。那个真正产生出来的值,就成为聚合器的统一输出。
可以把它理解成一个接线盒:
- 上游可能从不同管线送来结果;
- 每次只有一根管线真的有水;
- 下游不再关心这次走的是哪条管线,只从同一个出口取水。
如果一条复杂流程需要同时收敛多项数据,例如分别聚合"回答正文"和"来源信息",还可以在同一个变量聚合器里建立多个分组,各自独立聚合。不过这个案例只有一份最终回复,不需要增加额外复杂度。

两个候选输入,同一种类型,聚合器只关心谁真的交了值。
05让直接回复只认一个上游结果
原来的"直接回复"节点继续保留,但不再只引用 LLM.text。
把它的回复内容改为引用变量聚合器的输出变量,再让变量聚合器连接到这个直接回复节点。
改造后的"国家名称"分支变成:
条件分支 → 模板转换/LLM → 变量聚合器 → 直接回复
当 IF 成立时,固定兜底文案经过模板转换节点进入聚合器,再由统一的直接回复节点发给用户。
当 ELSE 成立时,gpt-4o-mini 生成首都回答,LLM.text 进入同一个聚合器,最后仍由同一个直接回复节点发给用户。
上游仍然有两条路,下游却只剩一个出口。

上游还是两条路,下游已经收回成一个出口——画面里那个"变量赋值"节点是下一节才会讲到的东西,先眼熟一下。
这次改造没有增加新的业务能力。用户问"法国",看到的答案和以前可能完全一样;空输入触发兜底时,文案也没有改变。
但工作流的可维护性已经不同了。
以后想在回复前统一增加免责声明,只改一个直接回复节点;想在输出前统一经过内容审核,只在聚合器后面接一次;想记录这一分支最终交付了什么,也只需要读取聚合器的统一输出。
变量聚合器的价值,不是让结果"能出来",而是避免所有下游处理随着上游分支一起复制。
分支负责制造差异,聚合器负责结束差异。
"问候或闲聊"和"无法识别"目前仍然保留各自独立的直接回复。读者可以尝试沿用同一种模式,把它们也收敛到统一出口;这一集为了控制改造范围,只处理"国家名称"分支。
06聚合器只能收互斥分支,不能合并并行结果
变量聚合器有一条必须讲清楚的边界:它面向的是互斥分支,不是并行计算。
If/Else 和问题分类器都符合这个条件。一次运行只会命中一条路径,所以聚合器面对的是"多个候选变量,只有一个实际有值"。
并行分支完全不同。
假设一条流程同时调用天气接口和汇率接口,两个分支都会执行,而且两个结果都需要保留。此时我们要做的是把多个真实结果组合起来,而不是从多个候选值里接住唯一存在的那个值。
变量聚合器不负责这种并行结果合并。并行场景应该使用代码节点或模板节点,根据需要组织多个结果,这一集暂不展开。
判断能不能使用变量聚合器,可以先问一句:
这些上游结果,是"每次只会出现一个",还是"这一次可能同时出现多个"?
只有前一种情况,才是聚合器设计出来解决的问题。
还有一个容易造成混淆的历史命名:Dify 官方文档曾把变量聚合器称作"变量赋值节点"。它和接下来要用的"变量赋值器"不是同一个节点。
两者的区别其实很明确:
- 变量聚合器:从互斥分支中收拢一个已有值;
- 变量赋值器:修改一个允许写入的变量。
一个负责汇流,一个负责落笔。名字相近,数据动作完全不同。
07第二次改造:让一轮数据活到下一轮
现在,"国家名称"分支已经拥有统一出口。
但用户连续问两个问题时,应用依然没有状态:
用户:法国 用户:日本的首都是什么?
第二轮运行时,sys.query 只包含"日本的首都是什么?"。上一轮的"法国"不会自动成为一个可供工作流读取的查询记录。
这里要区分两件经常被统称为"记忆"的能力。
LLM 可以使用对话上下文,让模型理解用户上一句话说过什么;工作流也可以保存结构化状态,让后续节点明确知道某个变量当前是什么值。
前者更像把聊天记录交给模型阅读,后者更像应用自己维护一份状态。
这一集要做的是后者:建立一个查询历史数组,并由工作流明确决定什么时候往里面追加内容。
这就是会话变量。
08会话变量不是更长寿的普通变量
在 Chatflow 中新增一个会话变量:
- 变量名:queried_countries
- 含义:查询历史
- 类型:Array[String]
- 初始值:空数组
![添加会话变量对话框,名称填写 queried_countries,类型选择 array[string],右侧会话变量面板的说明写着会话变量用于存储 LLM 需要的上下文信息,是可读写的](https://www.171host.com/wp-content/uploads/2026/09/20260905004341-6a9b65bd0f814.png)
名称、类型、默认值——会话变量的配置和普通变量没什么两样,特殊的只是它的生命周期。
普通节点输出通常属于这一轮运行。会话变量的生命周期则跨越同一个对话的多轮消息。
用户先问"法国",工作流可以把"法国"写入数组;同一对话里再问"日本的首都是什么?",数组可以继续保留上一轮内容,并追加本轮输入。
理想状态下,它会经历这样的变化:
新对话开始
queried_countries = []
第一轮输入"法国"后
queried_countries 保存一条查询记录。
第二轮输入"日本的首都是什么?"后
queried_countries 在原有记录后继续追加本轮原始输入。
这里强调"同一个对话",因为会话变量不是永久用户档案。
只要用户仍在当前对话中,它就可以跨轮保存;用户开启新对话后,会话变量重新回到初始值。它不会天然跨对话追踪用户,也不应该被当成数据库使用。
会话变量只存在于 Chatflow。普通 Workflow 是一次任务式执行,没有 Chatflow 的对话生命周期,因此没有同样的会话变量概念。
Chatflow 还提供 sys.conversation_id 和 sys.dialogue_count 等系统变量。前者标识当前会话,后者记录对话轮次并在每轮自动增加。它们能帮助我们识别"这是哪场对话、现在到了第几轮",但不会替我们维护查询历史。
要让应用真正记住"问过什么",仍然需要自定义会话变量。
09会话变量不能自己变化
声明 queried_countries 只是准备了一个容器。
如果没有节点向里面写数据,它会一直是空数组。用户问十次"法国",变量也不会因为名字叫"查询历史"就自动理解我们的意图。
根据 Dify 的变量模型,会话变量只能通过变量赋值器节点修改。
变量赋值器的任务,是把本轮工作流中已经产生的数据写进可写变量。它在这里要执行的动作是:
把本轮的 sys.query 追加到 queried_countries。
于是,临时变量和会话变量第一次发生了交接:
- sys.query 保存这一轮的原始输入;
- 变量赋值器读取 sys.query;
- queried_countries 接住这份输入;
- 下一轮运行时,sys.query 会改变,queried_countries 仍保留此前追加的记录。
这就是"状态"产生的地方。
10变量赋值器应该插在哪里
这次把变量赋值器放在变量聚合器之后、统一的直接回复之前。
改造后的主路径是:
条件分支 → 模板转换/LLM → 变量聚合器 → 变量赋值器 → 直接回复
这样安排有两个原因。
第一,只有上游分支已经完成、聚合器拿到本轮最终结果以后,才把这次查询记入历史。变量赋值器由此成为"本轮处理已经走到交付前"的明确标记,而不是用户输入刚进入流程就抢先写入状态。
第二,写入发生在最终回复之前。只要用户看到了这次回答,工作流就应该已经完成对应的状态更新,而不是先把消息发出去,再依赖后续节点补记。
![变量赋值节点配置面板,变量选择 queried_countries(Array[String]),赋值方式为追加,赋值内容引用用户输入的 query(String);背景画布可见该节点位于变量聚合器与直接回复之间](https://www.171host.com/wp-content/uploads/2026/09/20260905004343-6a9b65bf8a48b.png)
追加,不是覆盖——这是这一步唯一不能选错的地方。
这里沿用 EP3 的教学结构:空输入兜底位于问题分类器后的"国家名称"分支,正常情况下几乎不会被触发。我们真正需要验证的是"法国""日本的首都是什么?"这类有效查询会被追加到历史。
如果以后把空值检查移到问题分类器之前,或者实际日志表明空值确实可能进入这条公共路径,就应该让写入动作只发生在有效查询路径上,避免把空字符串也记进数组。节点位置不是固定仪式,它应该服从"什么事件发生后,状态才算成立"这条业务语义。
也可以把变量赋值器放在直接回复之后,让用户先看到答案再更新状态,但这会让"回答已交付"和"状态已落下"分成两个阶段。本例没有异步副作用,也不需要抢那一点展示顺序,因此放在回复之前更容易理解和检查。
11这次存原始问题,不假装已经提取出国家名
变量名叫 queried_countries,但我们实际追加的是 sys.query 原文。
用户输入"法国",数组里记录"法国"。
用户输入"日本的首都是什么?",数组里记录的也是"日本的首都是什么?",而不是经过清洗后的"日本"。
这不是疏忽,而是一次有意控制范围的取舍。
从自然语言中稳定提取国家实体,需要另一种能力。我们可以让节点把"日本的首都是什么?"解析成结构化字段,也可以处理一句话里出现多个国家、别名和歧义,但那已经进入参数提取器的范围。
这一集只解决"怎样跨轮保存数据",不同时解决"怎样把数据清洗到最理想的形式"。
先保存原始问题有三个现实好处:
- 数据来源明确,就是当前轮的 sys.query;
- 不需要增加额外模型调用或解析节点;
- 即使提取逻辑尚未建立,应用也已经拥有可用的历史记录。
它的代价也很清楚:这份历史是"用户问过什么",而不是一份严格的"国家名列表"。
所以,queried_countries 是便于理解的教学命名。若用于生产,query_history 可能更准确。这里继续使用前者,是为了让变量目的和当前案例保持直观,同时明确它保存的是粗粒度原始问题。
变量结构不必一步到位,但变量里究竟存了什么,必须说实话。
下一集引入参数提取器以后,我们再有能力把原始问题变成更干净、可计算的国家实体。
12让问候分支第一次感知历史
会话变量真正有价值,不是因为调试面板里多了一个数组,而是因为后续轮次能够使用它。
可以在"问候或闲聊"分支中引用 queried_countries,让问候回复根据当前查询历史表达类似这样的意图:
如果用户此前查过国家,就提示他已经进行过哪些查询,并引导继续提问;如果历史为空,则使用普通的首次问候。
写完设计意图,剩下的就不能再靠猜了——数组变量塞进一段中文回复文本里,最终到底长什么样,只有实际跑一遍才知道。
实测流程是这样的:在同一场对话里,先后输入"德国""日本的首都是什么?",queried_countries 依次追加了这两条记录;再输入"你好",触发"问候或闲聊"分支,回复文本正确读到了这个数组。
真实呈现出来的格式有点意外:
你已经问过我这些国家啦:- 德国
• 日本的首都是什么?
数组的第一项被当成了紧跟在冒号后面的行内文本、用短横线引出,后面的项却各自换行、前面带着一个实心圆点——这是 Dify 把数组变量转成文本时套用的默认 Markdown 列表语法,前端再把 Markdown 渲染成这个不算工整的混合样式。它不是我们配置错了,就是这个界面版本的真实行为。

数组变量真实的渲染效果——第一项内联、后面几项换行加圆点,没有想象中工整,但历史确实被记住了。
这段实测结果值得记一条经验:会话变量存进去的是干净的数据结构,但它变成用户能读的文字之后,格式主动权并不完全在你手上。如果最终要交付给用户的是一份整齐的列表,几乎肯定需要在这一步之后再接一个模板转换节点,自己把数组拼成想要的样子——这一集不做这层加工,留一个明确的入口给读者:模板转换节点的完整用法,正好是这个格式问题的答案,也是下一集会用到的工具。
当这一步跑通后,应用的行为就发生了本质变化。
过去,用户问完"德国"再说"你好",问候分支只会机械地返回一条固定引导语。现在,它至少可以知道当前对话里已经发生过查询,并据此调整回复。
这还不是永久记忆,也不是完整的用户画像。它只是同一场对话中的运行时状态。
但从工程角度看,这已经比"让模型看起来像记得"更扎实:历史存在哪个变量里、什么时候追加、什么时候重置、哪些分支可以读取,全部能够在工作流中明确说明。
13别把三类变量混成一个概念
走到这里,"国家信息小助手"里已经出现了三类用途不同的数据。
| 系统变量 | sys.query、sys.conversation_id、sys.dialogue_count | 由系统按运行或对话提供 | 读取本轮输入、识别会话和轮次 |
| 节点输出变量 | LLM.text、模板转换输出、聚合器输出 | 主要服务于当前轮工作流 | 在节点之间传递中间结果 |
| 会话变量 | queried_countries | 跨越同一对话的多轮消息 | 保存需要后续轮次继续读取的动态状态 |
系统变量由 Dify 提供。节点输出由某次节点运行产生。会话变量则由应用设计者声明,并通过变量赋值器主动修改。
这三者不是寿命从短到长的同一种容器,而是各自承担不同责任。
看到一个值下一轮还要使用,不要指望普通节点输出自动留下来;看到一个系统变量,也不要因为它带有 conversation 字样,就误以为它已经保存了业务历史。
变量设计的第一步,从来不是起名字,而是判断:
这份数据属于当前节点、当前一轮、当前对话,还是整个应用的固定配置?
最后一种情况,就是环境变量。
14环境变量保存的不是记忆,而是配置
环境变量经常和会话变量一起出现在 Dify 的变量说明里,但它们解决的不是同一类问题。
环境变量适合存放 API Key 等敏感信息,让凭证和应用编排分离。分享应用 DSL 文件时,密钥不必跟着流程配置一起泄露。
它也可以保存多个节点共同使用的配置。例如,多个 LLM 节点需要引用同一份模型配置时,可以让它们读取环境变量;以后修改一次,所有引用位置都能同步使用新值。
环境变量的本质是应用级配置。
它由开发者设置,与某个用户无关,与某场对话无关,也不会因为用户多问一句而变化。对于所有使用该应用的人,它都是一份共享常量。
会话变量则是运行时状态。
它随对话产生,在同一对话的多轮运行之间变化,用户开启新对话后重置。不同对话拥有各自的状态,不应该共享一份 queried_countries。
可以用一句话区分:
环境变量回答"这个应用依赖什么配置",会话变量回答"这场对话已经发生了什么"。
这一集不实操环境变量,因为"国家信息小助手"目前还没有调用需要密钥的外部服务。为了演示而随便塞进一个假 API Key,只会让概念显得比实际用途更抽象。
下一集加入 HTTP Request 节点、真正访问外部 API 时,环境变量才会从一项配置功能变成必要的工程边界。
15调试时,不要只看最后一句回答
变量改造以后,测试重点也要随之变化。
以前只要检查"法国的首都是不是巴黎",就能大致判断最小链路是否跑通。现在即使最后回复正确,内部状态也可能没有按预期更新。
至少应该验证下面几组行为。
验证聚合器的两条输入路径
先输入正常国家问题,确认:
- 流程进入 ELSE;
- gpt-4o-mini 产生 text;
- 聚合器输出等于本轮 LLM 输出;
- 统一直接回复正确展示聚合结果。
再以能够触发兜底的方式测试 IF 路径,确认:
- 模板转换节点产生固定字符串;
- LLM 没有在该路径运行;
- 聚合器输出等于模板转换结果;
- 最终仍由同一个直接回复节点交付。
测试的重点不是两个答案都"看起来对",而是它们确实从两个上游变量进入了同一个下游出口。
验证会话变量跨轮追加
在同一场对话中依次输入:
- 法国
- 日本的首都是什么?
- 德国
每一轮之后检查 queried_countries 是否保留此前记录,并追加本轮的 sys.query,而不是覆盖旧值。
然后开启一场新对话,确认它重新回到空数组。
只有"旧对话能累积、新对话会重置"同时成立,才能证明这是一份会话状态,而不是全局共享数据或单轮临时输出。
验证不同分支读取同一份状态
完成两次国家查询后,再发送一条问候,让流程进入"问候或闲聊"分支。
检查这个分支能否读取查询历史,并观察数组的实际呈现。若格式不适合直接交给用户,先记录真实行为,再决定后续怎样格式化,不要为了让截图好看而跳过数据语义。
最后再测一场全新对话中的首次问候。此时历史为空,回复不应该假装用户已经查询过任何内容。
16变量真正建立的是责任边界

这一集结束时,"国家信息小助手"长这样——比 EP3 结束时多了三个节点,但每一个都在做一件明确的事。
这次我们没有接知识库,没有调用外部 API,也没有换更强的模型。
但"国家信息小助手"的结构已经向真正可维护的应用迈了一大步。
变量聚合器解决的是空间上的分散:同一轮运行里,多个互斥分支可以产生不同结果,再汇入一个统一出口。它减少下游重复配置,却不负责合并并行执行产生的多个真实结果。
会话变量解决的是时间上的断裂:这一轮产生的信息可以跨越工作流结束,继续服务同一场对话的后续轮次。它只属于 Chatflow 的对话生命周期,用户开启新对话后便会重置。
变量赋值器则把两者之间最容易忽略的动作说清楚:状态不会自动产生,必须由工作流在明确的位置主动写入。会话变量负责"保存在哪里",变量赋值器负责"什么时候、把什么写进去"。
环境变量又站在另一条轴线上。它不保存用户经历,而是保存开发者为应用准备的共享配置,尤其适合 API Key 等不该进入 DSL 的敏感信息。
如果只记住这一集的两句话,可以记住:
多条互斥分支需要共享同一套下游处理,用变量聚合器把出口收回来。
一份数据需要跨越同一对话的多轮运行,用会话变量保存,再由变量赋值器明确更新。
节点决定流程往哪里走,变量决定数据怎样流、在哪里汇合、能活多久。直到这一步,Dify 画布才不再只是一张连线图,而开始拥有真正的应用状态。
下一集,我们会把外部世界接进来:用 HTTP Request 调用外部 API,用环境变量保存 API Key,再让 Code 节点和参数提取器处理从外部返回的数据。
本文首发于我的个人站 chengbei.org,同步转载于此。




