Blueking Lite AI 工作流记忆节点:让运维编排真正"记住"上下文

2026-05-29 27 预计阅读时间:1 分钟
来源:oschina.net AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:13 分钟

运维场景里有一类痛点反复出现——AI 工作流跑完一步就把前一步的结论忘了。排查告警时,第一步已经定位到异常主机,第二步却要从头再问一遍;执行修复时,第三步不知道第二步改了什么配置。每次节点之间只能靠硬编码的参数传递,遇到分支和循环就更棘手。

Blueking Lite 本周更新的 记忆节点(Memory Node) 正是为了解决这个问题:在工作流中显式地读写持久化记忆,让后续节点能拿到前序节点的结论、中间状态甚至历史执行记录,从而编排出真正确定性的运维场景。

记忆节点解决什么问题

传统 AI 工作流的节点间通信方式大致有两种:

  • 参数硬传递:上游节点把输出塞进下游节点的入参,链式依赖,一改全改。
  • 隐式上下文:靠 LLM 的对话历史"猜"前序信息,不可控、不可校验。

记忆节点引入了第三条路——显式、可读写的结构化记忆存储。你可以把它理解成工作流级别的"变量表"或"黑板":

  • 任何节点执行完毕后,可以把关键结论写入记忆(如 affected_hosts: ["10.0.1.3", "10.0.1.7"])。
  • 后续节点按 key 读取,不需要知道是谁写的,只需要知道 key 名。
  • 记忆跨执行周期持久化,同一工作流的多次运行可以累积经验(比如"上次这个告警的根因是磁盘满")。

这对确定性编排至关重要。确定性场景要求:同样的输入 → 同样的决策路径 → 同样的输出。如果中间状态靠 LLM 自由发挥,确定性就崩了;记忆节点把中间状态钉在结构化存储里,后续节点拿到的不再是"LLM 觉得大概是啥",而是"上一个节点明确写下来的值"。

记忆节点的读写模型

记忆节点提供两个核心操作:

操作 说明 典型用途
Write 将键值对写入记忆空间 节点执行结论、中间变量、决策标记
Read 按 key 从记忆空间读取值 后续节点获取前序结论、条件分支判断

记忆空间按工作流实例隔离——同一工作流的不同执行实例互不干扰,但同一实例内的所有节点共享同一份记忆。这意味着:

  • 并行分支可以各自写入不同 key,汇聚节点一次性读取全部。
  • 循环场景中,每次迭代可以追加写入(如 checked_hosts 列表逐步增长)。

下面用一个实际运维场景来演示完整编排。

实践:告警根因分析 + 自动修复工作流

假设我们要编排一个"CPU 告警 → 根因定位 → 自动修复"的确定性工作流。整个流程分四步,记忆节点贯穿始终:

workflow:
  name: cpu_alert_diagnosis_and_fix
  description: CPU 告警根因分析与自动修复,通过记忆节点传递中间结论
  nodes:
    # 第一步:接收告警,提取关键信息写入记忆
    - id: alert_receiver
      type: llm
      prompt: |
        分析以下 CPU 告警信息,提取受影响主机 IP、告警阈值、当前 CPU 使用率。
        输出格式严格为 JSON:
        {"affected_ip": "...", "threshold": ..., "current_cpu": ...}
      input:
        alert_text: "{{ trigger.alert_message }}"
      next: memory_write_alert

    # 记忆节点:写入告警摘要,供后续节点读取
    - id: memory_write_alert
      type: memory_write
      entries:
        - key: affected_ip
          value: "{{ alert_receiver.output.affected_ip }}"
        - key: threshold
          value: "{{ alert_receiver.output.threshold }}"
        - key: current_cpu
          value: "{{ alert_receiver.output.current_cpu }}"
        - key: alert_time
          value: "{{ trigger.timestamp }}"
      next: root_cause_analysis

    # 第二步:根因分析,从记忆读取主机 IP,写入根因结论
    - id: root_cause_analysis
      type: llm
      prompt: |
        主机 {{ memory_read.affected_ip }} 的 CPU 使用率达到 {{ memory_read.current_cpu }}%。
        请判断根因,只返回以下之一:
        - "process_stuck":某个进程卡死
        - "traffic_spike":流量突增
        - "cron_storm":定时任务集中执行
        输出格式:{"root_cause": "...", "suspect_process": "..."}
      input:
        memory_read.affected_ip: "{{ memory_write_alert.entries.affected_ip }}"
        memory_read.current_cpu: "{{ memory_write_alert.entries.current_cpu }}"
      next: memory_write_rootcause

    # 记忆节点:写入根因,决定后续分支
    - id: memory_write_rootcause
      type: memory_write
      entries:
        - key: root_cause
          value: "{{ root_cause_analysis.output.root_cause }}"
        - key: suspect_process
          value: "{{ root_cause_analysis.output.suspect_process }}"
      next: branch_by_rootcause

    # 第三步:条件分支——根据记忆中的根因走不同修复路径
    - id: branch_by_rootcause
      type: switch
      conditions:
        - when: "{{ memory_read.root_cause }} == 'process_stuck'"
          next: kill_stuck_process
        - when: "{{ memory_read.root_cause }} == 'traffic_spike'"
          next: scale_out_service
        - when: "{{ memory_read.root_cause }} == 'cron_storm'"
          next: reschedule_crons
      input:
        memory_read.root_cause: "{{ memory_write_rootcause.entries.root_cause }}"

    # 第四步(分支示例):杀卡死进程
    - id: kill_stuck_process
      type: script
      script_type: bash
      script_content: |
        # 从记忆读取目标主机和可疑进程名
        TARGET_HOST="{{ memory_read.affected_ip }}"
        SUSPECT_PROC="{{ memory_read.suspect_process }}"

        echo "正在处理主机 $TARGET_HOST 上的卡死进程 $SUSPECT_PROC"

        # 通过 SSH 执行远程命令(实际环境中使用 Blueking 的作业平台)
        ssh ops-agent@$TARGET_HOST "ps aux | grep '$SUSPECT_PROC' | grep -v grep | awk '{print \$2}' | head -1 | xargs -r kill -9"

        # 写入执行结果到记忆,供汇报节点使用
        echo "进程 $SUSPECT_PROC 已终止"
      input:
        memory_read.affected_ip: "{{ memory_write_alert.entries.affected_ip }}"
        memory_read.suspect_process: "{{ memory_write_rootcause.entries.suspect_process }}"
      next: memory_write_fix_result

    # 记忆节点:记录修复动作,形成完整闭环
    - id: memory_write_fix_result
      type: memory_write
      entries:
        - key: fix_action
          value: "killed_stuck_process"
        - key: fix_target
          value: "{{ memory_read.affected_ip }}"
        - key: fix_status
          value: "success"
      next: final_report

    # 最终汇报:从记忆中拼装完整上下文
    - id: final_report
      type: llm
      prompt: |
        请生成运维处理报告,以下信息来自工作流记忆:
        - 告警时间:{{ memory_read.alert_time }}
        - 受影响主机:{{ memory_read.affected_ip }}
        - CPU 使用率:{{ memory_read.current_cpu }}%(阈值 {{ memory_read.threshold }}%)
        - 根因:{{ memory_read.root_cause }}
        - 修复动作:{{ memory_read.fix_action }}
        - 修复状态:{{ memory_read.fix_status }}
      input:
        memory_read.alert_time: "{{ memory_write_alert.entries.alert_time }}"
        memory_read.affected_ip: "{{ memory_write_alert.entries.affected_ip }}"
        memory_read.current_cpu: "{{ memory_write_alert.entries.current_cpu }}"
        memory_read.threshold: "{{ memory_write_alert.entries.threshold }}"
        memory_read.root_cause: "{{ memory_write_rootcause.entries.root_cause }}"
        memory_read.fix_action: "{{ memory_write_fix_result.entries.fix_action }}"
        memory_read.fix_status: "{{ memory_write_fix_result.entries.fix_status }}"

说明:以上 YAML 是基于 Blueking Lite 工作流编排逻辑的示意结构,具体字段名以平台实际版本为准。核心思路是——每个关键节点后紧跟一个 memory_write,后续节点通过 memory_read 按 key 取值,而不是把上游 output 直接硬塞进下游 input。

这个编排的确定性体现在:

  1. 告警信息只提取一次,写入记忆后所有节点共享,不会重复解析。
  2. 根因判断结果被钉住,switch 分支读的是记忆里的确定值,不是 LLM 的二次猜测。
  3. 修复动作和结果有据可查,最终汇报节点从记忆拼装完整链路,不需要 LLM 去"回忆"。

记忆节点 vs 纯参数传递:什么时候该用

场景 纯参数传递够用 需要记忆节点
简单线性流程(A→B→C) ✅ 直接链式传参即可 ❌ 过度设计
多分支汇聚(A→B1/B2→C) ⚠️ 参数合并复杂 ✅ 各分支写不同 key,C 一次读取
循环/迭代场景 ❌ 参数无法累积 ✅ 每轮追加写入
跨执行周期复用经验 ❌ 参数生命周期仅当次运行 ✅ 记忆可持久化
需要审计追溯 ⚠️ 要翻每个节点的 log ✅ 记忆本身就是结构化日志

简单说:线性短链用参数,有分支、循环、跨周期就用记忆。别在两节点直连的场景里硬塞一个记忆节点,那只是徒增复杂度。

本周其他更新:Admin 密码到期机制优化

除了记忆节点,本周还优化了系统管理层面的一个实际问题——admin 账号密码到期不再直接锁定

旧机制:密码到期 → 账号锁定 → 管理员必须找另外的管理员或走后台解锁流程。如果只有一个 admin 账号,就彻底卡死了。

新机制:密码到期 → 登录时强制引导修改密码 → 改完即恢复使用。账号始终可登录,只是不改密码就进不了系统。

这个改动看似小,实际影响不小——单 admin 环境下不会再出现"密码过期把自己锁门外"的死锁场景。多 admin 环境下也减少了"帮解锁"的运维负担。

采用建议与注意事项

记忆节点上线前的检查清单:

  • Key 命名规范:建议用 节点id_字段名 格式(如 alert_receiver_affected_ip),避免不同节点写入同名 key 导致覆盖冲突。当前记忆空间是扁平 key-value,没有命名空间隔离。
  • 写入时机:只在"结论已确定"的节点后写记忆。LLM 节点的中间推理过程不要写——那部分不确定,写了反而污染后续判断。
  • 读取校验:下游节点读到记忆值后,加一层基础校验(IP 格式、数值范围等),防止上游写入异常值导致连锁错误。
  • 记忆清理:长期运行的工作流会累积记忆条目。确认平台是否有自动过期机制;如果没有,在最终节点加一个 memory_clear 或手动设置 TTL。
  • 敏感信息:密码、密钥等不要写入记忆——记忆存储未必加密,且最终汇报节点可能把记忆内容输出到聊天窗口。

密码到期机制切换注意:

  • 如果现有环境已有因密码过期被锁定的 admin 账号,升级后需要确认这些账号的状态是否自动解除锁定,还是仍需手动处理。
  • 新机制下,强制改密码的引导页面需要确保密码复杂度策略清晰展示,否则用户可能反复提交不符合要求的密码而无法进入系统。

记忆节点把 AI 工作流从"每步重新猜"拉到了"每步有据可查"的状态。对于运维这种对确定性要求极高的场景,这个能力补上了编排链条里最薄弱的一环——中间状态的可靠传递。如果你已经在 Blueking Lite 上跑 AI 工作流,优先把有分支和循环的场景改成记忆节点驱动;如果还在评估阶段,可以从一个两分支的告警处理流程开始试,感受参数传递和记忆传递的差异。


相关推荐