在这里插入图片描述

每日一句正能量

“重要的不是经历什么,而是如何诠释这些经历。”
同样失业,有人诠释为“我完了”,有人诠释为“终于可以换赛道”。经历是客观事件,诠释是主观选择。把诠释权握在自己手里,人就永远不是命运的受害者。

前言

摘要:随着AI智能体应用的爆发式增长,非技术用户快速构建智能体应用的需求日益迫切。HarmonyOS 6(API 23)引入的鸿蒙智能体框架(HMAF)配合小艺开放平台的四种编排模式,为低代码可视化智能体开发提供了全新可能。本文将实战开发一款面向HarmonyOS PC的"智流工坊"应用,展示如何利用HMAF构建拖拽式可视化智能体编排引擎,通过悬浮导航实现画布与组件库状态实时切换,基于沉浸光感打造"节点即氛围"的编排体验,以及基于多窗口架构构建浮动属性面板、预览窗口和调试控制台窗口的协作开发体验。


一、前言:低代码智能体编排的范式革新

2026年,AI智能体已从技术极客的玩具演变为企业数字化转型的核心引擎。蚂蚁数科Agentar、Dify、Coze等低代码智能体平台的崛起,证明了"可视化编排+智能体协同"模式的巨大市场潜力。然而,这些平台大多运行在Web端,缺乏原生操作系统的深度集成能力。

HarmonyOS 6(API 23)的HMAF框架不仅支持LLM模式、工作流模式、A2A模式和OpenClaw模式四种编排方式,更关键的是将智能体能力下沉至操作系统层,配合**悬浮导航(Float Navigation)沉浸光感(Immersive Light Effects)**特性,为PC端低代码智能体编排带来了"节点即氛围、连线即光效"的全新交互范式。

本文核心亮点

  • 节点类型光效:根据智能体节点类型(LLM节点/工具节点/条件节点/循环节点/输出节点)动态切换环境光色与脉冲节奏
  • 悬浮编排导航:底部悬浮页签替代传统工具栏,支持画布缩放、节点库切换、运行状态实时徽章
  • HMAF可视化编排引擎:基于Agent Framework Kit构建拖拽式节点编排引擎,支持四种编排模式无缝切换
  • 多窗口协作开发:主画布窗口 + 浮动属性面板 + 浮动预览窗口 + 浮动调试控制台窗口的光效联动
  • 运行状态沉浸感知:通过Intents Kit实时理解编排意图,自动调整界面光效与导航形态

在这里插入图片描述

二、核心特性解析与技术选型

2.1 沉浸光感在智能体编排中的价值

HarmonyOS 6的systemMaterialEffect通过模拟物理光照模型,为标题栏和导航组件带来细腻的光晕与反射效果。在智能体编排场景中,这种材质效果能够:

  • 增强节点辨识度:不同节点类型对应不同光色,LLM节点散发智慧紫光、工具节点呈现工具橙光,一眼即可区分
  • 营造编排氛围:玻璃拟态的半透明层让背景光效柔和过渡,营造"在星空中连线"的科技感
  • 状态即时感知:节点运行时光效脉冲变化,成功时泛绿光、失败时泛红光,无需查看日志即可掌握状态

2.2 悬浮导航的编排工作台适配

与传统移动端应用不同,PC端智能体编排工作台需要处理:

  • 高频模式切换:开发者常在LLM模式、工作流模式、A2A模式、OpenClaw模式间快速切换
  • 信息密度平衡:既要保证导航可见,又不能压缩画布编辑区域
  • 鼠标优先交互:悬停预览、右键节点菜单、中键平移画布等桌面级操作

HarmonyOS 6的悬浮页签支持**强(85%)、平衡(70%)、弱(55%)**三档透明度自定义,结合PC端的自由窗口能力,可以实现"需要时出现,专注时隐退"的智能导航体验。

2.3 技术架构选型

技术模块 选用方案 说明
智能体框架 HMAF (HarmonyOS Multi-Agent Framework) 系统级智能体编排能力
意图理解 Intents Kit 拖拽意图实时解析
窗口管理 Window Manager + 子窗口 多窗口协作架构
渲染引擎 Canvas + Gesture 自定义节点画布
状态管理 AppStorage 跨组件/跨窗口状态同步
光效系统 SystemMaterialEffect + 自定义动画 沉浸光感实现

在这里插入图片描述

三、项目实战:"智流工坊"架构设计

3.1 应用场景与功能规划

面向HarmonyOS PC的低代码可视化智能体编排场景,核心功能包括:

功能模块 技术实现 沉浸光感/HMAF应用
主画布窗口 Canvas + Gesture 节点光效、连线流光、吸附高亮
悬浮编排导航 HdsTabs + systemMaterialEffect 玻璃拟态页签,模式徽章
节点库面板 Grid + Drag 节点类型色光效
属性面板 Form + HdsInput 选中节点主题色同步
LLM编排模式 HMAF LLM Mode 智慧紫光效
工作流编排模式 HMAF Workflow Mode 流程蓝光效
A2A编排模式 HMAF A2A Mode 通信青光效
OpenClaw编排模式 HMAF OpenClaw Mode 轻量粉光效
浮动预览窗口 子窗口 + WebView 运行状态光效
浮动调试控制台 子窗口 + List 日志级别颜色编码

3.2 技术架构图

┌─────────────────────────────────────────────────────────────┐
│                    智流工坊 - 智能体编排平台                      │
├─────────────────────────────────────────────────────────────┤
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐         │
│  │ 沉浸光感层   │  │  主画布层    │  │ 悬浮导航层   │         │
│  │ (Ambient)   │  │  (Canvas)   │  │ (FloatNav)  │         │
│  │ 动态环境光   │  │  节点编排    │  │ 模式切换     │         │
│  └─────────────┘  └─────────────┘  └─────────────┘         │
├─────────────────────────────────────────────────────────────┤
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐         │
│  │ 浮动属性面板 │  │ 浮动预览窗口 │  │ 浮动调试控制台│         │
│  │ (SubWindow) │  │ (SubWindow) │  │ (SubWindow) │         │
│  │ 节点配置     │  │ 实时运行效果 │  │ 日志与调试   │         │
│  └─────────────┘  └─────────────┘  └─────────────┘         │
├─────────────────────────────────────────────────────────────┤
│  HMAF编排引擎 (LLM/Workflow/A2A/OpenClaw) + Intents Kit     │
└─────────────────────────────────────────────────────────────┘

四、环境配置与模块依赖

4.1 模块依赖配置

// entry/oh-package.json5
{
  "dependencies": {
    "@kit.UIDesignKit": "^1.0.0",
    "@kit.ArkUI": "^1.0.0",
    "@kit.AgentFrameworkKit": "^1.0.0",
    "@kit.IntentsKit": "^1.0.0",
    "@kit.WindowManagerKit": "^1.0.0"
  }
}

4.2 权限声明(module.json5)

{
  "module": {
    "name": "entry",
    "type": "entry",
    "description": "智流工坊 - 智能体编排平台",
    "mainElement": "EntryAbility",
    "abilities": [
      {
        "name": "EntryAbility",
        "srcEntry": "./ets/entryability/EntryAbility.ets",
        "description": "主编排窗口",
        "icon": "$media:icon",
        "label": "$string:EntryAbility_label",
        "startWindowIcon": "$media:icon",
        "startWindowBackground": "$color:start_window_background",
        "windowMode": "fullscreen",
        "supportWindowMode": ["fullscreen", "split", "float"]
      }
    ],
    "requestPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      },
      {
        "name": "ohos.permission.GET_NETWORK_INFO"
      }
    ]
  }
}

五、核心组件实战

5.1 窗口沉浸配置(EntryAbility.ets)

// entry/src/main/ets/entryability/EntryAbility.ets
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';

export default class EntryAbility extends UIAbility {
  onWindowStageCreate(windowStage: window.WindowStage): void {
    // 加载主页面
    windowStage.loadContent('pages/EditorPage', (err) => {
      if (err.code) {
        console.error('Failed to load content:', JSON.stringify(err));
        return;
      }
      console.info('Succeeded in loading content.');
      
      // 获取主窗口并配置沉浸模式
      let mainWindow = windowStage.getMainWindowSync();
      this.configureImmersiveWindow(mainWindow);
    });
  }

  private configureImmersiveWindow(mainWindow: window.Window): void {
    // 设置窗口全屏布局,移除系统标题栏
    mainWindow.setWindowLayoutFullScreen(true);
    
    // 设置窗口背景为透明,让沉浸光效穿透
    mainWindow.setWindowBackgroundColor('#00000000');
    
    // 设置窗口亮度跟随内容
    mainWindow.setWindowKeepScreenOn(true);
    
    // 监听窗口焦点变化,同步到全局状态
    mainWindow.on('windowFocusChange', (isFocused: boolean) => {
      AppStorage.setOrCreate('window_focused', isFocused);
    });
  }
}

代码亮点

  • setWindowLayoutFullScreen(true):移除系统标题栏,实现真正的无边框沉浸体验
  • setWindowBackgroundColor('#00000000'):透明背景让底层光效层完全可见
  • windowFocusChange监听:窗口焦点状态同步到AppStorage,供全应用组件响应

5.2 沉浸光感标题栏(ImmersiveTitleBar.ets)

// entry/src/main/ets/components/ImmersiveTitleBar.ets
import { HdsNavigation, SystemMaterialEffect } from '@kit.UIDesignKit';

@Component
export struct ImmersiveTitleBar {
  @Prop currentMode: string = 'LLM'; // LLM | Workflow | A2A | OpenClaw
  @State isWindowFocused: boolean = true;
  @State titleBarHeight: number = 48;

  // 编排模式主题色映射
  private modeColors: Map<string, string> = new Map([
    ['LLM', '#7B61FF'],      // 智慧紫
    ['Workflow', '#00B4D8'], // 流程蓝
    ['A2A', '#00C9A7'],      // 通信青
    ['OpenClaw', '#FF6B9D']  // 轻量粉
  ]);

  aboutToAppear(): void {
    // 监听窗口焦点变化,调整光效强度
    AppStorage.watch('window_focused', (focused: boolean) => {
      this.isWindowFocused = focused;
    });
  }

  private getThemeColor(): string {
    return this.modeColors.get(this.currentMode) || '#7B61FF';
  }

  build() {
    HdsNavigation({
      title: `智流工坊 - ${this.currentMode}模式`,
      subtitle: 'HarmonyOS PC 智能体编排',
      // 核心:启用沉浸光感材质
      systemMaterialEffect: SystemMaterialEffect.IMMERSIVE,
      // 背景透明度随焦点状态变化
      backgroundOpacity: this.isWindowFocused ? 0.85 : 0.55,
      // 标题栏高度
      height: this.titleBarHeight,
      // 左侧操作区:编排控制
      leading: this.buildLeadingActions(),
      // 右侧操作区:窗口与设置
      trailing: this.buildTrailingActions()
    })
    .width('100%')
    // 动态光效边框:窗口激活时增强发光
    .border({
      width: { bottom: 1 },
      color: this.isWindowFocused
        ? this.getThemeColor()
        : 'rgba(255,255,255,0.1)'
    })
    .shadow({
      radius: this.isWindowFocused ? 15 : 5,
      color: this.getThemeColor(),
      offsetX: 0,
      offsetY: 2
    })
    .animation({
      duration: 300,
      curve: Curve.EaseInOut
    })
  }

  @Builder
  buildLeadingActions(): void {
    Row({ space: 12 }) {
      // 运行编排按钮
      Button({ type: ButtonType.Circle }) {
        Image($r('app.media.ic_play'))
          .width(18)
          .height(18)
          .fillColor('#FFFFFF')
      }
      .width(32)
      .height(32)
      .backgroundColor('rgba(123, 97, 255, 0.3)')
      .onClick(() => {
        // 触发编排运行
        AppStorage.setOrCreate('agent_action', 'run_workflow');
      })

      // 暂停按钮
      Button({ type: ButtonType.Circle }) {
        Image($r('app.media.ic_pause'))
          .width(18)
          .height(18)
          .fillColor('#FFFFFF')
      }
      .width(32)
      .height(32)
      .backgroundColor('rgba(255, 193, 7, 0.3)')
      .onClick(() => {
        AppStorage.setOrCreate('agent_action', 'pause_workflow');
      })

      // 保存编排按钮
      Button({ type: ButtonType.Circle }) {
        Image($r('app.media.ic_save'))
          .width(18)
          .height(18)
          .fillColor('#FFFFFF')
      }
      .width(32)
      .height(32)
      .backgroundColor('rgba(76, 175, 80, 0.3)')
      .onClick(() => {
        AppStorage.setOrCreate('agent_action', 'save_workflow');
      })
    }
    .padding({ left: 16 })
  }

  @Builder
  buildTrailingActions(): void {
    Row({ space: 12 }) {
      // 打开属性面板
      Button({ type: ButtonType.Circle }) {
        Image($r('app.media.ic_properties'))
          .width(18)
          .height(18)
          .fillColor('#FFFFFF')
      }
      .width(32)
      .height(32)
      .backgroundColor('rgba(255,255,255,0.1)')
      .onClick(() => {
        AppStorage.setOrCreate('window_action', 'open_properties');
      })

      // 打开预览窗口
      Button({ type: ButtonType.Circle }) {
        Image($r('app.media.ic_preview'))
          .width(18)
          .height(18)
          .fillColor('#FFFFFF')
      }
      .width(32)
      .height(32)
      .backgroundColor('rgba(255,255,255,0.1)')
      .onClick(() => {
        AppStorage.setOrCreate('window_action', 'open_preview');
      })

      // 打开调试控制台
      Button({ type: ButtonType.Circle }) {
        Image($r('app.media.ic_terminal'))
          .width(18)
          .height(18)
          .fillColor('#FFFFFF')
      }
      .width(32)
      .height(32)
      .backgroundColor('rgba(255,255,255,0.1)')
      .onClick(() => {
        AppStorage.setOrCreate('window_action', 'open_console');
      })

      // 设置按钮(长按展开透明度调节)
      Button({ type: ButtonType.Circle }) {
        Image($r('app.media.ic_settings'))
          .width(18)
          .height(18)
          .fillColor('#FFFFFF')
      }
      .width(32)
      .height(32)
      .backgroundColor('rgba(255,255,255,0.1)')
      .gesture(
        LongPressGesture({ duration: 500 })
          .onAction(() => {
            AppStorage.setOrCreate('show_transparency_panel', true);
          })
      )
    }
    .padding({ right: 16 })
  }
}

代码亮点

  • SystemMaterialEffect.IMMERSIVE:启用HDS系统级沉浸光感材质,标题栏自动获得物理光照效果
  • 动态backgroundOpacity:窗口失焦时自动降低透明度,减少背景干扰
  • 模式感知光效:根据当前编排模式(LLM/Workflow/A2A/OpenClaw)动态切换主题色,从标题栏发光到边框颜色形成统一视觉语言
  • 微交互动画:所有状态变化均配备300ms的缓动动画,视觉过渡自然流畅

5.3 智能体节点画布(AgentCanvas.ets)

// entry/src/main/ets/components/AgentCanvas.ets
import { HMAFAgent, HMAFNodeType } from '@kit.AgentFrameworkKit';

interface AgentNode {
  id: string;
  type: HMAFNodeType;
  x: number;
  y: number;
  label: string;
  config: Record<string, any>;
  status: 'idle' | 'running' | 'success' | 'error';
}

interface AgentEdge {
  id: string;
  from: string;
  to: string;
  label?: string;
}

@Component
export struct AgentCanvas {
  @State nodes: AgentNode[] = [];
  @State edges: AgentEdge[] = [];
  @State selectedNodeId: string = '';
  @State scale: number = 1.0;
  @State offsetX: number = 0;
  @State offsetY: number = 0;
  @State isDragging: boolean = false;
  @State dragStartX: number = 0;
  @State dragStartY: number = 0;

  // 节点类型光色映射
  private nodeColors: Map<HMAFNodeType, string> = new Map([
    [HMAFNodeType.LLM, '#7B61FF'],      // 智慧紫
    [HMAFNodeType.TOOL, '#FF9F1C'],     // 工具橙
    [HMAFNodeType.CONDITION, '#00C9A7'], // 条件青
    [HMAFNodeType.LOOP, '#FF6B9D'],      // 循环粉
    [HMAFNodeType.OUTPUT, '#4CC9F0']     // 输出蓝
  ]);

  // 节点状态光效映射
  private statusEffects: Map<string, { color: string; pulse: boolean }> = new Map([
    ['idle', { color: 'rgba(255,255,255,0.6)', pulse: false }],
    ['running', { color: '#00E676', pulse: true }],
    ['success', { color: '#00C853', pulse: false }],
    ['error', { color: '#FF1744', pulse: true }]
  ]);

  aboutToAppear(): void {
    // 初始化示例编排:LLM -> 工具 -> 输出
    this.nodes = [
      { id: 'n1', type: HMAFNodeType.LLM, x: 200, y: 200, label: 'GPT-4o', config: { model: 'gpt-4o' }, status: 'idle' },
      { id: 'n2', type: HMAFNodeType.TOOL, x: 400, y: 200, label: '搜索工具', config: { tool: 'web_search' }, status: 'idle' },
      { id: 'n3', type: HMAFNodeType.OUTPUT, x: 600, y: 200, label: '结果输出', config: { format: 'markdown' }, status: 'idle' }
    ];
    this.edges = [
      { id: 'e1', from: 'n1', to: 'n2', label: '查询' },
      { id: 'e2', from: 'n2', to: 'n3', label: '结果' }
    ];
  }

  build() {
    Stack() {
      // 网格背景层
      this.buildGridBackground()

      // 连线层
      Canvas(this.context2D)
        .width('100%')
        .height('100%')
        .onReady((context) => {
          this.drawEdges(context);
        })

      // 节点层
      ForEach(this.nodes, (node: AgentNode) => {
        this.buildNode(node)
      }, (node: AgentNode) => node.id)

      // 拖拽遮罩层
      if (this.isDragging) {
        Column()
          .width('100%')
          .height('100%')
          .backgroundColor('rgba(123, 97, 255, 0.05)')
          .border({ width: 2, color: '#7B61FF', style: BorderStyle.Dashed })
      }
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#0a0a0f')
    .gesture(
      PanGesture()
        .onActionStart((event) => {
          this.isDragging = true;
          this.dragStartX = event.offsetX;
          this.dragStartY = event.offsetY;
        })
        .onActionUpdate((event) => {
          this.offsetX += event.offsetX - this.dragStartX;
          this.offsetY += event.offsetY - this.dragStartY;
          this.dragStartX = event.offsetX;
          this.dragStartY = event.offsetY;
        })
        .onActionEnd(() => {
          this.isDragging = false;
        })
    )
    .scale({ x: this.scale, y: this.scale })
    .translate({ x: this.offsetX, y: this.offsetY })
  }

  @Builder
  buildGridBackground(): void {
    Column()
      .width('100%')
      .height('100%')
      .backgroundImage($r('app.media.grid_pattern'))
      .backgroundImageSize({ width: '40px', height: '40px' })
      .backgroundImagePosition({ x: 0, y: 0 })
      .opacity(0.3)
  }

  @Builder
  buildNode(node: AgentNode): void {
    Stack() {
      // 节点光晕效果
      Column()
        .width(120)
        .height(120)
        .backgroundColor(this.nodeColors.get(node.type))
        .blur(40)
        .opacity(this.getNodeGlowOpacity(node))
        .position({ x: 0, y: 0 })
        .animation({
          duration: 2000,
          curve: Curve.EaseInOut,
          iterations: node.status === 'running' ? -1 : 0,
          playMode: PlayMode.Alternate
        })
        .scale({ x: 1.5, y: 1.5 })

      // 节点主体
      Column() {
        // 节点图标
        Image(this.getNodeIcon(node.type))
          .width(32)
          .height(32)
          .fillColor('#FFFFFF')
          .margin({ top: 12 })

        // 节点标签
        Text(node.label)
          .fontSize(12)
          .fontColor('#FFFFFF')
          .margin({ top: 8, bottom: 8 })

        // 状态指示灯
        Row() {
          Circle()
            .width(8)
            .height(8)
            .fill(this.statusEffects.get(node.status)?.color || '#FFFFFF')
            .animation({
              duration: 1000,
              curve: Curve.EaseInOut,
              iterations: this.statusEffects.get(node.status)?.pulse ? -1 : 0,
              playMode: PlayMode.Alternate
            })
            .scale({ x: 1.3, y: 1.3 })
        }
        .justifyContent(FlexAlign.Center)
        .width('100%')
      }
      .width(100)
      .height(100)
      .backgroundColor('rgba(30, 30, 40, 0.9)')
      .border({
        width: 2,
        color: this.selectedNodeId === node.id ? this.nodeColors.get(node.type) : 'rgba(255,255,255,0.2)'
      })
      .borderRadius(16)
      .shadow({
        radius: 10,
        color: this.nodeColors.get(node.type),
        offsetX: 0,
        offsetY: 4
      })
      .position({ x: node.x, y: node.y })
      .onClick(() => {
        this.selectedNodeId = node.id;
        AppStorage.setOrCreate('selected_node', node);
      })
      .gesture(
        LongPressGesture({ duration: 300 })
          .onAction(() => {
            // 长按打开属性面板
            AppStorage.setOrCreate('window_action', 'open_properties');
            AppStorage.setOrCreate('selected_node', node);
          })
      )
    }
  }

  private getNodeGlowOpacity(node: AgentNode): number {
    if (node.status === 'running') return 0.6;
    if (node.status === 'success') return 0.4;
    if (node.status === 'error') return 0.5;
    return 0.2;
  }

  private getNodeIcon(type: HMAFNodeType): Resource {
    switch (type) {
      case HMAFNodeType.LLM: return $r('app.media.ic_llm');
      case HMAFNodeType.TOOL: return $r('app.media.ic_tool');
      case HMAFNodeType.CONDITION: return $r('app.media.ic_condition');
      case HMAFNodeType.LOOP: return $r('app.media.ic_loop');
      case HMAFNodeType.OUTPUT: return $r('app.media.ic_output');
      default: return $r('app.media.ic_node');
    }
  }

  private drawEdges(context: CanvasRenderingContext2D): void {
    context.strokeStyle = 'rgba(123, 97, 255, 0.6)';
    context.lineWidth = 2;
    context.setLineDash([5, 5]);

    this.edges.forEach(edge => {
      const fromNode = this.nodes.find(n => n.id === edge.from);
      const toNode = this.nodes.find(n => n.id === edge.to);
      if (!fromNode || !toNode) return;

      // 绘制贝塞尔曲线连线
      const startX = fromNode.x + 100;
      const startY = fromNode.y + 50;
      const endX = toNode.x;
      const endY = toNode.y + 50;
      const cpX = (startX + endX) / 2;
      const cpY = startY;

      context.beginPath();
      context.moveTo(startX, startY);
      context.quadraticCurveTo(cpX, cpY, endX, endY);
      context.stroke();

      // 绘制连线标签
      if (edge.label) {
        context.fillStyle = 'rgba(255,255,255,0.8)';
        context.font = '12px sans-serif';
        context.fillText(edge.label, cpX - 20, cpY - 10);
      }
    });
  }
}

代码亮点

  • 节点类型光效:每种节点类型(LLM/工具/条件/循环/输出)拥有专属光色,从背景光晕到边框阴影统一主题
  • 状态呼吸灯:节点运行中时绿色光晕脉冲呼吸,错误时红色脉冲,成功时稳定绿光,无需查看日志即可掌握状态
  • 贝塞尔连线:使用Canvas绘制流畅的二次贝塞尔曲线,配合虚线流动效果,呈现"数据流"视觉隐喻
  • 长按属性:长按节点自动打开浮动属性面板,符合PC端右键/长按的交互习惯

5.4 悬浮编排导航(FloatNavigation.ets)

// entry/src/main/ets/components/FloatNavigation.ets
import { HdsTabs, HdsTabItem } from '@kit.UIDesignKit';

export enum TransparencyLevel {
  STRONG = 0.85,
  BALANCED = 0.70,
  WEAK = 0.55
}

@Component
export struct FloatNavigation {
  @State currentMode: string = 'LLM';
  @State transparency: number = TransparencyLevel.BALANCED;
  @State isExpanded: boolean = false;
  @State avoidHeight: number = 0;

  // 编排模式配置
  private modes: HdsTabItem[] = [
    { icon: $r('app.media.ic_llm'), label: 'LLM', badge: 0 },
    { icon: $r('app.media.ic_workflow'), label: '工作流', badge: 0 },
    { icon: $r('app.media.ic_a2a'), label: 'A2A', badge: 0 },
    { icon: $r('app.media.ic_openclaw'), label: 'OpenClaw', badge: 2 }
  ];

  aboutToAppear(): void {
    // 获取底部安全区高度
    let windowInstance = window.getLastWindow(getContext(this));
    windowInstance.then((win) => {
      let avoidArea = win.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR);
      this.avoidHeight = avoidArea.bottomRect.height;
    });
  }

  build() {
    Stack({ alignContent: Alignment.Bottom }) {
      // 悬浮导航主体
      Column() {
        HdsTabs({
          items: this.modes,
          selectedIndex: this.getModeIndex(),
          onSelect: (index: number) => {
            this.currentMode = this.modes[index].label === 'LLM' ? 'LLM' :
                               this.modes[index].label === '工作流' ? 'Workflow' :
                               this.modes[index].label === 'A2A' ? 'A2A' : 'OpenClaw';
            AppStorage.setOrCreate('current_mode', this.currentMode);
          },
          // 玻璃拟态背景
          backgroundStyle: {
            blurStyle: BlurStyle.REGULAR,
            backgroundColor: `rgba(20, 20, 30, ${this.transparency})`,
            borderRadius: 24
          },
          // 选中指示器光效
          indicatorStyle: {
            color: this.getModeColor(),
            height: 3,
            width: 24,
            borderRadius: 2
          }
        })
        .height(56)
        .width('96%')
        .margin({ bottom: 12 })

        // 透明度调节条(展开时显示)
        if (this.isExpanded) {
          Row() {
            Text('透明度').fontSize(12).fontColor('rgba(255,255,255,0.6)')
            Slider({
              value: this.transparency * 100,
              min: 55,
              max: 85,
              step: 15
            })
            .width(200)
            .onChange((value: number) => {
              this.transparency = value / 100;
            })
          }
          .width('96%')
          .height(40)
          .backgroundColor('rgba(20, 20, 30, 0.8)')
          .borderRadius(16)
          .justifyContent(FlexAlign.SpaceBetween)
          .padding({ left: 16, right: 16 })
          .animation({
            duration: 200,
            curve: Curve.EaseInOut
          })
        }
      }
      .width('100%')
      .padding({ bottom: this.avoidHeight + 12 })
    }
    .width('100%')
    .height('100%')
    .pointerEvents(PointerEvents.BoxNone) // 允许点击穿透到画布
  }

  private getModeIndex(): number {
    switch (this.currentMode) {
      case 'LLM': return 0;
      case 'Workflow': return 1;
      case 'A2A': return 2;
      case 'OpenClaw': return 3;
      default: return 0;
    }
  }

  private getModeColor(): string {
    switch (this.currentMode) {
      case 'LLM': return '#7B61FF';
      case 'Workflow': return '#00B4D8';
      case 'A2A': return '#00C9A7';
      case 'OpenClaw': return '#FF6B9D';
      default: return '#7B61FF';
    }
  }
}

代码亮点

  • 玻璃拟态导航BlurStyle.REGULAR配合动态透明度,实现悬浮于画布之上的玻璃质感
  • 模式徽章:OpenClaw模式显示数字徽章,提示有新插件可用
  • 透明度三档调节:强(85%)/平衡(70%)/弱(55%),通过Slider实时调节
  • 点击穿透pointerEvents(BoxNone)确保导航不遮挡画布操作,鼠标可穿透到下层节点

5.5 多窗口光效同步管理器(WindowManager.ets)

// entry/src/main/ets/utils/WindowManager.ets
import { window } from '@kit.ArkUI';

export class WindowManager {
  private static instance: WindowManager;
  private subWindows: Map<string, window.Window> = new Map();
  private themeColor: string = '#7B61FF';

  static getInstance(): WindowManager {
    if (!WindowManager.instance) {
      WindowManager.instance = new WindowManager();
    }
    return WindowManager.instance;
  }

  // 同步全局光效主题色
  syncGlobalLightEffect(color: string): void {
    this.themeColor = color;
    // 广播到所有子窗口
    this.subWindows.forEach((win, name) => {
      win.setWindowBackgroundColor(this.hexToRgba(color, 0.05));
    });
  }

  // 打开属性面板窗口
  async openPropertiesWindow(): Promise<void> {
    if (this.subWindows.has('properties')) {
      await this.subWindows.get('properties')?.show();
      return;
    }

    let mainWindow = await window.getLastWindow(getContext());
    let subWindow = await window.createSubWindow(getContext(), 'properties');
    
    await subWindow.moveWindowTo(1200, 100);
    await subWindow.resize(320, 600);
    await subWindow.setWindowBackgroundColor(this.hexToRgba(this.themeColor, 0.05));
    await subWindow.setWindowCornerRadius(16);
    await subWindow.setWindowShadow({
      radius: 20,
      color: this.themeColor,
      offsetX: 0,
      offsetY: 8
    });
    await subWindow.loadContent('pages/PropertiesPage');
    await subWindow.show();

    this.subWindows.set('properties', subWindow);
  }

  // 打开预览窗口
  async openPreviewWindow(): Promise<void> {
    if (this.subWindows.has('preview')) {
      await this.subWindows.get('preview')?.show();
      return;
    }

    let subWindow = await window.createSubWindow(getContext(), 'preview');
    await subWindow.moveWindowTo(200, 700);
    await subWindow.resize(600, 400);
    await subWindow.setWindowBackgroundColor('#0a0a0f');
    await subWindow.setWindowCornerRadius(16);
    await subWindow.setWindowShadow({
      radius: 20,
      color: this.themeColor,
      offsetX: 0,
      offsetY: 8
    });
    await subWindow.loadContent('pages/PreviewPage');
    await subWindow.show();

    this.subWindows.set('preview', subWindow);
  }

  // 打开调试控制台窗口
  async openConsoleWindow(): Promise<void> {
    if (this.subWindows.has('console')) {
      await this.subWindows.get('console')?.show();
      return;
    }

    let subWindow = await window.createSubWindow(getContext(), 'console');
    await subWindow.moveWindowTo(800, 700);
    await subWindow.resize(500, 300);
    await subWindow.setWindowBackgroundColor('#0d0d12');
    await subWindow.setWindowCornerRadius(12);
    await subWindow.setWindowShadow({
      radius: 15,
      color: '#00E676',
      offsetX: 0,
      offsetY: 6
    });
    await subWindow.loadContent('pages/ConsolePage');
    await subWindow.show();

    this.subWindows.set('console', subWindow);
  }

  private hexToRgba(hex: string, alpha: number): string {
    const r = parseInt(hex.slice(1, 3), 16);
    const g = parseInt(hex.slice(3, 5), 16);
    const b = parseInt(hex.slice(5, 7), 16);
    return `rgba(${r}, ${g}, ${b}, ${alpha})`;
  }
}

代码亮点

  • 子窗口独立生命周期:每个浮动窗口(属性/预览/控制台)独立管理,支持多次打开/关闭
  • 光效主题同步syncGlobalLightEffect将主窗口主题色广播到所有子窗口,实现跨窗口光效联动
  • 差异化阴影:属性面板跟随主色调、控制台使用绿色阴影(日志主题),视觉区分清晰
  • 圆角与阴影:所有子窗口统一16px圆角+动态阴影,保持设计语言一致性

5.6 属性面板窗口(PropertiesPage.ets)

// entry/src/main/ets/pages/PropertiesPage.ets
@Component
struct PropertiesPage {
  @State selectedNode: AgentNode | null = null;
  @State themeColor: string = '#7B61FF';

  aboutToAppear(): void {
    AppStorage.watch('selected_node', (node: AgentNode) => {
      this.selectedNode = node;
    });
    AppStorage.watch('current_mode', (mode: string) => {
      this.themeColor = this.getModeColor(mode);
    });
  }

  private getModeColor(mode: string): string {
    const colors: Map<string, string> = new Map([
      ['LLM', '#7B61FF'],
      ['Workflow', '#00B4D8'],
      ['A2A', '#00C9A7'],
      ['OpenClaw', '#FF6B9D']
    ]);
    return colors.get(mode) || '#7B61FF';
  }

  build() {
    Column() {
      // 面板标题栏(带光效)
      Row() {
        Text('节点属性')
          .fontSize(16)
          .fontWeight(FontWeight.Bold)
          .fontColor('#FFFFFF')
        
        Circle()
          .width(10)
          .height(10)
          .fill(this.themeColor)
          .shadow({ radius: 8, color: this.themeColor })
      }
      .width('100%')
      .height(48)
      .padding({ left: 16, right: 16 })
      .justifyContent(FlexAlign.SpaceBetween)
      .backgroundColor('rgba(255,255,255,0.05)')
      .border({ width: { bottom: 1 }, color: 'rgba(255,255,255,0.1)' })

      // 节点配置表单
      if (this.selectedNode) {
        Scroll() {
          Column({ space: 16 }) {
            // 节点类型标识
            Row() {
              Image(this.getNodeIcon(this.selectedNode.type))
                .width(24)
                .height(24)
                .fillColor(this.themeColor)
              Text(this.selectedNode.type)
                .fontSize(14)
                .fontColor(this.themeColor)
                .margin({ left: 8 })
            }
            .width('100%')
            .padding(12)
            .backgroundColor('rgba(255,255,255,0.03)')
            .borderRadius(8)

            // 节点名称
            Column({ space: 4 }) {
              Text('节点名称').fontSize(12).fontColor('rgba(255,255,255,0.6)')
              TextInput({ text: this.selectedNode.label })
                .width('100%')
                .height(40)
                .backgroundColor('rgba(255,255,255,0.05)')
                .fontColor('#FFFFFF')
                .borderRadius(8)
            }

            // 配置参数(根据节点类型动态渲染)
            this.buildNodeConfig(this.selectedNode)

            // 操作按钮
            Row({ space: 12 }) {
              Button('应用')
                .width(100)
                .height(36)
                .backgroundColor(this.themeColor)
                .fontColor('#FFFFFF')
                .onClick(() => {
                  AppStorage.setOrCreate('agent_action', 'update_node');
                })

              Button('删除')
                .width(100)
                .height(36)
                .backgroundColor('rgba(255, 23, 68, 0.2)')
                .fontColor('#FF1744')
                .onClick(() => {
                  AppStorage.setOrCreate('agent_action', 'delete_node');
                })
            }
            .width('100%')
            .justifyContent(FlexAlign.Center)
            .margin({ top: 20 })
          }
          .width('100%')
          .padding(16)
        }
        .layoutWeight(1)
      } else {
        // 未选中节点提示
        Column() {
          Image($r('app.media.ic_empty'))
            .width(64)
            .height(64)
            .opacity(0.3)
          Text('在画布中选择节点以编辑属性')
            .fontSize(14)
            .fontColor('rgba(255,255,255,0.4)')
            .margin({ top: 12 })
        }
        .width('100%')
        .layoutWeight(1)
        .justifyContent(FlexAlign.Center)
      }
    }
    .width('100%')
    .height('100%')
    .backgroundColor('rgba(15, 15, 25, 0.95)')
    .borderRadius(16)
  }

  @Builder
  buildNodeConfig(node: AgentNode): void {
    switch (node.type) {
      case HMAFNodeType.LLM:
        this.buildLLMConfig(node);
        break;
      case HMAFNodeType.TOOL:
        this.buildToolConfig(node);
        break;
      default:
        this.buildGenericConfig(node);
    }
  }

  @Builder
  buildLLMConfig(node: AgentNode): void {
    Column({ space: 12 }) {
      Column({ space: 4 }) {
        Text('模型选择').fontSize(12).fontColor('rgba(255,255,255,0.6)')
        Select([
          { value: 'gpt-4o', icon: $r('app.media.ic_openai') },
          { value: 'claude-3-5', icon: $r('app.media.ic_anthropic') },
          { value: 'qwen-2-5', icon: $r('app.media.ic_qwen') }
        ])
        .width('100%')
        .height(40)
        .selected(node.config.model || 'gpt-4o')
      }

      Column({ space: 4 }) {
        Text('温度').fontSize(12).fontColor('rgba(255,255,255,0.6)')
        Slider({ value: node.config.temperature || 0.7, min: 0, max: 2, step: 0.1 })
          .width('100%')
          .trackColor(this.themeColor)
      }

      Column({ space: 4 }) {
        Text('系统提示词').fontSize(12).fontColor('rgba(255,255,255,0.6)')
        TextArea({ text: node.config.systemPrompt || '' })
          .width('100%')
          .height(120)
          .backgroundColor('rgba(255,255,255,0.05)')
          .fontColor('#FFFFFF')
          .borderRadius(8)
      }
    }
  }

  @Builder
  buildToolConfig(node: AgentNode): void {
    Column({ space: 12 }) {
      Column({ space: 4 }) {
        Text('工具类型').fontSize(12).fontColor('rgba(255,255,255,0.6)')
        Select([
          { value: 'web_search', icon: $r('app.media.ic_search') },
          { value: 'code_executor', icon: $r('app.media.ic_code') },
          { value: 'file_reader', icon: $r('app.media.ic_file') }
        ])
        .width('100%')
        .height(40)
        .selected(node.config.tool || 'web_search')
      }
    }
  }

  private getNodeIcon(type: HMAFNodeType): Resource {
    // 同AgentCanvas中的实现
    return $r('app.media.ic_node');
  }
}

5.7 调试控制台窗口(ConsolePage.ets)

// entry/src/main/ets/pages/ConsolePage.ets
interface LogEntry {
  timestamp: string;
  level: 'info' | 'warn' | 'error' | 'debug';
  message: string;
  nodeId?: string;
}

@Component
struct ConsolePage {
  @State logs: LogEntry[] = [];
  @State filterLevel: string = 'all';
  @State autoScroll: boolean = true;

  // 日志级别颜色
  private levelColors: Map<string, string> = new Map([
    ['info', '#4CC9F0'],
    ['warn', '#FF9F1C'],
    ['error', '#FF1744'],
    ['debug', '#9C27B0']
  ]);

  aboutToAppear(): void {
    // 监听全局日志
    AppStorage.watch('agent_log', (log: LogEntry) => {
      this.logs.push(log);
      if (this.logs.length > 1000) {
        this.logs.shift(); // 限制日志数量
      }
    });
  }

  build() {
    Column() {
      // 控制台标题栏
      Row() {
        Text('调试控制台')
          .fontSize(14)
          .fontWeight(FontWeight.Medium)
          .fontColor('#00E676')
        
        Row({ space: 8 }) {
          // 日志级别筛选
          Select([
            { value: 'all' },
            { value: 'info' },
            { value: 'warn' },
            { value: 'error' },
            { value: 'debug' }
          ])
          .width(100)
          .height(28)
          .selected(this.filterLevel)
          .onSelect((index: number) => {
            this.filterLevel = ['all', 'info', 'warn', 'error', 'debug'][index];
          })

          // 自动滚动开关
          Toggle({ type: ToggleType.Checkbox, isOn: this.autoScroll })
            .selectedColor('#00E676')
            .onChange((isOn: boolean) => {
              this.autoScroll = isOn;
            })
        }
      }
      .width('100%')
      .height(36)
      .padding({ left: 12, right: 12 })
      .justifyContent(FlexAlign.SpaceBetween)
      .backgroundColor('rgba(0, 230, 118, 0.05)')
      .border({ width: { bottom: 1 }, color: 'rgba(0, 230, 118, 0.2)' })

      // 日志列表
      List({ space: 2 }) {
        ForEach(this.getFilteredLogs(), (log: LogEntry, index: number) => {
          ListItem() {
            Row({ space: 8 }) {
              // 时间戳
              Text(log.timestamp)
                .fontSize(10)
                .fontColor('rgba(255,255,255,0.4)')
                .width(80)

              // 级别标识
              Text(log.level.toUpperCase())
                .fontSize(10)
                .fontWeight(FontWeight.Bold)
                .fontColor(this.levelColors.get(log.level) || '#FFFFFF')
                .width(50)
                .textAlign(TextAlign.Center)

              // 节点标识
              if (log.nodeId) {
                Text(`[${log.nodeId}]`)
                  .fontSize(10)
                  .fontColor('rgba(255,255,255,0.5)')
                  .width(80)
              }

              // 日志内容
              Text(log.message)
                .fontSize(12)
                .fontColor('#FFFFFF')
                .layoutWeight(1)
                .maxLines(3)
                .textOverflow({ overflow: TextOverflow.Ellipsis })
            }
            .width('100%')
            .padding({ left: 12, right: 12, top: 6, bottom: 6 })
            .backgroundColor(index % 2 === 0 ? 'rgba(255,255,255,0.02)' : 'transparent')
          }
        }, (log: LogEntry, index: number) => `${log.timestamp}-${index}`)
      }
      .width('100%')
      .layoutWeight(1)
      .edgeEffect(EdgeEffect.Spring)
      .scrollBar(BarState.Auto)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('rgba(13, 13, 18, 0.98)')
    .borderRadius(12)
  }

  private getFilteredLogs(): LogEntry[] {
    if (this.filterLevel === 'all') return this.logs;
    return this.logs.filter(log => log.level === this.filterLevel);
  }
}

5.8 主页面集成(EditorPage.ets)

// entry/src/main/ets/pages/EditorPage.ets
import { ImmersiveTitleBar } from '../components/ImmersiveTitleBar';
import { AgentCanvas } from '../components/AgentCanvas';
import { FloatNavigation } from '../components/FloatNavigation';
import { WindowManager } from '../utils/WindowManager';

@Entry
@Component
struct EditorPage {
  @State currentMode: string = 'LLM';
  @State themeColor: string = '#7B61FF';
  @State lightIntensity: number = 0.6;

  aboutToAppear(): void {
    // 监听编排模式变化
    AppStorage.watch('current_mode', (mode: string) => {
      this.currentMode = mode;
      this.themeColor = this.getModeColor(mode);
      WindowManager.getInstance().syncGlobalLightEffect(this.themeColor);
    });

    // 监听窗口操作
    AppStorage.watch('window_action', (action: string) => {
      switch (action) {
        case 'open_properties':
          WindowManager.getInstance().openPropertiesWindow();
          break;
        case 'open_preview':
          WindowManager.getInstance().openPreviewWindow();
          break;
        case 'open_console':
          WindowManager.getInstance().openConsoleWindow();
          break;
      }
      // 重置操作
      AppStorage.setOrCreate('window_action', '');
    });
  }

  private getModeColor(mode: string): string {
    const colors: Map<string, string> = new Map([
      ['LLM', '#7B61FF'],
      ['Workflow', '#00B4D8'],
      ['A2A', '#00C9A7'],
      ['OpenClaw', '#FF6B9D']
    ]);
    return colors.get(mode) || '#7B61FF';
  }

  build() {
    Stack() {
      // 第一层:动态环境光背景
      this.buildAmbientLightLayer()

      // 第二层:内容层
      Column() {
        // 沉浸光感标题栏
        ImmersiveTitleBar({ currentMode: this.currentMode })

        // 智能体编排画布
        AgentCanvas()
          .layoutWeight(1)
      }
      .width('100%')
      .height('100%')

      // 第三层:悬浮编排导航
      FloatNavigation()
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#0a0a0f')
    .expandSafeArea(
      [SafeAreaType.SYSTEM],
      [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM, SafeAreaEdge.START, SafeAreaEdge.END]
    )
  }

  @Builder
  buildAmbientLightLayer(): void {
    Column() {
      // 主光晕 - 随模式变色
      Column()
        .width(600)
        .height(600)
        .backgroundColor(this.themeColor)
        .blur(200)
        .opacity(this.lightIntensity * 0.3)
        .position({ x: '50%', y: '30%' })
        .anchor('50%')
        .animation({
          duration: 8000,
          curve: Curve.EaseInOut,
          iterations: -1,
          playMode: PlayMode.Alternate
        })
        .scale({ x: 1.5, y: 1.5 })

      // 底部反射
      Column()
        .width('100%')
        .height(300)
        .backgroundColor(this.themeColor)
        .opacity(this.lightIntensity * 0.08)
        .blur(150)
        .position({ x: 0, y: '70%' })
        .linearGradient({
          direction: GradientDirection.Top,
          colors: [
            [this.themeColor, 0.0],
            ['transparent', 1.0]
          ]
        })
        .animation({
          duration: 10000,
          curve: Curve.EaseInOut,
          iterations: -1,
          playMode: PlayMode.Alternate
        })

      // 粒子光点(模拟数据流)
      ForEach([1, 2, 3, 4, 5], (index: number) => {
        Circle()
          .width(4)
          .height(4)
          .backgroundColor(this.themeColor)
          .opacity(0.6)
          .position({
            x: `${20 + index * 15}%`,
            y: `${30 + index * 10}%`
          })
          .animation({
            duration: 3000 + index * 500,
            curve: Curve.EaseInOut,
            iterations: -1,
            playMode: PlayMode.Alternate
          })
          .translate({ y: -20 })
      })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#050508')
  }
}

代码亮点

  • 三层架构:环境光层 → 内容层 → 悬浮导航层,层次分明
  • 模式感知环境光:切换编排模式时,整个背景光晕颜色随之变化,LLM模式紫色、工作流模式蓝色、A2A模式青色、OpenClaw模式粉色
  • 呼吸动画:主光晕8秒循环呼吸、底部反射10秒循环,营造"活"的界面氛围
  • 数据流粒子:5个光点模拟数据在节点间流动,增强编排的动态感
  • 安全区扩展expandSafeArea让内容延伸至所有屏幕边缘,实现真正的全屏沉浸

六、HMAF智能体编排引擎集成

6.1 创建智能体会话

// entry/src/main/ets/engine/AgentEngine.ets
import { hmaf } from '@kit.AgentFrameworkKit';
import { intents } from '@kit.IntentsKit';

export class AgentEngine {
  private session: hmaf.AgentSession | null = null;
  private intentEngine: intents.IntentEngine | null = null;

  async initialize(mode: 'LLM' | 'Workflow' | 'A2A' | 'OpenClaw'): Promise<void> {
    // 创建智能体会话
    this.session = await hmaf.createAgentSession({
      mode: mode === 'LLM' ? hmaf.AgentMode.LLM :
            mode === 'Workflow' ? hmaf.AgentMode.WORKFLOW :
            mode === 'A2A' ? hmaf.AgentMode.A2A : hmaf.AgentMode.OPENCLAW,
      enableDistributed: true, // 启用分布式能力
      maxConcurrentAgents: 10
    });

    // 创建意图引擎
    this.intentEngine = await intents.createIntentEngine({
      supportedDomains: ['agent.orchestration', 'node.creation', 'edge.connection'],
      confidenceThreshold: 0.8
    });

    // 监听编排事件
    this.session.on('taskCompleted', (result) => {
      AppStorage.setOrCreate('agent_log', {
        timestamp: new Date().toISOString(),
        level: 'info',
        message: `任务完成: ${result.taskId}`,
        nodeId: result.nodeId
      });
    });

    this.session.on('taskFailed', (error) => {
      AppStorage.setOrCreate('agent_log', {
        timestamp: new Date().toISOString(),
        level: 'error',
        message: `任务失败: ${error.message}`,
        nodeId: error.nodeId
      });
    });
  }

  // 执行编排
  async executeWorkflow(nodes: AgentNode[], edges: AgentEdge[]): Promise<void> {
    if (!this.session) return;

    // 构建HMAF任务图
    const taskGraph = this.buildTaskGraph(nodes, edges);
    
    // 提交编排任务
    await this.session.sendTask({
      targetAgent: 'orchestrator',
      taskType: hmaf.TaskType.WORKFLOW_EXECUTION,
      payload: taskGraph
    });
  }

  private buildTaskGraph(nodes: AgentNode[], edges: AgentEdge[]): any {
    return {
      nodes: nodes.map(n => ({
        id: n.id,
        type: n.type,
        config: n.config,
        agentId: `agent_${n.id}`
      })),
      edges: edges.map(e => ({
        from: e.from,
        to: e.to,
        condition: e.label
      }))
    };
  }
}

6.2 意图驱动的智能编排

// entry/src/main/ets/engine/IntentOrchestrator.ets
export class IntentOrchestrator {
  private engine: AgentEngine;

  constructor() {
    this.engine = new AgentEngine();
  }

  // 解析用户拖拽意图
  async parseDragIntent(
    startNode: AgentNode, 
    endNode: AgentNode, 
    gestureType: string
  ): Promise<string> {
    const intent = await this.engine.intentEngine?.process({
      action: gestureType === 'long_press' ? 'create_connection' : 'move_node',
      entities: [
        { type: 'node', value: startNode.id },
        { type: 'node', value: endNode.id },
        { type: 'node_type', value: startNode.type }
      ]
    });

    if (intent?.confidence && intent.confidence > 0.8) {
      return intent.action;
    }
    return 'unknown';
  }

  // 根据意图自动调整光效
  async applyIntentLightEffect(intent: string): Promise<void> {
    switch (intent) {
      case 'create_connection':
        // 连线时触发流光动画
        AppStorage.setOrCreate('light_effect', 'connection_flow');
        break;
      case 'delete_node':
        // 删除时红色闪烁警示
        AppStorage.setOrCreate('light_effect', 'delete_warning');
        break;
      case 'run_workflow':
        // 运行时全屏绿色脉冲
        AppStorage.setOrCreate('light_effect', 'running_pulse');
        break;
    }
  }
}

在这里插入图片描述

七、关键技术总结

7.1 HMAF可视化编排开发清单

技术点 API/方法 应用场景
智能体会话创建 hmaf.createAgentSession({ mode: MULTI_AGENT }) 多智能体协作编排
意图解析 intents.createIntentEngine({ supportedDomains }) 用户拖拽意图理解
任务分发 hmafSession.sendTask({ targetAgent, taskType }) 智能体间编排任务调度
状态监听 AppStorage 全局状态回调 跨组件编排状态同步
分布式协同 enableDistributed: true 多设备编排协作
四种编排模式 LLM/Workflow/A2A/OpenClaw 不同场景模式切换

7.2 沉浸光感实现清单

技术点 API/方法 应用场景
系统材质效果 systemMaterialEffect: SystemMaterialEffect.IMMERSIVE HdsNavigation标题栏
背景模糊 backgroundBlurStyle(BlurStyle.REGULAR) 悬浮导航玻璃拟态
背景滤镜 backdropFilter($r('sys.blur.20')) 精细模糊控制
安全区扩展 expandSafeArea([SafeAreaType.SYSTEM], [...]) 全屏沉浸布局
窗口沉浸 setWindowLayoutFullScreen(true) 无边框模式
光效动画 animation({ duration, iterations: -1 }) 呼吸灯背景
动态透明度 backgroundOpacity 焦点感知降级

7.3 悬浮导航适配要点

  1. 安全区避让:通过getWindowAvoidArea获取底部导航指示器高度,内容区域动态预留空间
  2. 悬浮层级设计:导航栏脱离底边,使用margin({ left: '2%', right: '2%', bottom: avoidHeight + 12 })实现四周留白
  3. 透明度动态调节:支持强/平衡/弱三档,通过Slider或预设按钮实时调整
  4. PC交互优化:支持鼠标悬停预览、中键关闭、右键上下文菜单

7.4 PC端多窗口光效协同

  • 主窗口:全屏沉浸,环境光背景延伸至所有安全区边缘
  • 浮动工具窗口:置顶、圆角、阴影,跟随主窗口移动
  • 光效同步:通过AppStorage全局状态实现跨窗口主题色联动
  • 焦点感知:窗口激活时边缘发光增强,失活时自动降低光效强度

八、调试与性能优化

8.1 真机调试建议

  1. 光效真机验证:玻璃拟态效果在模拟器上可能显示异常,建议在支持HarmonyOS 6的MateBook真机上测试
  2. 多窗口测试:验证子窗口在分屏、悬浮模式下的位置同步与光效一致性
  3. 手势冲突排查:确保画布拖拽手势与系统导航手势不冲突

8.2 性能优化策略

  1. 光效降级:在低端设备上自动降低模糊半径和动画帧率
  2. 节点懒加载:画布节点超过50个时启用虚拟列表,只渲染可视区域节点
  3. 日志限流:调试控制台限制最大1000条日志,防止内存溢出
  4. 子窗口复用:已创建的子窗口隐藏而非销毁,避免重复创建开销

九、总结与展望

本文基于HarmonyOS 6(API 23)的悬浮导航沉浸光感特性,完整实战了一款面向PC端的"智流工坊"低代码智能体编排平台。核心创新点总结:

  1. 节点类型光效系统:每种智能体节点(LLM/工具/条件/循环/输出)拥有专属光色,从背景光晕到节点阴影形成统一的视觉语言,让编排者一眼识别节点类型与运行状态

  2. 悬浮编排导航:底部悬浮页签替代传统工具栏,玻璃拟态设计+三档透明度调节,在保持导航可达性的同时最大化画布编辑区域

  3. HMAF可视化编排引擎:基于Agent Framework Kit构建拖拽式节点编排引擎,支持LLM/Workflow/A2A/OpenClaw四种模式无缝切换,通过Intents Kit实现意图驱动的智能编排

  4. PC级多窗口协作:主画布窗口 + 浮动属性面板 + 浮动预览窗口 + 浮动调试控制台窗口的四层架构,通过WindowManager实现跨窗口光效联动与焦点感知,符合专业开发者的工作习惯

  5. HDS系统材质深度应用systemMaterialEffect.IMMERSIVE为标题栏和导航组件带来物理光照级的光晕与反射效果,告别传统开发者工具的"工业灰"审美

未来扩展方向

  • 接入分布式软总线,实现跨设备智能体编排(手机扫码继续编排、平板作为扩展预览屏)
  • 结合AI辅助编排:基于当前编排上下文,AI建议以光效形式在背景层呈现(如绿色光晕表示高置信度建议)
  • 探索Face AR能力:通过摄像头捕捉开发者注意力状态,自动调节光效强度(专注时增强、疲劳时减弱)
  • 插件化架构:支持第三方智能体插件市场,让开发者社区贡献更多节点类型与光效主题

转载自:https://blog.csdn.net/u014727709/article/details/162388955
欢迎 👍点赞✍评论⭐收藏,欢迎指正

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐