在这里插入图片描述

每日一句正能量

度,是恰到好处的分寸,是过犹不及的警醒。
“度”是做事、说话、待人接物中的黄金分割点。它提醒我们,凡事超过了限度就和不及一样糟糕。儒家讲“中庸”,道家讲“知止”,核心都是这个“度”。它需要情境智慧,没有固定公式,只能靠觉察调整。


一、前言:从"单兵作战"到"集群协作"的智能体进化

在第一百零八篇中,我们实现了单个HMAF智能体与悬浮导航、沉浸光感的融合。但在真实的企业级场景中,单一智能体往往难以应对复杂任务——比如"帮我策划一场从北京到三亚的5天家庭旅行",这涉及机票查询、酒店预订、景点推荐、行程规划、预算核算等多个专业领域,需要多个垂域智能体协同完成。

HarmonyOS 6(API 23)在HMAF 2.0基础上,正式开放了多智能体协作框架(Multi-Agent Collaboration Framework,简称MACF),结合鸿蒙独有的**分布式软总线(Distributed Soft Bus)**能力,实现了跨设备智能体的发现、调度、通信与协作。

本文核心亮点:我们将实战构建一个"旅行智能体集群",包含机票Agent、酒店Agent、景点Agent、预算Agent四个专业智能体。它们分布在手机、平板、PC三台设备上,通过分布式软总线自动发现彼此,由"旅行管家Agent"作为协调者进行任务拆解与结果聚合,最终通过沉浸光感的UI呈现完整行程方案。


二、技术架构总览

2.1 多智能体协作架构

┌─────────────────────────────────────────────────────────────────────────────┐
│                              协调层(Coordinator)                           │
│                    ┌─────────────────────────────────────┐                  │
│                    │      旅行管家Agent(TravelMaster)    │                  │
│                    │   - 意图拆解   - 任务分配   - 结果聚合   │                  │
│                    └─────────────────┬───────────────────┘                  │
│                                      │                                      │
├──────────────────────────────────────┼──────────────────────────────────────┤
│                         分布式软总线(Distributed Soft Bus)                  │
│     设备发现    │    服务注册    │    跨设备RPC    │    数据总线    │         │
│   (DeviceDiscovery)  (ServiceRegistry)  (CrossDeviceRPC)  (DataBus)         │
│                                      │                                      │
├──────────────────┬───────────────────┼───────────────────┬──────────────────┤
│   手机设备        │    平板设备        │     PC设备         │   手表设备       │
│ ┌──────────────┐ │ ┌──────────────┐  │ ┌──────────────┐  │                 │
│ │ 机票Agent     │ │ │ 酒店Agent     │  │ │ 景点Agent     │  │                 │
│ │ - 航班查询    │ │ │ - 酒店搜索    │  │ │ - 景点推荐    │  │                 │
│ │ - 价格比较    │ │ │ - 房态确认    │  │ │ - 路线规划    │  │                 │
│ │ - 预订下单    │ │ │ - 优惠计算    │  │ │ - 门票预订    │  │                 │
│ └──────────────┘ │ └──────────────┘  │ └──────────────┘  │                 │
│ ┌──────────────┐ │                    │ ┌──────────────┐  │                 │
│ │ 预算Agent     │ │                    │ │ 沉浸光感UI    │  │                 │
│ │ - 费用汇总    │ │                    │ │ - 行程看板    │  │                 │
│ │ - 预算预警    │ │                    │ │ - 情绪渲染    │  │                 │
│ │ - 支付建议    │ │                    │ │ - 动态光效    │  │                 │
│ └──────────────┘ │                    │ └──────────────┘  │                 │
│   悬浮导航入口    │                    │   大屏展示中心     │                 │
└──────────────────┴────────────────────┴───────────────────┴─────────────────┘

2.2 关键技术栈

技术模块 API/框架 作用
MACF @ohos/macf 多智能体协作框架,负责任务编排
分布式软总线 @ohos.distributedHardware 跨设备发现、连接、通信
分布式对象 @ohos.distributedObject 跨设备状态同步
HMAF Skill @ohos/hmaf 单智能体能力封装
沉浸光感 @ohos/immersive-light 协作状态可视化
悬浮导航 windowManager.createWindow 跨设备统一入口

三、核心代码实战

3.1 项目配置与依赖

// oh-package.json5
{
  "name": "multi-agent-travel",
  "version": "1.0.0",
  "description": "HarmonyOS 6 多智能体协作 × 分布式软总线 × 沉浸光感实战",
  "dependencies": {
    "@ohos/hmaf": "2.0.0",
    "@ohos/macf": "1.0.0",
    "@ohos/distributed-hardware": "5.0.0",
    "@ohos/distributed-object": "5.0.0",
    "@ohos/immersive-light": "1.2.0",
    "@ohos/float-window": "1.1.0"
  }
}
// module.json5 权限声明
{
  "module": {
    "requestPermissions": [
      { "name": "ohos.permission.DISTRIBUTED_DATASYNC" },
      { "name": "ohos.permission.DISTRIBUTED_SOFTBUS_CENTER" },
      { "name": "ohos.permission.GET_WIFI_INFO" },
      { "name": "ohos.permission.GET_NETWORK_INFO" },
      { "name": "ohos.permission.SYSTEM_FLOAT_WINDOW" },
      { "name": "ohos.permission.INTERNET" }
    ]
  }
}

3.2 分布式软总线:设备发现与服务注册

代码亮点:实现了基于分布式软总线的智能体自动发现机制。当旅行管家Agent启动时,它会自动扫描局域网内的鸿蒙设备,发现其他专业Agent并建立P2P连接。

// src/distributed/DeviceDiscoveryManager.ts
import { distributedDeviceManager } from '@kit.DistributedServiceKit';
import { distributedHardware } from '@kit.DistributedHardwareKit';
import { hilog } from '@kit.PerformanceAnalysisKit';

/**
 * 分布式设备发现管理器
 * 核心功能:
 * 1. 自动发现局域网内鸿蒙设备
 * 2. 智能体服务注册与发现
 * 3. 设备能力协商与连接管理
 */
export class DeviceDiscoveryManager {
  private deviceManager: distributedDeviceManager.DeviceManager;
  private registeredAgents: Map<string, AgentEndpoint> = new Map();
  private onDeviceFoundCallback?: (devices: DiscoveredDevice[]) => void;
  private onAgentDiscoveredCallback?: (agent: DiscoveredAgent) => void;

  constructor() {
    this.deviceManager = distributedDeviceManager.createDeviceManager('com.example.travel');
  }

  /**
   * 启动设备发现
   */
  async startDiscovery(): Promise<void> {
    // 订阅设备上线/下线事件
    this.deviceManager.on('deviceStateChange', (data) => {
      hilog.info(0x0000, 'Discovery', `Device state changed: ${JSON.stringify(data)}`);
      this.handleDeviceStateChange(data);
    });

    // 启动主动发现
    const filterOptions: distributedDeviceManager.SubscribeInfo = {
      subscribeId: 10001,
      mode: distributedDeviceManager.DiscoverMode.DISCOVER_MODE_ACTIVE,
      medium: distributedDeviceManager.ExchangeMedium.AUTO,
      freq: distributedDeviceManager.ExchangeFreq.HIGH,
      isSameAccount: false,
      capability: distributedDeviceManager.SubscribeCap.SUBSCRIBE_CAP_OSD
    };

    await this.deviceManager.startDeviceDiscovery(filterOptions);
    hilog.info(0x0000, 'Discovery', 'Device discovery started');
  }

  /**
   * 注册本机智能体服务
   */
  async registerAgentService(agentInfo: AgentInfo): Promise<void> {
    const serviceId = `agent://${agentInfo.type}/${agentInfo.id}`;
    
    // 通过分布式软总线注册服务
    await distributedHardware.registerService({
      serviceId: serviceId,
      serviceType: 'agent',
      capabilities: agentInfo.capabilities,
      properties: {
        agentType: agentInfo.type,
        agentName: agentInfo.name,
        version: agentInfo.version,
        deviceType: deviceInfo.deviceType // phone/tablet/pc
      }
    });

    this.registeredAgents.set(serviceId, {
      serviceId,
      agentInfo,
      status: AgentStatus.AVAILABLE
    });

    hilog.info(0x0000, 'Discovery', `Agent registered: ${serviceId}`);
  }

  /**
   * 发现远程智能体
   */
  async discoverRemoteAgents(): Promise<DiscoveredAgent[]> {
    const agents: DiscoveredAgent[] = [];
    
    // 获取已连接设备列表
    const devices = this.deviceManager.getAvailableDeviceListSync();
    
    for (const device of devices) {
      // 向每个设备查询其注册的智能体服务
      try {
        const remoteAgents = await this.queryRemoteAgents(device.networkId);
        agents.push(...remoteAgents.map(agent => ({
          ...agent,
          deviceId: device.deviceId,
          deviceName: device.deviceName,
          deviceType: device.deviceType
        })));
      } catch (err) {
        hilog.warn(0x0000, 'Discovery', `Failed to query device ${device.deviceName}: ${err}`);
      }
    }

    return agents;
  }

  /**
   * 查询远程设备上的智能体(跨设备RPC)
   */
  private async queryRemoteAgents(networkId: string): Promise<AgentEndpoint[]> {
    // 使用分布式软总线的RPC能力
    const proxy = distributedHardware.createRpcProxy(networkId, 'agent_registry');
    const response = await proxy.call('listAgents', {});
    return response.agents || [];
  }

  /**
   * 建立与远程Agent的通信通道
   */
  async connectToAgent(agentId: string): Promise<AgentConnection> {
    const agent = Array.from(this.registeredAgents.values()).find(a => a.agentInfo.id === agentId);
    if (!agent) {
      throw new Error(`Agent ${agentId} not found`);
    }

    // 创建跨设备数据通道
    const dataBus = await distributedHardware.createDataBus({
      targetDevice: agent.agentInfo.deviceId,
      channelType: ' reliable', // 可靠传输
      qos: { bandwidth: 1024 * 1024 } // 1MB/s
    });

    return new AgentConnection(agent, dataBus);
  }

  private handleDeviceStateChange(data: distributedDeviceManager.DeviceStateChangeInfo): void {
    if (data.state === distributedDeviceManager.DeviceStateChangeAction.ONLINE) {
      // 新设备上线,触发智能体发现
      this.discoverRemoteAgents().then(agents => {
        agents.forEach(agent => this.onAgentDiscoveredCallback?.(agent));
      });
    }
  }

  setOnDeviceFound(callback: (devices: DiscoveredDevice[]) => void): void {
    this.onDeviceFoundCallback = callback;
  }

  setOnAgentDiscovered(callback: (agent: DiscoveredAgent) => void): void {
    this.onAgentDiscoveredCallback = callback;
  }
}

interface AgentInfo {
  id: string;
  type: string; // 'flight' | 'hotel' | 'attraction' | 'budget'
  name: string;
  version: string;
  capabilities: string[];
}

interface AgentEndpoint {
  serviceId: string;
  agentInfo: AgentInfo;
  status: AgentStatus;
}

enum AgentStatus {
  AVAILABLE = 'available',
  BUSY = 'busy',
  OFFLINE = 'offline'
}

interface DiscoveredDevice {
  deviceId: string;
  deviceName: string;
  deviceType: string;
  networkId: string;
}

interface DiscoveredAgent extends AgentEndpoint {
  deviceId: string;
  deviceName: string;
  deviceType: string;
}

class AgentConnection {
  constructor(
    public endpoint: AgentEndpoint,
    private dataBus: distributedHardware.DataBus
  ) {}

  async invoke(method: string, params: any): Promise<any> {
    const request = { method, params, timestamp: Date.now() };
    const response = await this.dataBus.sendAndReceive(request);
    return response.data;
  }

  async close(): Promise<void> {
    await this.dataBus.close();
  }
}

3.3 多智能体协作编排器:旅行管家的"指挥中枢"

代码亮点:实现了基于**合同网协议(Contract Net Protocol)**的多智能体任务分配机制。旅行管家Agent将复杂任务拆解为子任务,向所有可用Agent广播招标,各Agent根据自身能力投标,最终由管家选择最优组合执行。

// src/agents/TravelMasterOrchestrator.ts
import { DeviceDiscoveryManager, AgentConnection, DiscoveredAgent } from '../distributed/DeviceDiscoveryManager';
import { LightEffectManager } from '../effects/LightEffectManager';
import { hilog } from '@kit.PerformanceAnalysisKit';

/**
 * 旅行管家编排器
 * 核心能力:
 * 1. 复杂意图拆解(旅行规划 → 机票+酒店+景点+预算)
 * 2. 基于合同网协议的任务分配
 * 3. 并行执行与结果聚合
 * 4. 冲突检测与协商(如酒店位置与景点距离冲突)
 * 5. 沉浸光感状态可视化
 */
export class TravelMasterOrchestrator {
  private discoveryManager: DeviceDiscoveryManager;
  private availableAgents: Map<string, DiscoveredAgent> = new Map();
  private agentConnections: Map<string, AgentConnection> = new Map();
  private lightEffect: LightEffectManager;

  // 任务执行状态
  @State private executionState: ExecutionState = ExecutionState.IDLE;

  constructor() {
    this.discoveryManager = new DeviceDiscoveryManager();
    this.lightEffect = LightEffectManager.getInstance();
    
    // 监听智能体发现事件
    this.discoveryManager.setOnAgentDiscovered((agent) => {
      this.availableAgents.set(agent.agentInfo.id, agent);
      hilog.info(0x0000, 'Orchestrator', `Agent discovered: ${agent.agentInfo.name} on ${agent.deviceName}`);
    });
  }

  /**
   * 初始化:启动发现并注册本机服务
   */
  async initialize(): Promise<void> {
    await this.discoveryManager.startDiscovery();
    await this.discoveryManager.registerAgentService({
      id: `travel-master-${deviceInfo.deviceId}`,
      type: 'travel-master',
      name: '旅行管家',
      version: '1.0.0',
      capabilities: ['intent_parsing', 'task_decomposition', 'result_aggregation', 'conflict_resolution']
    });
  }

  /**
   * 核心方法:处理旅行规划请求
   */
  async planTrip(userRequest: string): Promise<TripPlan> {
    this.executionState = ExecutionState.PLANNING;
    this.lightEffect.render('thinking', 0.8); // 思考中光效

    // Step 1: 意图拆解
    const tripIntent = await this.parseTravelIntent(userRequest);
    hilog.info(0x0000, 'Orchestrator', `Intent parsed: ${JSON.stringify(tripIntent)}`);

    // Step 2: 任务分解
    const subTasks = this.decomposeTasks(tripIntent);
    hilog.info(0x0000, 'Orchestrator', `Decomposed into ${subTasks.length} sub-tasks`);

    // Step 3: 智能体招标(合同网协议)
    const assignments = await this.contractNetAllocation(subTasks);
    hilog.info(0x0000, 'Orchestrator', `Task assignments: ${JSON.stringify(assignments)}`);

    // Step 4: 并行执行
    this.executionState = ExecutionState.EXECUTING;
    this.lightEffect.render('excited', 0.9); // 执行中光效
    const results = await this.executeInParallel(assignments);

    // Step 5: 冲突检测与协商
    this.executionState = ExecutionState.NEGOTIATING;
    const resolved = await this.resolveConflicts(results);

    // Step 6: 结果聚合与行程生成
    this.executionState = ExecutionState.AGGREGATING;
    const tripPlan = await this.aggregateTripPlan(resolved, tripIntent);

    // Step 7: 完成光效
    this.executionState = ExecutionState.COMPLETED;
    this.lightEffect.render('warm', 0.7);

    return tripPlan;
  }

  /**
   * 意图拆解:将自然语言转为结构化旅行需求
   */
  private async parseTravelIntent(request: string): Promise<TravelIntent> {
    // 使用端侧NLU模型
    const nluResult = await aiEngine.nluParse(request, {
      domain: 'travel_planning',
      entities: ['destination', 'origin', 'dates', 'travelers', 'budget', 'preferences']
    });

    return {
      origin: nluResult.entities.origin || '北京',
      destination: nluResult.entities.destination,
      departureDate: nluResult.entities.dates?.start,
      returnDate: nluResult.entities.dates?.end,
      travelers: parseInt(nluResult.entities.travelers) || 2,
      budget: nluResult.entities.budget,
      preferences: nluResult.entities.preferences || [],
      rawRequest: request
    };
  }

  /**
   * 任务分解
   */
  private decomposeTasks(intent: TravelIntent): SubTask[] {
    const tasks: SubTask[] = [];

    // 任务1:机票查询
    tasks.push({
      id: 'task-flight',
      type: 'flight_search',
      description: `查询${intent.origin}${intent.destination}的往返机票`,
      parameters: {
        origin: intent.origin,
        destination: intent.destination,
        departureDate: intent.departureDate,
        returnDate: intent.returnDate,
        travelers: intent.travelers,
        budget: intent.budget ? intent.budget * 0.4 : undefined // 预算的40%用于机票
      },
      requiredCapabilities: ['flight_search', 'price_compare'],
      priority: 1 // 最高优先级
    });

    // 任务2:酒店搜索
    tasks.push({
      id: 'task-hotel',
      type: 'hotel_search',
      description: `搜索${intent.destination}的酒店`,
      parameters: {
        city: intent.destination,
        checkIn: intent.departureDate,
        checkOut: intent.returnDate,
        guests: intent.travelers,
        budget: intent.budget ? intent.budget * 0.35 : undefined, // 35%用于酒店
        preferences: intent.preferences.filter(p => ['海景', '市中心', '亲子'].includes(p))
      },
      requiredCapabilities: ['hotel_search', 'room_availability'],
      priority: 2
    });

    // 任务3:景点推荐
    tasks.push({
      id: 'task-attraction',
      type: 'attraction_recommend',
      description: `推荐${intent.destination}的景点和路线`,
      parameters: {
        city: intent.destination,
        days: this.calculateDays(intent.departureDate, intent.returnDate),
        preferences: intent.preferences.filter(p => ['文化', '自然', '美食', '购物'].includes(p)),
        travelers: intent.travelers
      },
      requiredCapabilities: ['attraction_recommend', 'route_plan'],
      priority: 3
    });

    // 任务4:预算核算
    tasks.push({
      id: 'task-budget',
      type: 'budget_calculation',
      description: '汇总费用并检查预算',
      parameters: {
        totalBudget: intent.budget,
        expectedExpenses: ['flight', 'hotel', 'attraction', 'food', 'transport']
      },
      requiredCapabilities: ['budget_calc', 'price_forecast'],
      priority: 4,
      dependsOn: ['task-flight', 'task-hotel', 'task-attraction'] // 依赖前三项结果
    });

    return tasks;
  }

  /**
   * 合同网协议:任务分配
   */
  private async contractNetAllocation(tasks: SubTask[]): Promise<TaskAssignment[]> {
    const assignments: TaskAssignment[] = [];

    for (const task of tasks) {
      // 1. 广播招标(Call for Proposals)
      const proposals: AgentProposal[] = [];
      
      for (const [agentId, agent] of this.availableAgents) {
        // 检查Agent是否具备所需能力
        const hasCapabilities = task.requiredCapabilities.every(
          cap => agent.agentInfo.capabilities.includes(cap)
        );
        
        if (!hasCapabilities) continue;

        try {
          const connection = await this.getOrCreateConnection(agentId);
          // 发送CFP,获取投标
          const proposal = await connection.invoke('bid', {
            taskId: task.id,
            taskType: task.type,
            parameters: task.parameters
          });
          
          proposals.push({
            agentId,
            agentName: agent.agentInfo.name,
            deviceName: agent.deviceName,
            estimatedCost: proposal.estimatedCost,
            estimatedTime: proposal.estimatedTime,
            confidence: proposal.confidence,
            proposalData: proposal
          });
        } catch (err) {
          hilog.warn(0x0000, 'Orchestrator', `Agent ${agentId} failed to bid: ${err}`);
        }
      }

      if (proposals.length === 0) {
        throw new Error(`No agent available for task: ${task.id}`);
      }

      // 2. 评估投标并选择最优(多目标优化:成本、时间、置信度)
      const bestProposal = this.selectBestProposal(proposals, task);
      
      assignments.push({
        task,
        assignedAgent: bestProposal,
        status: 'assigned'
      });

      hilog.info(0x0000, 'Orchestrator', 
        `Task ${task.id} assigned to ${bestProposal.agentName} on ${bestProposal.deviceName}`);
    }

    return assignments;
  }

  /**
   * 选择最优投标(加权评分)
   */
  private selectBestProposal(proposals: AgentProposal[], task: SubTask): AgentProposal {
    // 评分权重:成本30% + 时间30% + 置信度40%
    const weights = { cost: 0.3, time: 0.3, confidence: 0.4 };

    const scored = proposals.map(p => {
      // 归一化评分(越高越好)
      const minCost = Math.min(...proposals.map(x => x.estimatedCost));
      const maxCost = Math.max(...proposals.map(x => x.estimatedCost));
      const costScore = maxCost === minCost ? 1 : (maxCost - p.estimatedCost) / (maxCost - minCost);

      const minTime = Math.min(...proposals.map(x => x.estimatedTime));
      const maxTime = Math.max(...proposals.map(x => x.estimatedTime));
      const timeScore = maxTime === minTime ? 1 : (maxTime - p.estimatedTime) / (maxTime - minTime);

      const totalScore = 
        costScore * weights.cost + 
        timeScore * weights.time + 
        p.confidence * weights.confidence;

      return { ...p, score: totalScore };
    });

    scored.sort((a, b) => b.score - a.score);
    return scored[0];
  }

  /**
   * 并行执行所有任务
   */
  private async executeInParallel(assignments: TaskAssignment[]): Promise<Map<string, TaskResult>> {
    const promises = assignments.map(async (assignment) => {
      const connection = await this.getOrCreateConnection(assignment.assignedAgent.agentId);
      
      // 发送执行任务请求
      const result = await connection.invoke('execute', {
        taskId: assignment.task.id,
        parameters: assignment.task.parameters
      });

      return {
        taskId: assignment.task.id,
        result
      };
    });

    const results = await Promise.all(promises);
    const resultMap = new Map<string, TaskResult>();
    results.forEach(r => resultMap.set(r.taskId, r.result));
    
    return resultMap;
  }

  /**
   * 冲突检测与协商
   */
  private async resolveConflicts(results: Map<string, TaskResult>): Promise<Map<string, TaskResult>> {
    const resolved = new Map(results);

    // 检测1:酒店位置与景点距离冲突
    const hotelResult = resolved.get('task-hotel');
    const attractionResult = resolved.get('task-attraction');
    
    if (hotelResult && attractionResult) {
      const hotelLocation = hotelResult.data.location;
      const dailyRoutes = attractionResult.data.dailyRoutes;
      
      // 检查每天的第一站与酒店距离
      for (const day of dailyRoutes) {
        const firstAttraction = day.attractions[0];
        const distance = this.calculateDistance(hotelLocation, firstAttraction.location);
        
        if (distance > 30) { // 超过30km视为冲突
          hilog.warn(0x0000, 'Orchestrator', 
            `Conflict detected: Hotel is ${distance}km from first attraction on day ${day.day}`);
          
          // 触发协商:重新搜索更近的酒店或调整景点顺序
          const negotiated = await this.negotiateHotelAdjustment(hotelResult, day);
          resolved.set('task-hotel', negotiated);
        }
      }
    }

    // 检测2:预算超支
    const budgetResult = resolved.get('task-budget');
    if (budgetResult && budgetResult.data.overBudget) {
      hilog.warn(0x0000, 'Orchestrator', 'Budget exceeded, triggering cost optimization');
      const optimized = await this.optimizeBudget(resolved);
      resolved.set('task-budget', optimized);
    }

    return resolved;
  }

  /**
   * 结果聚合:生成完整行程方案
   */
  private async aggregateTripPlan(
    results: Map<string, TaskResult>, 
    intent: TravelIntent
  ): Promise<TripPlan> {
    const flight = results.get('task-flight')?.data;
    const hotel = results.get('task-hotel')?.data;
    const attractions = results.get('task-attraction')?.data;
    const budget = results.get('task-budget')?.data;

    const days = this.calculateDays(intent.departureDate, intent.returnDate);
    const dailyPlans: DailyPlan[] = [];

    for (let i = 0; i < days; i++) {
      const dayAttractions = attractions?.dailyRoutes[i]?.attractions || [];
      dailyPlans.push({
        day: i + 1,
        date: this.addDays(intent.departureDate, i),
        attractions: dayAttractions,
        meals: this.recommendMeals(dayAttractions),
        transport: i === 0 ? flight?.outbound : (i === days - 1 ? flight?.inbound : 'local')
      });
    }

    return {
      summary: {
        destination: intent.destination,
        dates: { from: intent.departureDate, to: intent.returnDate },
        travelers: intent.travelers,
        totalCost: budget?.total || 0,
        budgetStatus: budget?.status || 'unknown'
      },
      flights: flight,
      hotel: hotel,
      dailyPlans,
      budgetBreakdown: budget?.breakdown,
      tips: this.generateTips(intent, results)
    };
  }

  /**
   * 获取或创建Agent连接(连接池管理)
   */
  private async getOrCreateConnection(agentId: string): Promise<AgentConnection> {
    if (this.agentConnections.has(agentId)) {
      return this.agentConnections.get(agentId)!;
    }

    const agent = this.availableAgents.get(agentId);
    if (!agent) {
      throw new Error(`Agent ${agentId} not available`);
    }

    const connection = await this.discoveryManager.connectToAgent(agentId);
    this.agentConnections.set(agentId, connection);
    return connection;
  }

  // ===== 辅助方法 =====

  private calculateDays(start: string, end: string): number {
    const startDate = new Date(start);
    const endDate = new Date(end);
    return Math.ceil((endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24)) + 1;
  }

  private addDays(date: string, days: number): string {
    const d = new Date(date);
    d.setDate(d.getDate() + days);
    return d.toISOString().split('T')[0];
  }

  private calculateDistance(loc1: Location, loc2: Location): number {
    // 简化版距离计算(实际使用地图API)
    const R = 6371; // 地球半径km
    const dLat = (loc2.lat - loc1.lat) * Math.PI / 180;
    const dLon = (loc2.lng - loc1.lng) * Math.PI / 180;
    const a = Math.sin(dLat/2) * Math.sin(dLat/2) +
              Math.cos(loc1.lat * Math.PI / 180) * Math.cos(loc2.lat * Math.PI / 180) *
              Math.sin(dLon/2) * Math.sin(dLon/2);
    return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
  }

  private async negotiateHotelAdjustment(hotel: any, day: any): Promise<TaskResult> {
    // 重新搜索更近的酒店
    const connection = await this.getOrCreateConnection(
      Array.from(this.availableAgents.values()).find(a => a.agentInfo.type === 'hotel')!.agentInfo.id
    );
    return await connection.invoke('reSearch', {
      originalHotel: hotel,
      constraint: { maxDistanceFrom: day.attractions[0].location, maxDistanceKm: 15 }
    });
  }

  private async optimizeBudget(results: Map<string, TaskResult>): Promise<TaskResult> {
    // 预算优化逻辑:推荐更经济的选项
    return {
      status: 'optimized',
      data: {
        total: 0,
        status: 'optimized',
        breakdown: {},
        savings: []
      }
    };
  }

  private recommendMeals(attractions: any[]): MealRecommendation[] {
    return attractions.map(a => ({
      location: a.location,
      type: a.type === 'cultural' ? 'local_cuisine' : 'casual'
    }));
  }

  private generateTips(intent: TravelIntent, results: Map<string, TaskResult>): string[] {
    const tips: string[] = [];
    const budget = results.get('task-budget')?.data;
    
    if (budget?.status === 'over') {
      tips.push('💡 预算紧张,建议提前预订机票和酒店以获取更优价格');
    }
    if (intent.preferences.includes('亲子')) {
      tips.push('👨‍👩‍👧 已为您筛选亲子友好型酒店和景点');
    }
    
    return tips;
  }
}

// ===== 类型定义 =====

interface TravelIntent {
  origin: string;
  destination: string;
  departureDate: string;
  returnDate: string;
  travelers: number;
  budget?: number;
  preferences: string[];
  rawRequest: string;
}

interface SubTask {
  id: string;
  type: string;
  description: string;
  parameters: any;
  requiredCapabilities: string[];
  priority: number;
  dependsOn?: string[];
}

interface AgentProposal {
  agentId: string;
  agentName: string;
  deviceName: string;
  estimatedCost: number;
  estimatedTime: number;
  confidence: number;
  proposalData: any;
  score?: number;
}

interface TaskAssignment {
  task: SubTask;
  assignedAgent: AgentProposal;
  status: string;
}

interface TaskResult {
  status: string;
  data: any;
}

interface TripPlan {
  summary: TripSummary;
  flights: any;
  hotel: any;
  dailyPlans: DailyPlan[];
  budgetBreakdown: any;
  tips: string[];
}

interface TripSummary {
  destination: string;
  dates: { from: string; to: string };
  travelers: number;
  totalCost: number;
  budgetStatus: string;
}

interface DailyPlan {
  day: number;
  date: string;
  attractions: any[];
  meals: MealRecommendation[];
  transport: string;
}

interface MealRecommendation {
  location: Location;
  type: string;
}

interface Location {
  lat: number;
  lng: number;
}

enum ExecutionState {
  IDLE = 'idle',
  PLANNING = 'planning',
  EXECUTING = 'executing',
  NEGOTIATING = 'negotiating',
  AGGREGATING = 'aggregating',
  COMPLETED = 'completed',
  FAILED = 'failed'
}

3.4 专业智能体实现:以机票Agent为例

// src/agents/FlightAgent.ts
import { distributedHardware } from '@kit.DistributedHardwareKit';

/**
 * 机票智能体
 * 部署在手机端,负责航班查询、比价、预订
 */
export class FlightAgent {
  private serviceId: string;

  constructor() {
    this.serviceId = `agent://flight/${deviceInfo.deviceId}`;
  }

  /**
   * 初始化并注册服务
   */
  async initialize(): Promise<void> {
    // 注册到分布式软总线
    await distributedHardware.registerService({
      serviceId: this.serviceId,
      serviceType: 'agent',
      capabilities: ['flight_search', 'price_compare', 'booking'],
      properties: {
        agentType: 'flight',
        agentName: '机票助手',
        supportedAirlines: ['CA', 'MU', 'CZ', 'HU'],
        maxConcurrentTasks: 3
      }
    });

    // 注册RPC方法处理器
    distributedHardware.onRpcCall(this.serviceId, async (method: string, params: any) => {
      switch (method) {
        case 'bid': return this.handleBid(params);
        case 'execute': return this.handleExecute(params);
        default: throw new Error(`Unknown method: ${method}`);
      }
    });
  }

  /**
   * 处理招标请求(合同网协议)
   */
  private async handleBid(params: any): Promise<any> {
    const { taskType, parameters } = params;
    
    // 评估自身能力
    if (taskType !== 'flight_search') {
      return { canHandle: false, reason: 'Unsupported task type' };
    }

    // 估算成本和置信度
    const origin = parameters.origin;
    const destination = parameters.destination;
    
    // 检查航线覆盖
    const isRouteSupported = await this.checkRouteSupport(origin, destination);
    if (!isRouteSupported) {
      return { canHandle: false, reason: 'Route not supported' };
    }

    // 模拟投标评估
    const estimatedCost = 100; // 计算资源成本
    const estimatedTime = 3000; // 预计3秒完成
    const confidence = 0.95; // 高置信度

    return {
      canHandle: true,
      estimatedCost,
      estimatedTime,
      confidence,
      agentInfo: {
        name: '机票助手',
        device: deviceInfo.deviceName,
        features: ['实时价格', '多航司比价', '退改签保障']
      }
    };
  }

  /**
   * 执行任务
   */
  private async handleExecute(params: any): Promise<TaskResult> {
    const { taskId, parameters } = params;
    hilog.info(0x0000, 'FlightAgent', `Executing task: ${taskId}`);

    try {
      // 1. 查询航班
      const flights = await this.searchFlights(parameters);
      
      // 2. 价格比较
      const compared = this.comparePrices(flights);
      
      // 3. 推荐最优方案
      const recommended = this.recommendFlights(compared, parameters);

      return {
        status: 'success',
        data: {
          outbound: recommended.outbound,
          inbound: recommended.inbound,
          alternatives: recommended.alternatives,
          totalPrice: recommended.totalPrice,
          bookingUrl: recommended.bookingUrl
        }
      };
    } catch (err) {
      return {
        status: 'failed',
        error: err.message
      };
    }
  }

  private async searchFlights(params: any): Promise<Flight[]> {
    // 调用航司API或OTA接口
    // 实际实现需要对接真实数据源
    return [
      {
        flightNo: 'CA1234',
        airline: '中国国际航空',
        departure: { airport: 'PEK', time: '08:00' },
        arrival: { airport: 'SYX', time: '12:30' },
        price: 1280,
        class: '经济舱',
        stops: 0
      },
      {
        flightNo: 'MU5678',
        airline: '东方航空',
        departure: { airport: 'PKX', time: '10:30' },
        arrival: { airport: 'SYX', time: '15:00' },
        price: 1150,
        class: '经济舱',
        stops: 1
      }
    ];
  }

  private comparePrices(flights: Flight[]): Flight[] {
    return flights.sort((a, b) => a.price - b.price);
  }

  private recommendFlights(flights: Flight[], params: any): any {
    const best = flights[0]; // 最优价格
    return {
      outbound: best,
      inbound: { ...best, flightNo: best.flightNo + 'R' }, // 简化处理
      alternatives: flights.slice(1, 4),
      totalPrice: best.price * params.travelers * 2 // 往返
    };
  }

  private async checkRouteSupport(origin: string, destination: string): Promise<boolean> {
    // 检查是否支持该航线
    const supportedRoutes = ['北京-三亚', '上海-三亚', '广州-三亚'];
    return supportedRoutes.includes(`${origin}-${destination}`);
  }
}

interface Flight {
  flightNo: string;
  airline: string;
  departure: { airport: string; time: string };
  arrival: { airport: string; time: string };
  price: number;
  class: string;
  stops: number;
}

3.5 跨设备沉浸光感协作看板(PC端)

// src/pc/TravelDashboard.ets
import { TravelMasterOrchestrator } from '../agents/TravelMasterOrchestrator';
import { LightEffectManager } from '../effects/LightEffectManager';

/**
 * PC端旅行规划看板
 * 特点:
 * 1. 大屏沉浸式展示完整行程
 * 2. 实时显示多智能体协作状态
 * 3. 动态光感反映协作进度
 * 4. 支持拖拽调整行程
 */
@Entry
@Component
struct TravelDashboard {
  @State tripPlan: TripPlan | null = null;
  @State collaborationState: CollaborationState = CollaborationState.IDLE;
  @State agentStates: Map<string, AgentStateInfo> = new Map();
  @State selectedDay: number = 1;

  private orchestrator: TravelMasterOrchestrator;

  aboutToAppear() {
    this.orchestrator = new TravelMasterOrchestrator();
    this.orchestrator.initialize();
    
    // 监听协作状态变化
    this.orchestrator.onStateChange((state) => {
      this.collaborationState = state;
      this.updateLightEffect(state);
    });
  }

  build() {
    Column() {
      // 顶部标题栏
      this.Header()

      if (!this.tripPlan) {
        // 输入区域
        this.InputSection()
      } else {
        // 行程看板
        this.TripBoard()
      }

      // 底部协作状态栏
      this.CollaborationStatusBar()
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#0A0A0F') // 深色背景,光感更明显
  }

  @Builder
  Header() {
    Row() {
      Text('🧳 鸿蒙智能旅行')
        .fontSize(28)
        .fontWeight(FontWeight.Bold)
        .fontColor('#FFFFFF')
      
      // 协作状态指示灯
      Circle()
        .width(12)
        .height(12)
        .fill(this.getStateColor())
        .shadow({
          radius: 8,
          color: this.getStateColor(0.6),
          offsetY: 0
        })
        .animation({
          duration: 1000,
          iterations: -1,
          curve: Curve.EaseInOut
        })

      Text(this.getStateText())
        .fontSize(14)
        .fontColor(this.getStateColor())
    }
    .width('100%')
    .height(64)
    .padding({ left: 32, right: 32 })
    .justifyContent(FlexAlign.SpaceBetween)
    .backgroundColor('rgba(255,255,255,0.05)')
    .backdropBlur(20)
  }

  @Builder
  InputSection() {
    Column() {
      Text('告诉旅行管家你的计划')
        .fontSize(20)
        .fontColor('#FFFFFF')
        .margin({ bottom: 24 })

      // 快捷标签
      Row({ space: 12 }) {
        ForEach(['北京→三亚 5天', '上海→成都 3天', '广州→丽江 7天'], (tag: string) => {
          Text(tag)
            .fontSize(14)
            .fontColor('#4A90D9')
            .padding({ left: 16, right: 16, top: 8, bottom: 8 })
            .backgroundColor('rgba(74, 144, 217, 0.15)')
            .borderRadius(16)
            .border({ width: 1, color: 'rgba(74, 144, 217, 0.3)' })
            .onClick(() => this.startPlanning(tag))
        })
      }
      .margin({ bottom: 24 })

      // 自定义输入
      TextInput({ placeholder: '例如:一家三口从北京去三亚玩5天,预算1万5,想看海和吃海鲜...' })
        .width('60%')
        .height(56)
        .backgroundColor('rgba(255,255,255,0.08)')
        .borderRadius(12)
        .fontColor('#FFFFFF')
        .placeholderColor('rgba(255,255,255,0.4)')
        .onSubmit((value) => this.startPlanning(value))
    }
    .layoutWeight(1)
    .justifyContent(FlexAlign.Center)
  }

  @Builder
  TripBoard() {
    Row() {
      // 左侧日期导航
      this.DayNavigator()

      // 中间行程详情
      this.DayDetail()

      // 右侧预算与智能体状态
      this.SidePanel()
    }
    .width('100%')
    .layoutWeight(1)
  }

  @Builder
  DayNavigator() {
    Column() {
      ForEach(this.tripPlan?.dailyPlans || [], (day: DailyPlan, index: number) => {
        Column() {
          Text(`Day ${day.day}`)
            .fontSize(16)
            .fontWeight(FontWeight.Bold)
            .fontColor(this.selectedDay === day.day ? '#FFFFFF' : 'rgba(255,255,255,0.5)')
          
          Text(day.date)
            .fontSize(12)
            .fontColor('rgba(255,255,255,0.4)')
            .margin({ top: 4 })
        }
        .width(120)
        .height(80)
        .backgroundColor(this.selectedDay === day.day ? 'rgba(74, 144, 217, 0.2)' : 'transparent')
        .borderRadius(12)
        .border({
          width: { left: this.selectedDay === day.day ? 3 : 0 },
          color: '#4A90D9'
        })
        .onClick(() => { this.selectedDay = day.day })
      })
    }
    .width(140)
    .height('100%')
    .padding(16)
    .backgroundColor('rgba(255,255,255,0.03)')
  }

  @Builder
  DayDetail() {
    Column() {
      const day = this.tripPlan?.dailyPlans.find(d => d.day === this.selectedDay);
      if (!day) return;

      // 日期标题
      Text(`${day.date}${day.day}`)
        .fontSize(24)
        .fontColor('#FFFFFF')
        .margin({ bottom: 16 })

      // 景点卡片(带光感效果)
      ForEach(day.attractions, (attraction: any) => {
        this.AttractionCard(attraction)
      })

      // 餐饮推荐
      if (day.meals.length > 0) {
        Text('🍽️ 餐饮推荐')
          .fontSize(16)
          .fontColor('#FFFFFF')
          .margin({ top: 16, bottom: 8 })

        ForEach(day.meals, (meal: any) => {
          Row() {
            Text(meal.type === 'local_cuisine' ? '🥘 当地特色' : '🍜 简餐')
              .fontSize(14)
              .fontColor('rgba(255,255,255,0.7)')
          }
          .width('100%')
          .height(48)
          .backgroundColor('rgba(255,255,255,0.05)')
          .borderRadius(8)
          .padding({ left: 16 })
        })
      }
    }
    .layoutWeight(1)
    .padding(24)
  }

  @Builder
  AttractionCard(attraction: any) {
    Row() {
      // 景点图片(带光晕)
      Stack() {
        Image(attraction.image || $r('app.media.placeholder_attraction'))
          .width(120)
          .height(80)
          .borderRadius(8)
          .objectFit(ImageFit.Cover)
        
        // 光感叠加
        Column()
          .width(120)
          .height(80)
          .backgroundColor('linear-gradient(to right, transparent, rgba(74, 144, 217, 0.3))')
          .borderRadius(8)
      }

      Column() {
        Text(attraction.name)
          .fontSize(16)
          .fontWeight(FontWeight.Bold)
          .fontColor('#FFFFFF')
        
        Text(attraction.description || '热门景点')
          .fontSize(13)
          .fontColor('rgba(255,255,255,0.5)')
          .margin({ top: 4 })
          .maxLines(2)
        
        Row() {
          Text(`${attraction.rating || 4.5}`)
            .fontSize(12)
            .fontColor('#FFD700')
          
          Text(`⏱️ ${attraction.duration || '2小时'}`)
            .fontSize(12)
            .fontColor('rgba(255,255,255,0.4)')
            .margin({ left: 12 })
        }
        .margin({ top: 8 })
      }
      .alignItems(HorizontalAlign.Start)
      .margin({ left: 16 })
      .layoutWeight(1)
    }
    .width('100%')
    .height(100)
    .backgroundColor('rgba(255,255,255,0.05)')
    .borderRadius(12)
    .padding(12)
    .margin({ bottom: 12 })
    .border({
      width: 1,
      color: 'rgba(74, 144, 217, 0.2)'
    })
    .shadow({
      radius: 12,
      color: 'rgba(74, 144, 217, 0.1)',
      offsetY: 4
    })
  }

  @Builder
  SidePanel() {
    Column() {
      // 预算概览
      this.BudgetCard()

      // 智能体协作状态
      this.AgentStatusPanel()

      // 操作按钮
      Button('导出行程')
        .width('100%')
        .height(48)
        .backgroundColor('#4A90D9')
        .fontColor('#FFFFFF')
        .borderRadius(24)
        .margin({ top: 24 })
        .onClick(() => this.exportItinerary())
    }
    .width(280)
    .height('100%')
    .padding(24)
    .backgroundColor('rgba(255,255,255,0.03)')
  }

  @Builder
  BudgetCard() {
    Column() {
      Text('💰 预算概览')
        .fontSize(16)
        .fontWeight(FontWeight.Bold)
        .fontColor('#FFFFFF')
        .margin({ bottom: 12 })

      // 预算环形图(简化版)
      Stack() {
        Circle()
          .width(120)
          .height(120)
          .fill('none')
          .stroke('rgba(255,255,255,0.1)')
          .strokeWidth(8)
        
        Circle()
          .width(120)
          .height(120)
          .fill('none')
          .stroke('#4A90D9')
          .strokeWidth(8)
          .strokeLineCap(LineCapStyle.Round)
          .strokeDashArray([this.getBudgetProgress() * 3.77, 377]) // 2πr ≈ 377

        Column() {
          Text(`¥${this.tripPlan?.summary.totalCost || 0}`)
            .fontSize(20)
            .fontWeight(FontWeight.Bold)
            .fontColor('#FFFFFF')
          
          Text(this.tripPlan?.summary.budgetStatus || '计算中')
            .fontSize(12)
            .fontColor(this.getBudgetColor())
        }
      }
      .width(120)
      .height(120)
      .margin({ bottom: 16 })

      // 费用明细
      ForEach([
        { label: '✈️ 机票', value: this.tripPlan?.budgetBreakdown?.flight || 0, color: '#FF6B6B' },
        { label: '🏨 酒店', value: this.tripPlan?.budgetBreakdown?.hotel || 0, color: '#4ECDC4' },
        { label: '🎫 景点', value: this.tripPlan?.budgetBreakdown?.attraction || 0, color: '#FFD93D' },
        { label: '🍜 餐饮', value: this.tripPlan?.budgetBreakdown?.food || 0, color: '#95E1D3' }
      ], (item: any) => {
        Row() {
          Text(item.label)
            .fontSize(13)
            .fontColor('rgba(255,255,255,0.7)')
          
          Text(`¥${item.value}`)
            .fontSize(13)
            .fontColor(item.color)
        }
        .width('100%')
        .justifyContent(FlexAlign.SpaceBetween)
        .margin({ bottom: 8 })
      })
    }
    .width('100%')
    .padding(16)
    .backgroundColor('rgba(255,255,255,0.05)')
    .borderRadius(16)
    .margin({ bottom: 16 })
  }

  @Builder
  AgentStatusPanel() {
    Column() {
      Text('🤖 智能体协作')
        .fontSize(16)
        .fontWeight(FontWeight.Bold)
        .fontColor('#FFFFFF')
        .margin({ bottom: 12 })

      ForEach(Array.from(this.agentStates.entries()), ([agentId, state]: [string, AgentStateInfo]) => {
        Row() {
          // Agent状态指示灯
          Circle()
            .width(8)
            .height(8)
            .fill(this.getAgentStateColor(state.status))
            .shadow({
              radius: 6,
              color: this.getAgentStateColor(state.status, 0.5),
              offsetY: 0
            })

          Column() {
            Text(state.name)
              .fontSize(13)
              .fontColor('#FFFFFF')
            
            Text(state.currentTask || '空闲')
              .fontSize(11)
              .fontColor('rgba(255,255,255,0.5)')
          }
          .alignItems(HorizontalAlign.Start)
          .margin({ left: 12 })
          .layoutWeight(1)

          // 进度条
          if (state.progress > 0) {
            Progress({ value: state.progress, total: 100, type: ProgressType.Linear })
              .width(60)
              .height(4)
              .color('#4A90D9')
              .backgroundColor('rgba(255,255,255,0.1)')
          }
        }
        .width('100%')
        .height(48)
        .backgroundColor('rgba(255,255,255,0.03)')
        .borderRadius(8)
        .padding({ left: 12, right: 12 })
        .margin({ bottom: 8 })
      })
    }
    .width('100%')
    .padding(16)
    .backgroundColor('rgba(255,255,255,0.05)')
    .borderRadius(16)
  }

  @Builder
  CollaborationStatusBar() {
    Row() {
      // 设备连接状态
      Row({ space: 8 }) {
        ForEach(['📱 手机', '💻 PC', '⌚ 手表'], (device: string) => {
          Text(device)
            .fontSize(12)
            .fontColor('rgba(255,255,255,0.6)')
            .padding({ left: 8, right: 8, top: 4, bottom: 4 })
            .backgroundColor('rgba(255,255,255,0.08)')
            .borderRadius(12)
        })
      }

      // 实时协作日志
      Text(this.getLastLog())
        .fontSize(12)
        .fontColor('rgba(255,255,255,0.4)')
        .maxLines(1)
        .textOverflow({ overflow: TextOverflow.Ellipsis })
        .layoutWeight(1)
        .margin({ left: 16, right: 16 })
    }
    .width('100%')
    .height(40)
    .padding({ left: 24, right: 24 })
    .backgroundColor('rgba(0,0,0,0.3)')
  }

  // ===== 业务逻辑 =====

  private async startPlanning(request: string): Promise<void> {
    this.collaborationState = CollaborationState.PLANNING;
    this.updateLightEffect(CollaborationState.PLANNING);

    try {
      const plan = await this.orchestrator.planTrip(request);
      this.tripPlan = plan;
      this.collaborationState = CollaborationState.COMPLETED;
    } catch (err) {
      this.collaborationState = CollaborationState.FAILED;
      promptAction.showToast({ message: '规划失败,请重试' });
    }
  }

  private updateLightEffect(state: CollaborationState): void {
    const effectMap: Record<CollaborationState, { color: string; intensity: number }> = {
      [CollaborationState.IDLE]: { color: '#4A90D9', intensity: 0.3 },
      [CollaborationState.PLANNING]: { color: '#FFD93D', intensity: 0.7 },
      [CollaborationState.EXECUTING]: { color: '#FF6B6B', intensity: 0.9 },
      [CollaborationState.NEGOTIATING]: { color: '#95E1D3', intensity: 0.8 },
      [CollaborationState.COMPLETED]: { color: '#4ECDC4', intensity: 0.6 },
      [CollaborationState.FAILED]: { color: '#FF4757', intensity: 0.5 }
    };

    const effect = effectMap[state];
    LightEffectManager.getInstance().render(
      state === CollaborationState.EXECUTING ? 'excited' : 
      state === CollaborationState.COMPLETED ? 'warm' : 'professional',
      effect.intensity
    );
  }

  private getStateColor(alpha: number = 1): string {
    const colors: Record<CollaborationState, string> = {
      [CollaborationState.IDLE]: `rgba(74, 144, 217, ${alpha})`,
      [CollaborationState.PLANNING]: `rgba(255, 217, 61, ${alpha})`,
      [CollaborationState.EXECUTING]: `rgba(255, 107, 107, ${alpha})`,
      [CollaborationState.NEGOTIATING]: `rgba(149, 225, 211, ${alpha})`,
      [CollaborationState.COMPLETED]: `rgba(78, 205, 196, ${alpha})`,
      [CollaborationState.FAILED]: `rgba(255, 71, 87, ${alpha})`
    };
    return colors[this.collaborationState];
  }

  private getStateText(): string {
    const texts: Record<CollaborationState, string> = {
      [CollaborationState.IDLE]: '等待输入',
      [CollaborationState.PLANNING]: '意图拆解中...',
      [CollaborationState.EXECUTING]: '多智能体协作执行中...',
      [CollaborationState.NEGOTIATING]: '冲突协商中...',
      [CollaborationState.COMPLETED]: '行程规划完成',
      [CollaborationState.FAILED]: '执行失败'
    };
    return texts[this.collaborationState];
  }

  private getAgentStateColor(status: string, alpha: number = 1): string {
    const colors: Record<string, string> = {
      'idle': `rgba(128, 128, 128, ${alpha})`,
      'working': `rgba(255, 217, 61, ${alpha})`,
      'completed': `rgba(78, 205, 196, ${alpha})`,
      'error': `rgba(255, 71, 87, ${alpha})`
    };
    return colors[status] || colors['idle'];
  }

  private getBudgetProgress(): number {
    if (!this.tripPlan?.summary.totalCost || !this.tripPlan?.summary.budget) return 0;
    return Math.min(this.tripPlan.summary.totalCost / this.tripPlan.summary.budget, 1);
  }

  private getBudgetColor(): string {
    const progress = this.getBudgetProgress();
    if (progress > 0.9) return '#FF6B6B';
    if (progress > 0.7) return '#FFD93D';
    return '#4ECDC4';
  }

  private getLastLog(): string {
    return '机票Agent完成航班查询 | 酒店Agent搜索中...';
  }

  private exportItinerary(): void {
    // 导出为PDF或分享
    hilog.info(0x0000, 'Dashboard', 'Exporting itinerary...');
  }
}

enum CollaborationState {
  IDLE = 'idle',
  PLANNING = 'planning',
  EXECUTING = 'executing',
  NEGOTIATING = 'negotiating',
  COMPLETED = 'completed',
  FAILED = 'failed'
}

interface AgentStateInfo {
  name: string;
  status: string;
  currentTask?: string;
  progress: number;
  deviceName: string;
}

3.6 手机端悬浮导航入口

// src/phone/FloatTravelAgent.ets
import { TravelMasterOrchestrator } from '../agents/TravelMasterOrchestrator';

/**
 * 手机端悬浮旅行Agent入口
 * 作为多设备协作的触发器,长按语音输入后,自动将任务分发到各设备Agent
 */
@Entry
@Component
struct FloatTravelAgent {
  @State isExpanded: boolean = false;
  @State isListening: boolean = false;
  @State recentPlans: TripPlan[] = [];

  private orchestrator: TravelMasterOrchestrator;

  aboutToAppear() {
    this.orchestrator = new TravelMasterOrchestrator();
    this.orchestrator.initialize();
  }

  build() {
    Stack() {
      if (this.isExpanded) {
        // 展开面板
        this.ExpandedPanel()
      }

      // 悬浮球
      this.FloatBall()
    }
    .width('100%')
    .height('100%')
    .backgroundColor(this.isExpanded ? 'rgba(0,0,0,0.5)' : '#00000000')
    .animation({ duration: 200 })
  }

  @Builder
  FloatBall() {
    Stack() {
      // 光晕层
      Circle()
        .width(80)
        .height(80)
        .fill(this.isListening ? '#FFD93D' : '#4A90D9')
        .opacity(0.2)
        .blur(20)
        .scale({ x: this.isListening ? 1.3 : 1.0, y: this.isListening ? 1.3 : 1.0 })
        .animation({ duration: 1000, iterations: -1 })

      Circle()
        .width(64)
        .height(64)
        .fill('#FFFFFF')
        .shadow({
          radius: 12,
          color: this.isListening ? 'rgba(255, 217, 61, 0.4)' : 'rgba(74, 144, 217, 0.4)',
          offsetY: 4
        })

      Image(this.isListening ? $r('app.media.ic_mic') : $r('app.media.ic_travel'))
        .width(32)
        .height(32)
        .fillColor(this.isListening ? '#FFD93D' : '#4A90D9')
    }
    .width(80)
    .height(80)
    .position({ x: 300, y: 600 })
    .gesture(
      GestureGroup(GestureMode.Sequence,
        LongPressGesture({ duration: 500 })
          .onAction(() => this.startVoiceInput()),
        TapGesture()
          .onAction(() => { this.isExpanded = !this.isExpanded })
      )
    )
  }

  @Builder
  ExpandedPanel() {
    Column() {
      Text('🧳 鸿蒙智能旅行')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .fontColor('#FFFFFF')
        .margin({ top: 40, bottom: 24 })

      // 快捷输入
      TextInput({ placeholder: '想去哪里玩?' })
        .width('90%')
        .height(48)
        .backgroundColor('rgba(255,255,255,0.1)')
        .borderRadius(24)
        .fontColor('#FFFFFF')
        .placeholderColor('rgba(255,255,255,0.4)')
        .onSubmit((value) => this.submitRequest(value))

      // 最近行程
      if (this.recentPlans.length > 0) {
        Text('最近行程')
          .fontSize(14)
          .fontColor('rgba(255,255,255,0.6)')
          .margin({ top: 24, bottom: 12 })
          .alignSelf(ItemAlign.Start)
          .margin({ left: '5%' })

        List() {
          ForEach(this.recentPlans, (plan: TripPlan) => {
            ListItem() {
              Row() {
                Column() {
                  Text(plan.summary.destination)
                    .fontSize(16)
                    .fontColor('#FFFFFF')
                  Text(`${plan.summary.dates.from} ~ ${plan.summary.dates.to}`)
                    .fontSize(12)
                    .fontColor('rgba(255,255,255,0.5)')
                }
                .alignItems(HorizontalAlign.Start)
                .layoutWeight(1)

                Text(`¥${plan.summary.totalCost}`)
                  .fontSize(14)
                  .fontColor('#4ECDC4')
              }
              .width('100%')
              .height(64)
              .backgroundColor('rgba(255,255,255,0.08)')
              .borderRadius(12)
              .padding({ left: 16, right: 16 })
            }
          })
        }
        .width('90%')
        .height(200)
      }

      // 多设备提示
      Row() {
        Image($r('app.media.ic_devices'))
          .width(20)
          .height(20)
          .fillColor('rgba(255,255,255,0.6)')
        
        Text('将在手机、平板、PC上协同规划')
          .fontSize(12)
          .fontColor('rgba(255,255,255,0.6)')
          .margin({ left: 8 })
      }
      .margin({ top: 24 })
    }
    .width('100%')
    .height('70%')
    .backgroundColor('#1A1A2E')
    .borderRadius({ topLeft: 24, topRight: 24 })
    .position({ y: '30%' })
  }

  private async startVoiceInput(): Promise<void> {
    this.isListening = true;
    // 语音识别...
    setTimeout(() => {
      this.isListening = false;
      this.submitRequest('一家三口从北京去三亚玩5天');
    }, 2000);
  }

  private async submitRequest(request: string): Promise<void> {
    this.isExpanded = false;
    // 触发多智能体协作
    promptAction.showToast({ message: '正在协调多设备智能体...' });
  }
}

四、运行效果与图片展示

4.1 鸿蒙PC应用多设备统一体验

在这里插入图片描述
在这里插入图片描述

上图展示了HarmonyOS PC应用与手机、平板统一的状态栏和交互体验。我们的旅行看板正是基于这种多端统一的UX设计,在PC大屏上展示完整行程,手机作为语音输入入口。

4.2 多智能体协作生态

在这里插入图片描述

华为Mate X7搭载的鸿蒙6首次商用多智能体协作,"小艺和TA的朋友们"涵盖旅行、购物、金融等垂域智能体。本文的机票Agent、酒店Agent、景点Agent正是这一生态的技术实现。

4.3 分布式软总线跨设备架构

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

分布式软总线是鸿蒙的核心底座,通过任务总线和数据总线实现摄像头、屏幕、存储、MIC等硬件能力的跨设备共享。本文的多智能体协作正是基于软总线的服务发现与RPC通信能力。

4.4 沉浸光感与游戏特效

在这里插入图片描述

HarmonyOS的沉浸光感特效系统不仅用于UI美化,更可应用于游戏和交互场景。本文PC端看板的动态光效正是借鉴了这一渲染管线。


五、关键技术总结

5.1 创新点

创新维度 具体实现
协作协议 基于合同网协议(CNP)的任务分配,支持多目标优化评分
分布式架构 智能体通过软总线自动发现,无需手动配置IP/端口
冲突解决 酒店-景点距离冲突检测 + 自动协商重搜索
状态可视化 协作状态 → 沉浸光感颜色/强度映射,"看得见"的AI思考
多端协同 手机语音输入 → 分布式任务分发 → PC大屏展示

5.2 性能优化

// 1. 连接池复用:避免重复建立跨设备连接
private agentConnections: Map<string, AgentConnection> = new Map();

// 2. 并行执行:无依赖任务同时发起
const promises = assignments.map(async (assignment) => { ... });
const results = await Promise.all(promises);

// 3. 增量更新:仅同步变化的状态
distributedObject.sync({
  strategy: SyncStrategy.PUSH_ONLY_CHANGED,
  interval: 500 // 500ms批量同步
});

5.3 扩展方向

  1. 垂域扩展:将机票/酒店/景点Agent替换为医疗/教育/办公Agent,快速构建行业解决方案
  2. 人机协作:引入"人在回路"机制,关键决策(如预算超支)需用户确认
  3. 模型优化:使用端侧大模型替代规则引擎,提升意图理解准确率

六、结语

本文通过HarmonyOS 6(API 23)的多智能体协作框架(MACF)分布式软总线沉浸光感三大核心能力的深度融合,展示了一种"一呼百应"的跨设备智能体集群架构。旅行管家Agent作为协调者,通过合同网协议将复杂任务智能分配给分布在手机、平板、PC上的专业Agent,实现了真正的"分布式AI"。

从代码层面看,关键创新在于:

  • DeviceDiscoveryManager 实现了基于软总线的智能体自动发现与P2P连接
  • TravelMasterOrchestrator 实现了意图拆解→招标→投标→执行→协商→聚合的完整协作闭环
  • TravelDashboard 将抽象的协作状态转化为直观的沉浸光感可视化

这种架构不仅适用于旅行规划,更可扩展至企业级智能办公(HarmonyOS PC)、智慧医疗会诊工业设备协同运维等场景。期待更多开发者基于MACF框架,构建出更具想象力的鸿蒙多智能体生态!


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

Logo

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

更多推荐