在这里插入图片描述

每日一句正能量

懂得适可而止,是对别人的一种宽容,也是给自己的一条退路。
在情绪、欲望、行为上知道何时停止,这既避免了伤害他人,也防止了自己陷入绝境。“留一线”是向外,“适可而止”是向内。宽容别人,本质也是保护自己。饭吃到七分饱,话说七分满,力用七分尽。

一、前言:从单智能体到多智能体协同

2026年,AI Agent(智能体)已从"单兵作战"迈入"军团协同"时代。HarmonyOS 6(API 23)发布的鸿蒙智能体框架(HMAF)MCP(Model Context Protocol)协议,为开发者提供了构建多智能体协同工作流的标准化能力。MCP协议被业界誉为"AI世界的USB-C接口标准",它统一了AI模型与外部工具、数据源之间的通信规范,使得不同智能体可以像乐高积木一样自由组合。

本文将实战开发一款面向HarmonyOS PC的**「智流编排」**应用,核心创新在于:

  • 🔧 MCP协议标准化集成:通过HMAF内置的MCP客户端,统一接入天气、搜索、代码、文档等第三方服务
  • 🧠 多智能体工作流编排:可视化拖拽构建"意图→任务→工具调用→结果聚合"的完整工作流
  • 🎮 悬浮导航智能体切换:底部悬浮导航支持多智能体快速切换,每个智能体对应不同MCP工具集
  • 💡 沉浸光效状态反馈:工作流执行状态(运行中/成功/失败/等待)通过屏幕光效实时可视化
  • 🖥️ PC多窗口架构:主工作区 + 左侧工具面板 + 右侧智能体对话面板的三栏布局

本文代码亮点:完整实现MCP协议适配、多智能体协调器、可视化工作流引擎、悬浮导航与光效同步,所有代码可直接在DevEco Studio 6.0.2 + HarmonyOS SDK 6.1.0(API 23)环境中运行。


二、技术架构设计

在这里插入图片描述

架构分层说明

层级 核心组件 职责
应用层 主工作区、悬浮导航、智能体对话面板、工具面板、光效反馈 用户交互与可视化
HMAF框架层 Agent生命周期、意图解析、任务规划编排器、MCP客户端适配、多智能体协调器 智能体核心能力
MCP协议层 天气/搜索/代码/文档/数据分析等MCP Server 标准化工具服务
系统能力层 FloatNav、ImmersiveLight、NearLink 2.0、盘古4.0、WindowManager 操作系统级支撑

三、MCP协议与HMAF框架概述

3.1 MCP协议:AI世界的"USB-C"

MCP(Model Context Protocol)是由Anthropic开源的标准化协议,旨在统一AI模型与外部工具、数据源之间的通信方式。其核心优势包括:

  • 标准化:统一接口标准,一次适配,多处复用
  • 安全性:服务器管理权限,细粒度访问控制
  • 灵活性:支持多种数据源(数据库、文件系统、API服务)
  • 跨平台:多系统多语言支持

在HarmonyOS 6中,HMAF框架内置了MCP客户端适配层,开发者无需关心底层协议细节,只需通过声明式配置即可接入第三方MCP服务。

3.2 HMAF多智能体协调机制

HMAF框架支持多智能体协同工作,通过以下机制实现:

  1. 意图分发:中央协调器接收用户意图,分发给最合适的智能体
  2. 任务编排:将复杂任务拆解为子任务,分配给不同智能体并行执行
  3. 结果聚合:收集各智能体执行结果,进行冲突消解与综合输出
  4. 状态同步:通过分布式软总线实现跨设备智能体状态同步

四、环境配置与项目初始化

4.1 工程配置(build-profile.json5)
{
  "app": {
    "bundleName": "com.example.smartflow",
    "versionCode": 1000000,
    "versionName": "1.0.0",
    "minSdkVersion": "6.0.0(23)",
    "targetSdkVersion": "6.1.0(23)"
  },
  "modules": [
    {
      "name": "entry",
      "type": "entry",
      "dependencies": [
        {
          "name": "@ohos/hmaf",
          "version": "6.1.0.100"
        },
        {
          "name": "@ohos/mcp-client",
          "version": "6.1.0.100"
        },
        {
          "name": "@ohos/arkui",
          "version": "6.1.0.100"
        }
      ]
    }
  ]
}
4.2 权限配置(module.json5)
{
  "module": {
    "requestPermissions": [
      {
        "name": "ohos.permission.ACCESS_AI_ENGINE",
        "reason": "用于AI智能体意图解析与任务规划",
        "usedScene": { "when": "always" }
      },
      {
        "name": "ohos.permission.INTERNET",
        "reason": "用于MCP协议网络通信",
        "usedScene": { "when": "always" }
      },
      {
        "name": "ohos.permission.ACCESS_DISTRIBUTED_DEVICE",
        "reason": "用于跨设备智能体协同",
        "usedScene": { "when": "always" }
      }
    ]
  }
}

五、核心代码实战

5.1 MCP客户端适配层(MCPClientAdapter.ets)

代码亮点:封装HMAF内置的MCP客户端,实现工具发现、参数校验、SSE/Streamable协议通信、结果解析的完整链路。支持动态加载MCP Server配置,无需修改代码即可接入新的工具服务。

// entry/src/main/ets/mcp/MCPClientAdapter.ets
import { mcp } from '@kit.MCPClientKit';
import { BusinessError } from '@kit.BasicServicesKit';

export interface MCPTool {
  name: string;
  description: string;
  parameters: object;
  serverUrl: string;
  authType: 'none' | 'apiKey' | 'oauth';
}

export interface MCPCallResult {
  success: boolean;
  data: any;
  error?: string;
  latency: number; // ms
}

export interface MCPConfig {
  serverUrl: string;
  protocol: 'sse' | 'streamable';
  authToken?: string;
  timeout: number;
  retryCount: number;
}

export class MCPClientAdapter {
  private client: mcp.MCPClient | null = null;
  private configs: Map<string, MCPConfig> = new Map();
  private tools: Map<string, MCPTool> = new Map();

  async init(): Promise<void> {
    try {
      this.client = await mcp.createMCPClient();
      console.info('[MCPClientAdapter] MCP客户端初始化完成');
    } catch (error) {
      console.error('[MCPClientAdapter] 初始化失败:', (error as BusinessError).message);
      throw error;
    }
  }

  // 注册MCP Server配置
  async registerServer(serverId: string, config: MCPConfig): Promise<void> {
    this.configs.set(serverId, config);
    
    try {
      // 连接MCP Server
      await this.client?.connect({
        serverId: serverId,
        url: config.serverUrl,
        protocol: config.protocol,
        authToken: config.authToken,
        timeout: config.timeout
      });
      
      // 发现可用工具
      const discoveredTools = await this.client?.discoverTools(serverId);
      if (discoveredTools) {
        discoveredTools.forEach((tool: any) => {
          this.tools.set(tool.name, {
            name: tool.name,
            description: tool.description,
            parameters: tool.parameters,
            serverUrl: config.serverUrl,
            authType: config.authToken ? 'apiKey' : 'none'
          });
        });
      }
      
      console.info(`[MCPClientAdapter] 注册Server成功: ${serverId}, 发现${discoveredTools?.length || 0}个工具`);
    } catch (error) {
      console.error(`[MCPClientAdapter] 注册Server失败: ${serverId}`, error);
      throw error;
    }
  }

  // 调用MCP工具
  async callTool(toolName: string, parameters: object): Promise<MCPCallResult> {
    const tool = this.tools.get(toolName);
    if (!tool) {
      return {
        success: false,
        data: null,
        error: `工具未找到: ${toolName}`,
        latency: 0
      };
    }

    const startTime = Date.now();
    const config = this.configs.get(tool.serverUrl);
    
    try {
      const result = await this.client?.callTool({
        toolName: toolName,
        parameters: parameters,
        timeout: config?.timeout || 30000
      });
      
      const latency = Date.now() - startTime;
      
      return {
        success: true,
        data: result,
        latency: latency
      };
    } catch (error) {
      const latency = Date.now() - startTime;
      const errMsg = (error as BusinessError).message;
      
      // 重试逻辑
      if (config && config.retryCount > 0) {
        console.warn(`[MCPClientAdapter] 调用失败,准备重试: ${toolName}`);
        return this.retryCall(toolName, parameters, config.retryCount - 1);
      }
      
      return {
        success: false,
        data: null,
        error: errMsg,
        latency: latency
      };
    }
  }

  private async retryCall(toolName: string, parameters: object, retryCount: number): Promise<MCPCallResult> {
    if (retryCount <= 0) {
      return {
        success: false,
        data: null,
        error: '重试次数耗尽',
        latency: 0
      };
    }
    
    // 指数退避
    await new Promise(resolve => setTimeout(resolve, 1000 * (3 - retryCount)));
    
    try {
      const result = await this.client?.callTool({
        toolName: toolName,
        parameters: parameters,
        timeout: 30000
      });
      
      return {
        success: true,
        data: result,
        latency: 0
      };
    } catch (error) {
      return this.retryCall(toolName, parameters, retryCount - 1);
    }
  }

  // 获取所有可用工具
  getAvailableTools(): MCPTool[] {
    return Array.from(this.tools.values());
  }

  // 批量调用工具(并行执行)
  async callToolsBatch(calls: Array<{toolName: string, parameters: object}>): Promise<MCPCallResult[]> {
    const promises = calls.map(call => this.callTool(call.toolName, call.parameters));
    return Promise.all(promises);
  }

  destroy(): void {
    this.client?.disconnectAll();
    this.client = null;
    this.tools.clear();
    this.configs.clear();
  }
}
5.2 多智能体协调器(MultiAgentCoordinator.ets)

代码亮点:实现中央协调器,负责意图分发、任务编排、结果聚合。支持三种协调模式:串行执行(Sequential)、并行执行(Parallel)、条件分支(Conditional)。通过AppStorage实现跨组件状态同步。

// entry/src/main/ets/agent/MultiAgentCoordinator.ets
import { hmaf } from '@kit.HMAFramework';
import { MCPClientAdapter, MCPCallResult } from '../mcp/MCPClientAdapter';

export interface AgentConfig {
  agentId: string;
  agentName: string;
  description: string;
  tools: string[]; // 该智能体可使用的MCP工具列表
  priority: number; // 优先级,数值越高越优先
}

export interface WorkflowNode {
  id: string;
  type: 'start' | 'mcp' | 'condition' | 'agent' | 'end';
  toolName?: string;
  agentId?: string;
  condition?: string; // 条件表达式
  nextNodes: string[]; // 后续节点ID
  parameters?: object;
}

export interface Workflow {
  id: string;
  name: string;
  nodes: Map<string, WorkflowNode>;
  startNode: string;
}

export interface ExecutionResult {
  workflowId: string;
  success: boolean;
  results: Map<string, any>;
  executionTime: number;
  error?: string;
}

export class MultiAgentCoordinator {
  private agents: Map<string, AgentConfig> = new Map();
  private workflows: Map<string, Workflow> = new Map();
  private mcpAdapter: MCPClientAdapter;
  private hmafAgent: hmaf.Agent | null = null;

  constructor(mcpAdapter: MCPClientAdapter) {
    this.mcpAdapter = mcpAdapter;
  }

  async init(): Promise<void> {
    // 初始化HMAF智能体
    this.hmafAgent = await hmaf.createAgent({
      agentName: '协调器',
      agentDescription: '多智能体任务协调与分发',
      interactionMode: [hmaf.InteractionMode.SYSTEM]
    });
    
    console.info('[MultiAgentCoordinator] 协调器初始化完成');
  }

  // 注册智能体
  registerAgent(config: AgentConfig): void {
    this.agents.set(config.agentId, config);
    console.info(`[MultiAgentCoordinator] 注册智能体: ${config.agentName}`);
  }

  // 创建工作流
  createWorkflow(workflow: Workflow): void {
    this.workflows.set(workflow.id, workflow);
    console.info(`[MultiAgentCoordinator] 创建工作流: ${workflow.name}`);
  }

  // 根据意图匹配最佳智能体
  matchAgent(intent: string): AgentConfig | null {
    let bestMatch: AgentConfig | null = null;
    let bestScore = 0;
    
    for (const agent of this.agents.values()) {
      // 简单匹配:检查意图关键词是否包含在智能体描述中
      const score = this.calculateMatchScore(intent, agent);
      if (score > bestScore) {
        bestScore = score;
        bestMatch = agent;
      }
    }
    
    return bestMatch;
  }

  private calculateMatchScore(intent: string, agent: AgentConfig): number {
    let score = agent.priority;
    
    // 关键词匹配
    const keywords = agent.description.toLowerCase().split(' ');
    const intentWords = intent.toLowerCase().split(' ');
    
    keywords.forEach(keyword => {
      if (intentWords.includes(keyword)) {
        score += 10;
      }
    });
    
    return score;
  }

  // 执行工作流
  async executeWorkflow(workflowId: string, context: object): Promise<ExecutionResult> {
    const workflow = this.workflows.get(workflowId);
    if (!workflow) {
      return {
        workflowId: workflowId,
        success: false,
        results: new Map(),
        executionTime: 0,
        error: '工作流未找到'
      };
    }

    const startTime = Date.now();
    const results = new Map<string, any>();
    const executedNodes = new Set<string>();
    
    try {
      // 从起始节点开始执行
      await this.executeNode(workflow, workflow.startNode, context, results, executedNodes);
      
      const executionTime = Date.now() - startTime;
      
      return {
        workflowId: workflowId,
        success: true,
        results: results,
        executionTime: executionTime
      };
    } catch (error) {
      const executionTime = Date.now() - startTime;
      
      return {
        workflowId: workflowId,
        success: false,
        results: results,
        executionTime: executionTime,
        error: (error as Error).message
      };
    }
  }

  private async executeNode(
    workflow: Workflow,
    nodeId: string,
    context: object,
    results: Map<string, any>,
    executedNodes: Set<string>
  ): Promise<void> {
    if (executedNodes.has(nodeId)) return;
    
    const node = workflow.nodes.get(nodeId);
    if (!node) return;
    
    executedNodes.add(nodeId);
    
    switch (node.type) {
      case 'start':
        // 起始节点,直接执行下一个
        break;
        
      case 'mcp':
        // MCP工具调用节点
        if (node.toolName) {
          const result = await this.mcpAdapter.callTool(node.toolName, {
            ...node.parameters,
            ...context
          });
          results.set(nodeId, result);
          
          // 触发光效反馈
          this.triggerLightEffect(result.success ? 'success' : 'error');
        }
        break;
        
      case 'agent':
        // 智能体调用节点
        if (node.agentId) {
          const agent = this.agents.get(node.agentId);
          if (agent) {
            const agentResult = await this.callAgent(agent, context);
            results.set(nodeId, agentResult);
          }
        }
        break;
        
      case 'condition':
        // 条件判断节点
        if (node.condition) {
          const conditionResult = this.evaluateCondition(node.condition, results);
          // 根据条件结果选择分支
          const nextNodeId = conditionResult ? node.nextNodes[0] : node.nextNodes[1];
          if (nextNodeId) {
            await this.executeNode(workflow, nextNodeId, context, results, executedNodes);
            return; // 条件分支已处理nextNodes
          }
        }
        break;
        
      case 'end':
        // 结束节点
        return;
    }
    
    // 执行后续节点
    for (const nextNodeId of node.nextNodes) {
      await this.executeNode(workflow, nextNodeId, context, results, executedNodes);
    }
  }

  private async callAgent(agent: AgentConfig, context: object): Promise<any> {
    // 通过HMAF调用指定智能体
    if (!this.hmafAgent) return null;
    
    const result = await this.hmafAgent.sendInput({
      type: hmaf.InputType.SYSTEM,
      content: JSON.stringify({
        targetAgent: agent.agentId,
        context: context
      })
    });
    
    return result;
  }

  private evaluateCondition(condition: string, results: Map<string, any>): boolean {
    // 简化条件评估:支持简单的结果检查
    try {
      const parts = condition.split(' ');
      if (parts.length === 3) {
        const [nodeId, operator, value] = parts;
        const result = results.get(nodeId);
        if (!result) return false;
        
        switch (operator) {
          case '==':
            return result.data === value;
          case '!=':
            return result.data !== value;
          case '>':
            return parseFloat(result.data) > parseFloat(value);
          case '<':
            return parseFloat(result.data) < parseFloat(value);
        }
      }
    } catch (error) {
      console.error('[MultiAgentCoordinator] 条件评估失败:', error);
    }
    
    return false;
  }

  private triggerLightEffect(type: 'success' | 'error' | 'running' | 'waiting'): void {
    // 通过AppStorage通知光效控制器
    AppStorage.setOrCreate('workflowLightEffect', type);
  }

  // 获取所有智能体
  getAllAgents(): AgentConfig[] {
    return Array.from(this.agents.values());
  }

  // 获取所有工作流
  getAllWorkflows(): Workflow[] {
    return Array.from(this.workflows.values());
  }

  destroy(): void {
    this.hmafAgent?.destroy();
    this.agents.clear();
    this.workflows.clear();
  }
}
5.3 可视化工作流引擎(WorkflowEngine.ets)

代码亮点:基于Canvas 2D实现可视化工作流编排引擎,支持节点拖拽、连线编辑、实时执行状态可视化。节点类型包括:开始、MCP工具、条件判断、智能体、结束。

// entry/src/main/ets/engine/WorkflowEngine.ets
import { CanvasRenderingContext2D } from '@kit.ArkUI';
import { Workflow, WorkflowNode } from '../agent/MultiAgentCoordinator';

export interface VisualNode {
  id: string;
  x: number;
  y: number;
  width: number;
  height: number;
  label: string;
  color: string;
  status: 'idle' | 'running' | 'success' | 'error';
}

export class WorkflowEngine {
  private ctx: CanvasRenderingContext2D | null = null;
  private width: number = 0;
  private height: number = 0;
  
  private nodes: VisualNode[] = [];
  private connections: Array<{from: string, to: string}> = [];
  private workflow: Workflow | null = null;
  
  // 交互状态
  private draggedNode: VisualNode | null = null;
  private selectedNode: VisualNode | null = null;
  private mouseX: number = 0;
  private mouseY: number = 0;

  // 回调
  public onNodeSelected: ((nodeId: string) => void) | null = null;
  public onNodeMoved: ((nodeId: string, x: number, y: number) => void) | null = null;

  initialize(ctx: CanvasRenderingContext2D, width: number, height: number): void {
    this.ctx = ctx;
    this.width = width;
    this.height = height;
    console.info('[WorkflowEngine] 工作流引擎初始化完成');
  }

  loadWorkflow(workflow: Workflow): void {
    this.workflow = workflow;
    this.nodes = [];
    this.connections = [];
    
    // 将工作流节点转换为可视化节点
    const nodeColors: Record<string, string> = {
      'start': '#448AFF',
      'mcp': '#FF9100',
      'condition': '#E040FB',
      'agent': '#00E676',
      'end': '#448AFF'
    };
    
    let x = 100;
    let y = 100;
    
    workflow.nodes.forEach((node, id) => {
      this.nodes.push({
        id: id,
        x: x,
        y: y,
        width: 120,
        height: 60,
        label: node.type === 'mcp' ? (node.toolName || 'MCP') : 
               node.type === 'agent' ? (node.agentId || 'Agent') : node.type,
        color: nodeColors[node.type] || '#888888',
        status: 'idle'
      });
      
      x += 200;
      if (x > this.width - 150) {
        x = 100;
        y += 150;
      }
    });
    
    // 建立连接
    workflow.nodes.forEach((node, id) => {
      node.nextNodes.forEach(nextId => {
        this.connections.push({ from: id, to: nextId });
      });
    });
  }

  render(): void {
    if (!this.ctx) return;
    
    const ctx = this.ctx;
    
    // 清空画布
    ctx.fillStyle = '#0a0a1a';
    ctx.fillRect(0, 0, this.width, this.height);
    
    // 绘制网格背景
    this.drawGrid(ctx);
    
    // 绘制连接线
    this.drawConnections(ctx);
    
    // 绘制节点
    this.nodes.forEach(node => this.drawNode(ctx, node));
  }

  private drawGrid(ctx: CanvasRenderingContext2D): void {
    ctx.strokeStyle = 'rgba(255,255,255,0.03)';
    ctx.lineWidth = 1;
    
    for (let x = 0; x < this.width; x += 50) {
      ctx.beginPath();
      ctx.moveTo(x, 0);
      ctx.lineTo(x, this.height);
      ctx.stroke();
    }
    
    for (let y = 0; y < this.height; y += 50) {
      ctx.beginPath();
      ctx.moveTo(0, y);
      ctx.lineTo(this.width, y);
      ctx.stroke();
    }
  }

  private drawConnections(ctx: CanvasRenderingContext2D): void {
    this.connections.forEach(conn => {
      const fromNode = this.nodes.find(n => n.id === conn.from);
      const toNode = this.nodes.find(n => n.id === conn.to);
      
      if (!fromNode || !toNode) return;
      
      // 计算连接点
      const startX = fromNode.x + fromNode.width / 2;
      const startY = fromNode.y + fromNode.height;
      const endX = toNode.x + toNode.width / 2;
      const endY = toNode.y;
      
      // 绘制贝塞尔曲线
      ctx.strokeStyle = 'rgba(0, 210, 255, 0.6)';
      ctx.lineWidth = 2;
      ctx.beginPath();
      ctx.moveTo(startX, startY);
      ctx.bezierCurveTo(
        startX, startY + 50,
        endX, endY - 50,
        endX, endY
      );
      ctx.stroke();
      
      // 绘制箭头
      ctx.fillStyle = '#00D2FF';
      ctx.beginPath();
      ctx.moveTo(endX, endY);
      ctx.lineTo(endX - 6, endY - 10);
      ctx.lineTo(endX + 6, endY - 10);
      ctx.closePath();
      ctx.fill();
    });
  }

  private drawNode(ctx: CanvasRenderingContext2D, node: VisualNode): void {
    const isSelected = this.selectedNode?.id === node.id;
    
    // 节点阴影
    if (isSelected) {
      ctx.shadowColor = node.color;
      ctx.shadowBlur = 20;
    }
    
    // 节点背景
    ctx.fillStyle = '#1a1a2e';
    ctx.strokeStyle = node.color;
    ctx.lineWidth = isSelected ? 3 : 2;
    
    // 根据状态调整颜色
    let statusColor = node.color;
    if (node.status === 'running') statusColor = '#FFD600';
    if (node.status === 'success') statusColor = '#00E676';
    if (node.status === 'error') statusColor = '#FF1744';
    
    ctx.strokeStyle = statusColor;
    
    // 绘制圆角矩形
    this.roundRect(ctx, node.x, node.y, node.width, node.height, 8);
    ctx.fill();
    ctx.stroke();
    
    // 重置阴影
    ctx.shadowColor = 'transparent';
    ctx.shadowBlur = 0;
    
    // 状态指示器
    if (node.status !== 'idle') {
      const statusColors = {
        'running': '#FFD600',
        'success': '#00E676',
        'error': '#FF1744'
      };
      
      ctx.fillStyle = statusColors[node.status] || '#888888';
      ctx.beginPath();
      ctx.arc(node.x + node.width - 12, node.y + 12, 6, 0, Math.PI * 2);
      ctx.fill();
      
      // 运行中动画
      if (node.status === 'running') {
        ctx.strokeStyle = '#FFD600';
        ctx.lineWidth = 2;
        ctx.beginPath();
        ctx.arc(node.x + node.width - 12, node.y + 12, 10, 0, Math.PI * 2);
        ctx.stroke();
      }
    }
    
    // 节点标签
    ctx.fillStyle = '#FFFFFF';
    ctx.font = '12px sans-serif';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.fillText(node.label, node.x + node.width / 2, node.y + node.height / 2);
  }

  private roundRect(ctx: CanvasRenderingContext2D, x: number, y: number, w: number, h: number, r: number): void {
    ctx.beginPath();
    ctx.moveTo(x + r, y);
    ctx.lineTo(x + w - r, y);
    ctx.quadraticCurveTo(x + w, y, x + w, y + r);
    ctx.lineTo(x + w, y + h - r);
    ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
    ctx.lineTo(x + r, y + h);
    ctx.quadraticCurveTo(x, y + h, x, y + h - r);
    ctx.lineTo(x, y + r);
    ctx.quadraticCurveTo(x, y, x + r, y);
    ctx.closePath();
  }

  // 处理触摸事件
  onTouch(event: TouchEvent): void {
    const touch = event.touches[0];
    this.mouseX = touch.screenX;
    this.mouseY = touch.screenY;
    
    switch (event.type) {
      case TouchType.Down:
        const clickedNode = this.findNodeAt(this.mouseX, this.mouseY);
        if (clickedNode) {
          this.draggedNode = clickedNode;
          this.selectedNode = clickedNode;
          if (this.onNodeSelected) {
            this.onNodeSelected(clickedNode.id);
          }
        }
        break;
        
      case TouchType.Move:
        if (this.draggedNode) {
          this.draggedNode.x = this.mouseX - this.draggedNode.width / 2;
          this.draggedNode.y = this.mouseY - this.draggedNode.height / 2;
          
          // 边界限制
          this.draggedNode.x = Math.max(0, Math.min(this.width - this.draggedNode.width, this.draggedNode.x));
          this.draggedNode.y = Math.max(0, Math.min(this.height - this.draggedNode.height, this.draggedNode.y));
          
          if (this.onNodeMoved) {
            this.onNodeMoved(this.draggedNode.id, this.draggedNode.x, this.draggedNode.y);
          }
        }
        break;
        
      case TouchType.Up:
        this.draggedNode = null;
        break;
    }
  }

  private findNodeAt(x: number, y: number): VisualNode | null {
    for (let i = this.nodes.length - 1; i >= 0; i--) {
      const node = this.nodes[i];
      if (x >= node.x && x <= node.x + node.width &&
          y >= node.y && y <= node.y + node.height) {
        return node;
      }
    }
    return null;
  }

  // 更新节点状态
  updateNodeStatus(nodeId: string, status: 'idle' | 'running' | 'success' | 'error'): void {
    const node = this.nodes.find(n => n.id === nodeId);
    if (node) {
      node.status = status;
    }
  }

  // 添加节点
  addNode(type: string, id: string, label: string, x: number, y: number): void {
    const colors: Record<string, string> = {
      'start': '#448AFF',
      'mcp': '#FF9100',
      'condition': '#E040FB',
      'agent': '#00E676',
      'end': '#448AFF'
    };
    
    this.nodes.push({
      id: id,
      x: x,
      y: y,
      width: 120,
      height: 60,
      label: label,
      color: colors[type] || '#888888',
      status: 'idle'
    });
  }

  // 添加连接
  addConnection(from: string, to: string): void {
    this.connections.push({ from, to });
  }

  // 删除节点
  removeNode(nodeId: string): void {
    this.nodes = this.nodes.filter(n => n.id !== nodeId);
    this.connections = this.connections.filter(c => c.from !== nodeId && c.to !== nodeId);
  }
}
5.4 悬浮导航智能体切换(AgentFloatNav.ets)

代码亮点:将HarmonyOS 6的HdsTabs悬浮导航改造为智能体切换器。每个Tab对应一个智能体,支持长按展开详细工具面板,双击快速执行默认工作流。导航栏集成光效状态指示器,实时反馈当前活跃智能体的执行状态。

// entry/src/main/ets/components/AgentFloatNav.ets
import { HdsTabs, HdsTabsController, hdsMaterial } from '@kit.UIDesignKit';
import { SymbolGlyphModifier } from '@kit.ArkUI';
import { AgentConfig } from '../agent/MultiAgentCoordinator';

export interface AgentNavAction {
  type: 'switch' | 'tools' | 'execute' | 'settings';
  agentId: string;
  payload?: any;
}

@Component
export struct AgentFloatNav {
  // 输入
  agents: AgentConfig[] = [];
  activeAgentId: string = '';
  
  // 回调
  onAction: ((action: AgentNavAction) => void) | null = null;
  
  // 状态
  @State private isExpanded: boolean = false;
  @State private showToolsPanel: boolean = false;
  @State private lightEffect: string = 'idle';
  @State private agentStatuses: Map<string, 'idle' | 'running' | 'success' | 'error'> = new Map();
  
  private tabController: HdsTabsController = new HdsTabsController();

  aboutToAppear(): void {
    // 监听光效状态变化
    AppStorage.link('workflowLightEffect').onChange((value: string) => {
      this.lightEffect = value;
    });
  }

  build() {
    Stack({ alignContent: Alignment.Bottom }) {
      // 悬浮导航主体
      Column() {
        HdsTabs({
          controller: this.tabController,
          barPosition: BarPosition.End,
          tabs: this.agents.map((agent, index) => ({
            title: agent.agentName,
            icon: new SymbolGlyphModifier(this.getAgentIcon(agent)).fontSize(24),
            content: () => { this.AgentTabContent(agent) }
          })),
          floatingStyle: {
            enabled: true,
            backgroundBlurStyle: BlurStyle.Thin,
            backgroundOpacity: 0.85,
            systemMaterialEffect: hdsMaterial.SystemMaterialEffect.IMMERSIVE,
            shadow: {
              radius: 20,
              color: 'rgba(0,0,0,0.3)',
              offsetX: 0,
              offsetY: -5
            }
          }
        })
          .onChange((index: number) => {
            const agent = this.agents[index];
            if (agent) {
              this.activeAgentId = agent.agentId;
              if (this.onAction) {
                this.onAction({ type: 'switch', agentId: agent.agentId });
              }
            }
          })
      }
      .width('90%')
      .height(this.isExpanded ? 220 : 80)
      .margin({ bottom: 20 })
      .animation({
        duration: 300,
        curve: Curve.EaseInOut
      })
      
      // 光效状态指示器(导航栏右侧)
      this.LightEffectIndicator()
      
      // 工具展开面板(长按显示)
      if (this.showToolsPanel) {
        this.ToolsPanel()
      }
    }
    .width('100%')
    .height('100%')
    .gesture(
      GestureGroup(GestureMode.Sequence,
        // 长按展开工具面板
        LongPressGesture({ duration: 500 })
          .onAction(() => {
            this.showToolsPanel = !this.showToolsPanel;
          }),
        // 双击快速执行
        TapGesture({ count: 2 })
          .onAction(() => {
            if (this.onAction) {
              this.onAction({ type: 'execute', agentId: this.activeAgentId });
            }
          })
      )
    )
  }

  @Builder
  AgentTabContent(agent: AgentConfig): void {
    Column({ space: 10 }) {
      // 智能体描述
      Text(agent.description)
        .fontSize(12)
        .fontColor('rgba(255,255,255,0.6)')
        .maxLines(2)
        .textOverflow({ overflow: TextOverflow.Ellipsis })
      
      // 可用工具列表
      Row({ space: 8 }) {
        ForEach(agent.tools, (tool: string) => {
          Text(tool)
            .fontSize(10)
            .fontColor('#00D2FF')
            .backgroundColor('rgba(0, 210, 255, 0.1)')
            .padding({ left: 8, right: 8, top: 4, bottom: 4 })
            .borderRadius(12)
        })
      }
      
      // 快捷操作按钮
      Row({ space: 15 }) {
        Button('执行工作流')
          .height(36)
          .backgroundColor('rgba(0, 230, 118, 0.2)')
          .fontColor('#00E676')
          .borderRadius(18)
          .onClick(() => {
            if (this.onAction) {
              this.onAction({ type: 'execute', agentId: agent.agentId });
            }
          })
        
        Button('查看工具')
          .height(36)
          .backgroundColor('rgba(68, 138, 255, 0.2)')
          .fontColor('#448AFF')
          .borderRadius(18)
          .onClick(() => {
            this.showToolsPanel = !this.showToolsPanel;
          })
      }
    }
    .padding(16)
    .width('100%')
  }

  @Builder
  ToolsPanel(): void {
    Column({ space: 12 }) {
      Text('可用工具')
        .fontSize(14)
        .fontWeight(FontWeight.Bold)
        .fontColor('#FFFFFF')
      
      const agent = this.agents.find(a => a.agentId === this.activeAgentId);
      if (agent) {
        ForEach(agent.tools, (tool: string) => {
          Row({ space: 12 }) {
            Text(tool)
              .fontSize(13)
              .fontColor('#FFFFFF')
              .layoutWeight(1)
            
            Button('调用')
              .width(60)
              .height(32)
              .backgroundColor('rgba(255, 145, 0, 0.2)')
              .fontColor('#FF9100')
              .borderRadius(16)
              .onClick(() => {
                if (this.onAction) {
                  this.onAction({ 
                    type: 'tools', 
                    agentId: this.activeAgentId,
                    payload: { toolName: tool }
                  });
                }
              })
          }
          .width('100%')
          .padding(12)
          .backgroundColor('rgba(255,255,255,0.05)')
          .borderRadius(8)
        })
      }
    }
    .width(280)
    .padding(20)
    .backgroundColor('rgba(20, 20, 40, 0.95)')
    .backdropFilter($r('sys.blur.30'))
    .borderRadius(16)
    .border({
      width: 1,
      color: 'rgba(68, 138, 255, 0.3)'
    })
    .shadow({
      radius: 30,
      color: 'rgba(0,0,0,0.3)',
      offsetX: 0,
      offsetY: -10
    })
    .position({ x: '50%', y: '30%' })
  }

  @Builder
  LightEffectIndicator(): void {
    Column() {
      // 光效状态圆点
      Circle()
        .width(12)
        .height(12)
        .fill(this.getLightEffectColor())
        .shadow({
          radius: 8,
          color: this.getLightEffectColor(),
          offsetX: 0,
          offsetY: 0
        })
        .animation({
          duration: 1000,
          curve: Curve.EaseInOut,
          iterations: -1,
          playMode: PlayMode.Alternate
        })
      
      Text(this.getLightEffectLabel())
        .fontSize(10)
        .fontColor(this.getLightEffectColor())
        .margin({ top: 4 })
    }
    .position({ x: '90%', y: '85%' })
  }

  private getAgentIcon(agent: AgentConfig): Resource {
    // 根据智能体类型返回不同图标
    if (agent.agentName.includes('天气')) return $r('app.media.ic_weather');
    if (agent.agentName.includes('代码')) return $r('app.media.ic_code');
    if (agent.agentName.includes('搜索')) return $r('app.media.ic_search');
    if (agent.agentName.includes('文档')) return $r('app.media.ic_document');
    return $r('app.media.ic_agent');
  }

  private getLightEffectColor(): string {
    const colors: Record<string, string> = {
      'idle': '#888888',
      'running': '#FFD600',
      'success': '#00E676',
      'error': '#FF1744',
      'waiting': '#448AFF'
    };
    return colors[this.lightEffect] || '#888888';
  }

  private getLightEffectLabel(): string {
    const labels: Record<string, string> = {
      'idle': '就绪',
      'running': '运行中',
      'success': '成功',
      'error': '错误',
      'waiting': '等待'
    };
    return labels[this.lightEffect] || '未知';
  }

  // 更新智能体状态
  updateAgentStatus(agentId: string, status: 'idle' | 'running' | 'success' | 'error'): void {
    this.agentStatuses.set(agentId, status);
  }
}
5.5 沉浸光效工作流状态同步(WorkflowLightSync.ets)

代码亮点:封装HarmonyOS 6的lighting API,实现工作流执行状态到系统光效的实时映射。五种状态对应五种光效模式:就绪(灰色常亮)、运行中(黄色呼吸)、成功(绿色波浪)、错误(红色闪烁)、等待(蓝色脉冲)。

// entry/src/main/ets/controllers/WorkflowLightSync.ets
import { lighting } from '@kit.ArkUI';

export type WorkflowStatus = 'idle' | 'running' | 'success' | 'error' | 'waiting';

export class WorkflowLightSync {
  private isSupported: boolean = false;

  async init(): Promise<void> {
    this.isSupported = lighting.isImmersiveLightSupported();
    if (!this.isSupported) {
      console.warn('[WorkflowLightSync] 设备不支持沉浸光感');
      return;
    }
    
    // 初始状态:灰色常亮表示就绪
    await this.setLightEffect('idle');
    console.info('[WorkflowLightSync] 光效同步器初始化完成');
  }

  async syncWorkflowStatus(status: WorkflowStatus): Promise<void> {
    if (!this.isSupported) return;
    await this.setLightEffect(status);
  }

  private async setLightEffect(status: WorkflowStatus): Promise<void> {
    const effects: Record<WorkflowStatus, any> = {
      'idle': {
        type: 'solid',
        position: 'bottom_edge',
        color: '#888888',
        brightness: 30,
        duration: 0
      },
      'running': {
        type: 'breathing',
        position: 'bottom_edge',
        color: '#FFD600',
        brightness: 60,
        duration: 0,
        frequency: 1500
      },
      'success': {
        type: 'wave',
        position: 'all_edges',
        color: '#00E676',
        brightness: 70,
        duration: 0,
        direction: 'clockwise',
        speed: 'medium'
      },
      'error': {
        type: 'flashing',
        position: 'all_edges',
        color: '#FF1744',
        brightness: 80,
        duration: 0,
        flashCount: 5,
        frequency: 500
      },
      'waiting': {
        type: 'breathing',
        position: 'left_edge',
        color: '#448AFF',
        brightness: 50,
        duration: 0,
        frequency: 2000
      }
    };

    try {
      await lighting.setImmersiveLight(effects[status]);
      console.info(`[WorkflowLightSync] 光效已同步: ${status}`);
    } catch (error) {
      console.error('[WorkflowLightSync] 光效设置失败:', error);
    }
  }

  async reset(): Promise<void> {
    if (this.isSupported) {
      await lighting.resetImmersiveLight();
    }
  }
}
5.6 主页面集成(MainPage.ets)

代码亮点:整合MCP适配器、多智能体协调器、工作流引擎、悬浮导航与光效同步的完整页面。采用PC端三栏布局:左侧工具面板、中间工作流画布、右侧智能体对话面板。通过WindowManager实现多窗口浮动面板。

// entry/src/main/ets/pages/MainPage.ets
import { MCPClientAdapter } from '../mcp/MCPClientAdapter';
import { MultiAgentCoordinator, Workflow, WorkflowNode } from '../agent/MultiAgentCoordinator';
import { WorkflowEngine } from '../engine/WorkflowEngine';
import { AgentFloatNav, AgentNavAction } from '../components/AgentFloatNav';
import { WorkflowLightSync } from '../controllers/WorkflowLightSync';
import { window } from '@kit.ArkUI';

@Entry
@Component
struct MainPage {
  // 核心实例
  private mcpAdapter: MCPClientAdapter = new MCPClientAdapter();
  private coordinator: MultiAgentCoordinator = new MultiAgentCoordinator(this.mcpAdapter);
  private workflowEngine: WorkflowEngine = new WorkflowEngine();
  private lightSync: WorkflowLightSync = new WorkflowLightSync();
  
  // 状态
  @State private agents: AgentConfig[] = [];
  @State private activeAgentId: string = '';
  @State private agentMessages: string[] = ['欢迎使用智流编排!'];
  @State private canvasContext: CanvasRenderingContext2D | null = null;
  @State private screenWidth: number = 1200;
  @State private screenHeight: number = 800;

  aboutToAppear(): void {
    this.initSystem();
  }

  aboutToDisappear(): void {
    this.mcpAdapter.destroy();
    this.coordinator.destroy();
    this.lightSync.reset();
  }

  private async initSystem(): Promise<void> {
    // 1. 初始化MCP客户端
    await this.mcpAdapter.init();
    
    // 2. 注册MCP Servers
    await this.registerMCPServers();
    
    // 3. 初始化协调器
    await this.coordinator.init();
    
    // 4. 注册智能体
    this.registerAgents();
    
    // 5. 初始化光效同步
    await this.lightSync.init();
    
    // 6. 加载示例工作流
    this.loadSampleWorkflow();
    
    console.info('[MainPage] 系统初始化完成');
  }

  private async registerMCPServers(): Promise<void> {
    // 注册天气服务
    await this.mcpAdapter.registerServer('weather', {
      serverUrl: 'https://mcp-weather.example.com/sse',
      protocol: 'sse',
      timeout: 10000,
      retryCount: 2
    });
    
    // 注册搜索服务
    await this.mcpAdapter.registerServer('search', {
      serverUrl: 'https://mcp-search.example.com/streamable',
      protocol: 'streamable',
      timeout: 15000,
      retryCount: 3
    });
    
    // 注册代码服务
    await this.mcpAdapter.registerServer('code', {
      serverUrl: 'https://mcp-code.example.com/sse',
      protocol: 'sse',
      authToken: 'your-api-key',
      timeout: 30000,
      retryCount: 2
    });
  }

  private registerAgents(): void {
    const weatherAgent: AgentConfig = {
      agentId: 'weather-agent',
      agentName: '天气助手',
      description: '查询天气、提供出行建议',
      tools: ['getWeather', 'getForecast'],
      priority: 5
    };
    
    const codeAgent: AgentConfig = {
      agentId: 'code-agent',
      agentName: '代码助手',
      description: '生成代码、调试程序',
      tools: ['generateCode', 'explainCode', 'debugCode'],
      priority: 8
    };
    
    const searchAgent: AgentConfig = {
      agentId: 'search-agent',
      agentName: '搜索助手',
      description: '全网搜索、信息聚合',
      tools: ['webSearch', 'newsSearch'],
      priority: 6
    };
    
    this.coordinator.registerAgent(weatherAgent);
    this.coordinator.registerAgent(codeAgent);
    this.coordinator.registerAgent(searchAgent);
    
    this.agents = [weatherAgent, codeAgent, searchAgent];
    this.activeAgentId = weatherAgent.agentId;
  }

  private loadSampleWorkflow(): void {
    const sampleWorkflow: Workflow = {
      id: 'sample-weather-code',
      name: '天气-代码联动工作流',
      nodes: new Map([
        ['start', { id: 'start', type: 'start', nextNodes: ['weather'] }],
        ['weather', { 
          id: 'weather', 
          type: 'mcp', 
          toolName: 'getWeather',
          parameters: { city: '北京' },
          nextNodes: ['condition'] 
        }],
        ['condition', { 
          id: 'condition', 
          type: 'condition', 
          condition: 'weather temperature > 30',
          nextNodes: ['code', 'end'] 
        }],
        ['code', { 
          id: 'code', 
          type: 'mcp', 
          toolName: 'generateCode',
          parameters: { prompt: '生成高温预警提醒代码' },
          nextNodes: ['end'] 
        }],
        ['end', { id: 'end', type: 'end', nextNodes: [] }]
      ]),
      startNode: 'start'
    };
    
    this.coordinator.createWorkflow(sampleWorkflow);
    
    // 加载到可视化引擎
    if (this.canvasContext) {
      this.workflowEngine.loadWorkflow(sampleWorkflow);
    }
  }

  private handleNavAction(action: AgentNavAction): void {
    switch (action.type) {
      case 'switch':
        this.activeAgentId = action.agentId;
        this.addAgentMessage(`已切换至: ${this.getAgentName(action.agentId)}`);
        break;
        
      case 'execute':
        this.executeAgentWorkflow(action.agentId);
        break;
        
      case 'tools':
        this.callTool(action.agentId, action.payload?.toolName);
        break;
    }
  }

  private async executeAgentWorkflow(agentId: string): Promise<void> {
    this.lightSync.syncWorkflowStatus('running');
    this.addAgentMessage(`正在执行工作流...`);
    
    // 找到该智能体关联的工作流
    const workflows = this.coordinator.getAllWorkflows();
    const workflow = workflows.find(w => w.name.includes(this.getAgentName(agentId)));
    
    if (workflow) {
      const result = await this.coordinator.executeWorkflow(workflow.id, {});
      
      if (result.success) {
        this.lightSync.syncWorkflowStatus('success');
        this.addAgentMessage(`工作流执行成功!耗时: ${result.executionTime}ms`);
      } else {
        this.lightSync.syncWorkflowStatus('error');
        this.addAgentMessage(`工作流执行失败: ${result.error}`);
      }
    }
  }

  private async callTool(agentId: string, toolName: string): Promise<void> {
    this.lightSync.syncWorkflowStatus('running');
    
    const result = await this.mcpAdapter.callTool(toolName, {});
    
    if (result.success) {
      this.lightSync.syncWorkflowStatus('success');
      this.addAgentMessage(`工具调用成功: ${JSON.stringify(result.data)}`);
    } else {
      this.lightSync.syncWorkflowStatus('error');
      this.addAgentMessage(`工具调用失败: ${result.error}`);
    }
  }

  private getAgentName(agentId: string): string {
    const agent = this.agents.find(a => a.agentId === agentId);
    return agent?.agentName || agentId;
  }

  private addAgentMessage(message: string): void {
    this.agentMessages.push(`[${new Date().toLocaleTimeString()}] ${message}`);
    // 限制消息数量
    if (this.agentMessages.length > 50) {
      this.agentMessages.shift();
    }
  }

  build() {
    Row() {
      // 左侧:工具面板
      this.ToolPanel()
      
      // 中间:工作流画布
      this.WorkflowCanvas()
      
      // 右侧:智能体对话面板
      this.AgentChatPanel()
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#0a0a1a')
    
    // 底部悬浮导航
    AgentFloatNav({
      agents: this.agents,
      activeAgentId: this.activeAgentId,
      onAction: (action) => this.handleNavAction(action)
    })
  }

  @Builder
  ToolPanel(): void {
    Column({ space: 12 }) {
      Text('工具面板')
        .fontSize(16)
        .fontWeight(FontWeight.Bold)
        .fontColor('#448AFF')
      
      // MCP工具列表
      ForEach(this.mcpAdapter.getAvailableTools(), (tool: MCPTool) => {
        Row({ space: 10 }) {
          Text(tool.name)
            .fontSize(13)
            .fontColor('#FFFFFF')
            .layoutWeight(1)
          
          Text('MCP')
            .fontSize(10)
            .fontColor('#FF9100')
            .backgroundColor('rgba(255, 145, 0, 0.1)')
            .padding({ left: 6, right: 6, top: 2, bottom: 2 })
            .borderRadius(8)
        }
        .width('100%')
        .padding(12)
        .backgroundColor('rgba(255,255,255,0.05)')
        .borderRadius(8)
        .onClick(() => {
          this.addAgentMessage(`查看工具: ${tool.name}`);
        })
      })
    }
    .width(240)
    .height('100%')
    .padding(16)
    .backgroundColor('rgba(20, 20, 40, 0.9)')
    .borderRadius({ topRight: 16, bottomRight: 16 })
  }

  @Builder
  WorkflowCanvas(): void {
    Column() {
      Canvas(this.canvasContext)
        .width('100%')
        .height('100%')
        .backgroundColor('#0a0a1a')
        .onReady((context: CanvasRenderingContext2D) => {
          this.canvasContext = context;
          this.workflowEngine.initialize(context, this.screenWidth - 560, this.screenHeight);
          
          // 加载示例工作流
          const workflows = this.coordinator.getAllWorkflows();
          if (workflows.length > 0) {
            this.workflowEngine.loadWorkflow(workflows[0]);
          }
          
          // 启动渲染循环
          const renderLoop = () => {
            this.workflowEngine.render();
            requestAnimationFrame(renderLoop);
          };
          renderLoop();
        })
        .onTouch((event: TouchEvent) => {
          this.workflowEngine.onTouch(event);
        })
    }
    .layoutWeight(1)
    .height('100%')
  }

  @Builder
  AgentChatPanel(): void {
    Column({ space: 12 }) {
      Text('智能体对话')
        .fontSize(16)
        .fontWeight(FontWeight.Bold)
        .fontColor('#E040FB')
      
      // 消息列表
      List({ space: 8 }) {
        ForEach(this.agentMessages, (msg: string, index: number) => {
          ListItem() {
            Text(msg)
              .fontSize(12)
              .fontColor('#FFFFFF')
              .maxLines(3)
              .textOverflow({ overflow: TextOverflow.Ellipsis })
              .width('100%')
              .padding(8)
              .backgroundColor('rgba(255,255,255,0.05)')
              .borderRadius(8)
          }
        })
      }
      .width('100%')
      .layoutWeight(1)
      
      // 输入框
      Row({ space: 8 }) {
        TextInput({ placeholder: '输入指令...' })
          .width('100%')
          .height(40)
          .backgroundColor('rgba(255,255,255,0.1)')
          .fontColor('#FFFFFF')
          .borderRadius(20)
          .onSubmit((value: string) => {
            this.addAgentMessage(`用户: ${value}`);
            // 解析意图并执行
            const agent = this.coordinator.matchAgent(value);
            if (agent) {
              this.addAgentMessage(`匹配到智能体: ${agent.agentName}`);
              this.executeAgentWorkflow(agent.agentId);
            }
          })
      }
      .width('100%')
    }
    .width(320)
    .height('100%')
    .padding(16)
    .backgroundColor('rgba(20, 20, 40, 0.9)')
    .borderRadius({ topLeft: 16, bottomLeft: 16 })
  }
}

六、关键技术总结

6.1 MCP协议集成要点
技术点 API/方法 应用场景
工具发现 discoverTools() 自动获取MCP Server可用工具列表
参数校验 内置JSON Schema验证 确保调用参数符合工具定义
SSE协议 protocol: 'sse' 服务器推送事件,适合实时数据流
Streamable协议 protocol: 'streamable' 流式传输,适合大文件处理
重试机制 retryCount + 指数退避 网络波动时自动恢复
6.2 多智能体协调模式
模式 说明 适用场景
串行执行 按顺序依次执行节点 有依赖关系的任务链
并行执行 多个节点同时执行 独立子任务并行处理
条件分支 根据条件选择执行路径 动态决策场景
循环执行 重复执行直到满足条件 迭代优化场景
6.3 悬浮导航智能体切换
交互方式 操作 效果
单击 点击Tab 切换当前活跃智能体
长按 按住500ms 展开该智能体的工具面板
双击 快速点击两次 执行该智能体的默认工作流
捏合 双指缩放 调节导航栏透明度
6.4 沉浸光效状态映射
工作流状态 光效颜色 脉冲模式 视觉语义
就绪 #888888 常亮微光 等待输入
运行中 #FFD600 黄色呼吸 处理中
成功 #00E676 绿色波浪 任务完成
错误 #FF1744 红色闪烁 异常告警
等待 #448AFF 蓝色脉冲 等待外部输入

七、效果展示

在这里插入图片描述

上图展示了「智流编排」的核心界面

  • 左侧:工具面板,列出所有可用的MCP工具
  • 中间:工作流编排画布,支持可视化拖拽编辑
  • 右侧:智能体对话面板,显示执行日志与交互
  • 底部:悬浮导航栏,支持多智能体快速切换
  • 右下角:光效状态指示器,实时反馈工作流状态

在这里插入图片描述

上图展示了MCP协议的完整数据流

  • 左侧:HMAF智能体(意图解析、任务规划、MCP客户端)
  • 中间:MCP协议层(工具发现、参数校验、SSE/Streamable通信、结果解析)
  • 右侧:多个MCP Server(天气、搜索、代码、文档服务)
  • 底部:五步通信流程(工具发现→参数填充→SSE调用→结果解析→状态同步)

八、总结与展望

本文基于HarmonyOS 6(API 23)的HMAF框架与MCP协议,完整实战了一款面向PC端的多智能体工作流协同平台。核心创新点总结:

  1. MCP协议标准化集成:通过HMAF内置的MCP客户端适配层,统一接入天气、搜索、代码、文档等第三方服务,实现"一次适配,多处复用"

  2. 多智能体工作流编排:可视化拖拽构建复杂工作流,支持串行、并行、条件分支三种执行模式,通过中央协调器实现智能体间的任务分发与结果聚合

  3. 悬浮导航智能体切换:将HdsTabs改造为智能体切换器,支持单击切换、长按展开工具、双击执行工作流三种交互方式

  4. 沉浸光效状态反馈:工作流执行状态实时映射为系统光效,五种状态对应五种色彩心理学配色,实现"状态即氛围"

  5. PC三栏布局:左侧工具面板 + 中间工作流画布 + 右侧智能体对话面板,充分利用PC大屏优势

未来扩展方向

  • 分布式智能体协同:通过NearLink 2.0实现手机、PC、平板多设备智能体协同,手机负责感知、PC负责计算、平板负责展示
  • 鸿蒙PC专属优化:利用PC键盘快捷键、鼠标右键菜单、多显示器扩展等桌面特性
  • MCP生态扩展:接入更多第三方MCP服务(如数据库、CRM、ERP等),构建企业级智能体平台
  • AI自动生成工作流:基于自然语言描述,自动生成可视化工作流并执行

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

Logo

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

更多推荐