在这里插入图片描述

每日一句正能量

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

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

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开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐