当AI Agent学会“打电话“——微软Agent Framework的A2A与AGUI协议深度解析

"如果说单个AI Agent是一个聪明的员工,那么能够互相通信的Agent网络就是一个高效协作的团队。"

引子:从孤岛到生态

你有没有想过这样一个场景:你的客服AI助手在处理客户投诉时,需要查询发票系统、物流系统和政策库,但这三个系统分别由不同的AI Agent管理。传统做法是什么?要么把所有功能塞进一个超级Agent(然后看着它变得臃肿不堪),要么写一堆胶水代码让它们勉强配合(然后在维护时欲哭无泪)。

微软的Agent Framework给出了一个更优雅的答案:让Agent之间像人类同事一样,通过标准化的"语言"直接对话。这就是A2A(Agent-to-Agent)和AGUI(Agent UI)协议的核心价值------不是造一个无所不能的超级英雄,而是建立一个能够高效协作的复仇者联盟。

今天,我们就来深入剖析这套框架的技术内核,看看微软的工程师们是如何用.NET把这个愿景变成现实的。

一、架构哲学:为什么需要Agent间通信协议?

1.1 单体Agent的困境

想象你正在开发一个企业级AI助手。最初,它只需要回答一些简单问题,一切都很美好。但随着业务增长,需求开始失控:

  • 财务部门要它能查发票

  • 物流部门要它能追踪包裹

  • 客服部门要它能处理退款

  • HR部门要它能查考勤...

你会发现,这个Agent变成了一个"什么都懂一点,什么都不精通"的万金油。更糟糕的是,每次某个部门的业务逻辑变更,你都要重新训练整个模型,牵一发而动全身。

1.2 微服务思想在AI领域的映射

软件工程早就给出了答案:微服务架构。把大系统拆成小服务,每个服务专注做好一件事,通过标准接口通信。

Agent Framework的A2A和AGUI协议,本质上就是把这套思想搬到了AI领域:

复制代码
传统单体Agent              →    Agent微服务架构
┌─────────────────┐              ┌──────────┐
│  超级Agent      │              │ 主Agent  │
│  - 发票查询     │              └────┬─────┘
│  - 物流追踪     │                   │ A2A协议
│  - 政策查询     │         ┌─────────┼─────────┐
│  - 客户服务     │         │         │         │
│  - ...          │      ┌──▼──┐  ┌──▼──┐  ┌──▼──┐
└─────────────────┘      │发票  │  │物流  │  │政策  │
                         │Agent │  │Agent │  │Agent │
                         └─────┘  └─────┘  └─────┘

A2A协议 :定义Agent之间如何"打电话"------如何发起请求、传递消息、处理响应 AGUI协议:定义Agent如何与客户端通信------如何流式传输、状态同步、工具调用

二、A2A协议深度剖析:Agent之间的"外交语言"

2.1 协议设计的核心理念

A2A协议基于Google提出的开放标准,微软在Agent Framework中提供了完整的.NET实现。它的设计哲学可以用三个词概括:

  1. 标准化:就像HTTP之于Web服务,A2A为Agent通信提供统一规范

  2. 异步优先:支持长时间运行的任务,不会因为一个Agent"思考"太久而阻塞整个系统

  3. 上下文保持:通过ContextId维护对话连续性,Agent能记住"我们刚才聊到哪了"

2.2 核心概念解析

让我们通过代码来理解A2A的关键抽象:

复制代码
// A2AAgent: 远程Agent的本地代理
internal sealed class A2AAgent : AIAgent
{
    private readonly A2AClient _a2aClient;
    private readonly string? _id;
    private readonly string? _name;
    
    public override async Task<AgentRunResponse> RunAsync(
        IEnumerable<ChatMessage> messages, 
        AgentThread? thread = null, 
        AgentRunOptions? options = null, 
        CancellationToken cancellationToken = default)
    {
        A2AAgentThread typedThread = this.GetA2AThread(thread, options);
        
        // 构造A2A消息,携带上下文信息
        var a2aMessage = CreateA2AMessage(typedThread, messages);
        
        // 通过A2A协议发送消息
        A2AResponse? a2aResponse = await this._a2aClient
            .SendMessageAsync(new MessageSendParams { Message = a2aMessage }, 
                             cancellationToken);
        
        // 处理响应:可能是即时消息,也可能是长时间任务
        if (a2aResponse is AgentMessage message)
        {
            return ConvertToAgentRunResponse(message);
        }
        else if (a2aResponse is AgentTask task)
        {
            return ConvertToAgentRunResponse(task);
        }
    }
}

这段代码揭示了几个关键设计:

1. 透明代理模式

A2AAgent继承自AIAgent,这意味着调用方根本不需要知道它在和远程Agent通信。就像RPC(远程过程调用)一样,本地调用和远程调用在接口层面完全一致:

复制代码
// 本地Agent
var localAgent = chatClient.CreateAIAgent("本地助手");
await localAgent.RunAsync("你好");

// 远程A2A Agent - 使用方式完全相同!
var remoteAgent = await cardResolver.GetAIAgentAsync();
await remoteAgent.RunAsync("你好");

2. 上下文延续机制

A2AAgentThread维护了两个关键ID:

复制代码
public sealed class A2AAgentThread : AgentThread
{
    public string? ContextId { get; internal set; }  // 对话上下文ID
    public string? TaskId { get; internal set; }     // 当前任务ID
}
  • ContextId:标识一次完整的对话会话,就像你和客服的工单号

  • TaskId:标识Agent正在处理的具体任务,支持任务续传和状态查询

3. 响应类型的二元性

A2A协议支持两种响应模式:

  • AgentMessage:即时响应,适合快速查询(如"今天天气如何?")

  • AgentTask:后台任务,适合耗时操作(如"帮我分析这份100页的报告")

这种设计让框架能够优雅地处理从毫秒级到小时级的各种场景。

2.3 实战案例:多Agent协作的客户投诉处理

让我们看一个真实场景。客户投诉:"我订了1000件T恤,只收到900件!"

传统做法需要人工协调三个系统:

  1. 查发票确认订单

  2. 查物流确认发货数量

  3. 查政策确定处理流程

使用A2A协议,主Agent可以这样编排:

复制代码
// 主Agent的工具定义
var invoiceAgent = await CreateA2AAgent("http://localhost:5000/");
var logisticsAgent = await CreateA2AAgent("http://localhost:5001/");
var policyAgent = await CreateA2AAgent("http://localhost:5002/");

// 将远程Agent包装为本地工具
var tools = new[] {
    invoiceAgent.AsAIFunction(),
    logisticsAgent.AsAIFunction(),
    policyAgent.AsAIFunction()
};

var hostAgent = chatClient.CreateAIAgent(
    name: "客服主管",
    instructions: "你负责协调各部门处理客户投诉",
    tools: tools
);

// 一句话触发多Agent协作
var response = await hostAgent.RunAsync(
    "客户投诉TICKET-XYZ987,声称收到的T恤数量不足"
);

背后发生了什么?主Agent会:

  1. 调用发票Agent查询订单详情

  2. 调用物流Agent确认实际发货量

  3. 调用政策Agent获取处理规范

  4. 综合信息给出解决方案

整个过程对用户来说是一次对话,但底层是三个专业Agent的精密协作。这就是A2A协议的魅力------让复杂性在架构层面被优雅地分解

2.4 技术亮点:流式响应与任务续传

A2A协议的流式API设计值得特别关注:

复制代码
public override async IAsyncEnumerable<AgentRunResponseUpdate> 
    RunStreamingAsync(
        IEnumerable<ChatMessage> messages, 
        AgentThread? thread = null, 
        AgentRunOptions? options = null, 
        CancellationToken cancellationToken = default)
{
    var a2aMessage = CreateA2AMessage(typedThread, messages);
    
    // 订阅服务器发送事件(SSE)流
    var a2aSseEvents = this._a2aClient
        .SendMessageStreamingAsync(
            new MessageSendParams { Message = a2aMessage }, 
            cancellationToken);
    
    await foreach (var sseEvent in a2aSseEvents)
    {
        if (sseEvent.Data is AgentMessage message)
        {
            yield return ConvertToUpdate(message);
        }
        else if (sseEvent.Data is AgentTask task)
        {
            yield return ConvertToUpdate(task);
        }
        else if (sseEvent.Data is TaskUpdateEvent updateEvent)
        {
            // 任务进度更新
            yield return ConvertToUpdate(updateEvent);
        }
    }
}

这里使用了C#的IAsyncEnumerable,配合SSE(Server-Sent Events)实现真正的流式传输。用户可以实时看到Agent的"思考过程",而不是傻等一个最终结果。

更巧妙的是任务续传机制:

复制代码
// 首次调用,Agent开始处理
var response = await agent.RunAsync(message, thread, 
    new AgentRunOptions { AllowBackgroundResponses = true });

// 如果返回了ContinuationToken,说明任务还在后台运行
if (response.ContinuationToken != null)
{
    // 稍后可以用token查询进度
    var updatedResponse = await agent.RunAsync([], thread, 
        new AgentRunOptions { 
            ContinuationToken = response.ContinuationToken 
        });
}

这种设计让Agent能够处理真正的长时间任务,比如"分析过去一年的销售数据并生成报告"------用户不需要保持连接,可以过一小时再回来取结果。

三、AGUI协议深度剖析:Agent与客户端的"实时对讲机"

3.1 AGUI vs A2A:定位差异

如果说A2A是Agent之间的"内部通信协议",那AGUI就是Agent与最终用户(或客户端应用)的"对外接口"。

复制代码
用户应用 <--AGUI--> 主Agent <--A2A--> 专业Agent群
   │                    │              │
   │                    │              ├─ 发票Agent
   │                    │              ├─ 物流Agent
   │                    │              └─ 政策Agent
   │                    │
   └─ 实时流式交互      └─ 任务编排协调

AGUI的核心特性:

  1. 完整消息历史:每次请求都发送全部对话历史(类似ChatGPT的做法)

  2. 丰富的事件类型:不只是文本,还有工具调用、状态更新、错误通知等

  3. 客户端工具执行:支持在客户端执行某些工具(比如访问本地传感器)

3.2 核心实现:AGUIChatClient的巧妙设计

AGUIChatClient的实现展示了如何在标准IChatClient接口上构建协议适配层:

复制代码
public sealed class AGUIChatClient : DelegatingChatClient
{
    public override async IAsyncEnumerable<ChatResponseUpdate> 
        GetStreamingResponseAsync(
            IEnumerable<ChatMessage> messages,
            ChatOptions? options = null,
            CancellationToken cancellationToken = default)
    {
        // 生成或复用Thread ID
        var threadId = ExtractThreadIdFromOptions(options) 
                    ?? $"thread_{Guid.NewGuid():N}";
        var runId = $"run_{Guid.NewGuid():N}";
        
        // 构造AGUI请求
        var input = new RunAgentInput
        {
            ThreadId = threadId,
            RunId = runId,
            Messages = messages.AsAGUIMessages(),
            Tools = options?.Tools?.AsAGUITools()
        };
        
        // 发送POST请求,接收SSE流
        await foreach (var update in 
            this._httpService.PostRunAsync(input, cancellationToken)
                .AsChatResponseUpdatesAsync(cancellationToken))
        {
            // 处理不同类型的更新
            yield return ProcessUpdate(update);
        }
    }
}

设计亮点1: 透明的Thread管理

AGUI要求每次请求都带ThreadId,但IChatClient接口并没有这个概念。框架通过AdditionalProperties巧妙地传递这个信息:

复制代码
// 首次调用,框架自动生成ThreadId
var response = await chatClient.GetResponseAsync(messages);

// 后续调用,ThreadId通过ConversationId传递
var options = new ChatOptions { 
    ConversationId = response.ConversationId 
};
var nextResponse = await chatClient.GetResponseAsync(newMessages, options);

用户感知不到ThreadId的存在,但框架确保了对话的连续性。

设计亮点2: 客户端工具的智能路由

AGUI支持一个强大特性:某些工具在服务端执行,某些在客户端执行。框架如何区分?

复制代码
// 客户端注册的工具集
var clientToolSet = new HashSet<string>();
foreach (var tool in options?.Tools ?? [])
{
    clientToolSet.Add(tool.Name);
}

// 处理工具调用响应
if (update.Contents[0] is FunctionCallContent fcc)
{
    if (clientToolSet.Contains(fcc.Name))
    {
        // 这是客户端工具,交给FunctionInvokingChatClient处理
        PrepareForClientExecution(fcc);
    }
    else
    {
        // 这是服务端工具,已经执行完毕,直接返回结果
        yield return ConvertServerResult(fcc);
    }
}

这种设计让同一个Agent可以同时使用服务端能力(如数据库查询)和客户端能力(如读取本地传感器),实现真正的混合执行模式。

3.3 实战案例:智能家居控制Agent

让我们看一个AGUI的典型应用场景------智能家居助手:

复制代码
// 服务端Agent定义
var agent = chatClient.CreateAIAgent(
    name: "智能家居助手",
    tools: [
        AIFunctionFactory.Create(
            () => DateTimeOffset.UtcNow,
            name: "get_current_time",
            description: "获取当前时间"
        ),
        AIFunctionFactory.Create(
            (WeatherRequest req) => GetWeatherForecast(req),
            name: "get_weather",
            description: "获取天气预报"
        )
    ]
);

// 客户端连接并注册本地工具
var aguiClient = new AGUIChatClient(httpClient, serverUrl);
var clientAgent = aguiClient.CreateAIAgent(
    name: "客户端代理",
    tools: [
        AIFunctionFactory.Create(
            (SensorRequest req) => ReadLocalSensors(req),
            name: "read_climate_sensors",
            description: "读取本地温湿度传感器"
        ),
        AIFunctionFactory.Create(
            () => ChangeBackgroundColor(),
            name: "change_background_color",
            description: "改变界面背景色"
        )
    ]
);

// 用户提问:"现在室内温度多少?外面天气如何?"
await foreach (var update in clientAgent.RunStreamingAsync(userMessage))
{
    // Agent会自动决定:
    // 1. 调用客户端的read_climate_sensors获取室内温度
    // 2. 调用服务端的get_weather获取室外天气
    // 3. 综合信息回答用户
    
    foreach (var content in update.Contents)
    {
        if (content is TextContent text)
        {
            Console.Write(text.Text);  // 实时显示Agent的回答
        }
        else if (content is FunctionCallContent funcCall)
        {
            Console.WriteLine($"[调用工具: {funcCall.Name}]");
        }
    }
}

这个例子展示了AGUI的强大之处:

  • 服务端工具(get_weather)可以访问云端API和数据库

  • 客户端工具(read_climate_sensors)可以访问本地硬件

  • Agent自动编排两类工具,用户无需关心执行位置

3.4 事件流的精妙设计

AGUI定义了丰富的事件类型,让客户端能够精确感知Agent的每个动作:

复制代码
// AGUI事件类型
public enum AGUIEventTypes
{
    RunStarted,           // 运行开始
    TextMessageStart,     // 文本消息开始
    TextMessageContent,   // 文本内容(流式)
    TextMessageEnd,       // 文本消息结束
    ToolCallStart,        // 工具调用开始
    ToolCallArgs,         // 工具参数(流式)
    ToolCallEnd,          // 工具调用结束
    ToolCallResult,       // 工具执行结果
    StateDelta,           // 状态增量更新
    StateSnapshot,        // 状态快照
    RunFinished,          // 运行完成
    RunError              // 运行错误
}

这种细粒度的事件设计让客户端可以构建丰富的UI体验:

复制代码
await foreach (var update in agent.RunStreamingAsync(messages))
{
    foreach (var content in update.Contents)
    {
        switch (content)
        {
            case TextContent text:
                // 逐字显示,模拟打字效果
                await TypewriterEffect(text.Text);
                break;
                
            case FunctionCallContent funcCall:
                // 显示"正在查询天气..."的加载动画
                ShowLoadingIndicator($"正在{funcCall.Name}...");
                break;
                
            case FunctionResultContent result:
                // 隐藏加载动画,显示结果
                HideLoadingIndicator();
                break;
                
            case ErrorContent error:
                // 显示错误提示
                ShowErrorNotification(error.Message);
                break;
        }
    }
}

四、架构对比:A2A vs AGUI vs 传统方案

让我们通过一个表格直观对比三种架构方案:

维度 传统REST API A2A协议 AGUI协议
通信模式 请求-响应 消息+任务 流式事件
状态管理 无状态/手动管理 ContextId自动管理 ThreadId+RunId管理
长时间任务 需要轮询或WebHook 原生支持ContinuationToken 支持后台任务
流式传输 需要额外实现 SSE原生支持 SSE原生支持
工具执行 仅服务端 仅服务端 客户端+服务端混合
协议标准化 各自实现 Google A2A标准 新兴标准
适用场景 简单查询 Agent间协作 Agent与用户交互

选型建议:

  1. 纯后端Agent协作 → 使用A2A协议

  2. 需要客户端交互 → 使用AGUI协议

  3. 简单的单次查询 → 传统REST API足够

五、生产实践:从Demo到Production的关键考量

5.1 性能优化策略

1. 连接池管理

复制代码
// 不要每次都创建新的HttpClient
// ❌ 错误做法
var client = new HttpClient();
var aguiClient = new AGUIChatClient(client, serverUrl);

// ✅ 正确做法:使用IHttpClientFactory
services.AddHttpClient<AGUIChatClient>();

2. 流式响应的背压控制

复制代码
// 处理速度跟不上生产速度时,需要背压控制
await foreach (var update in agent.RunStreamingAsync(messages)
    .WithCancellation(cancellationToken))
{
    // 如果UI渲染太慢,考虑批量处理
    await Task.Delay(10);  // 给UI喘息的机会
    ProcessUpdate(update);
}

3. Agent Card缓存

复制代码
// Agent Card不会频繁变化,应该缓存
private static readonly ConcurrentDictionary<string, AIAgent> _agentCache = new();

public async Task<AIAgent> GetOrCreateAgentAsync(string url)
{
    return _agentCache.GetOrAdd(url, async u => 
    {
        var resolver = new A2ACardResolver(new Uri(u), _httpClient);
        return await resolver.GetAIAgentAsync();
    });
}

5.2 错误处理与重试

A2A和AGUI都是网络协议,必须考虑各种异常情况:

复制代码
public async Task<AgentRunResponse> RunWithRetryAsync(
    AIAgent agent, 
    string message,
    int maxRetries = 3)
{
    for (int i = 0; i < maxRetries; i++)
    {
        try
        {
            return await agent.RunAsync(message);
        }
        catch (HttpRequestException ex) when (i < maxRetries - 1)
        {
            // 网络错误,指数退避重试
            await Task.Delay(TimeSpan.FromSeconds(Math.Pow(2, i)));
            _logger.LogWarning($"重试第{i + 1}次: {ex.Message}");
        }
        catch (TaskCanceledException ex)
        {
            // 超时错误,检查是否有ContinuationToken
            if (ex.CancellationToken.IsCancellationRequested)
            {
                throw;  // 用户主动取消,不重试
            }
            _logger.LogWarning("请求超时,尝试使用ContinuationToken恢复");
            // 实现续传逻辑...
        }
    }
    throw new Exception("达到最大重试次数");
}

5.3 安全性考虑

1. Agent身份验证

复制代码
// 服务端:验证调用方身份
app.MapA2A("/", agent, options => 
{
    options.RequireAuthorization = true;
    options.AllowedOrigins = new[] { "https://trusted-client.com" };
});

// 客户端:提供认证信息
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = 
    new AuthenticationHeaderValue("Bearer", apiKey);

2. 工具权限控制

复制代码
// 不是所有工具都应该暴露给所有Agent
var agent = chatClient.CreateAIAgent(
    name: "受限Agent",
    tools: FilterToolsByPermission(allTools, currentUserRole)
);

private IList<AITool> FilterToolsByPermission(
    IList<AITool> tools, 
    string userRole)
{
    return tools.Where(t => 
        t.Metadata.GetValueOrDefault("RequiredRole") as string 
        == userRole
    ).ToList();
}

5.4 可观测性:让Agent行为可追踪

复制代码
// 集成OpenTelemetry追踪Agent调用链
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .AddSource("Microsoft.Agents.AI")
    .AddConsoleExporter()
    .Build();

// 每次Agent调用都会生成Span
await agent.RunAsync(message);  

// 在分布式追踪系统中可以看到:
// Span 1: HostAgent.RunAsync
//   Span 2: InvoiceAgent.RunAsync (A2A调用)
//   Span 3: LogisticsAgent.RunAsync (A2A调用)
//   Span 4: PolicyAgent.RunAsync (A2A调用)

六、未来展望:Agent生态的演进方向

6.1 标准化进程

A2A协议目前由Google主导,正在快速演进(当前v2.x,v3.0即将发布)。微软的积极参与表明:

  • 跨平台互操作将成为现实:Python的Agent可以调用.NET的Agent

  • Agent市场可能出现:就像Docker Hub一样,开发者可以发布和订阅Agent服务

  • 协议生态会更丰富:除了A2A和AGUI,可能出现更多专用协议

6.2 技术演进趋势

1. 更智能的Agent路由

复制代码
// 未来可能出现的Agent网关
var gateway = new AgentGateway()
    .RegisterAgent("invoice", invoiceAgentUrl)
    .RegisterAgent("logistics", logisticsAgentUrl)
    .WithLoadBalancing()      // 负载均衡
    .WithCircuitBreaker()     // 熔断保护
    .WithRateLimiting();      // 限流控制

// 主Agent只需要知道网关地址
var hostAgent = chatClient.CreateAIAgent(
    tools: gateway.GetAllAgentsAsTools()
);

2. Agent能力的动态发现

复制代码
// 不需要硬编码Agent URL,通过服务发现
var discoveryClient = new AgentDiscoveryClient("https://agent-registry.com");
var agents = await discoveryClient.FindAgentsAsync(
    capabilities: new[] { "invoice_query", "logistics_tracking" }
);

// 动态组装工具集
var tools = agents.Select(a => a.AsAIFunction()).ToList();

3. 多模态Agent协作

复制代码
// 未来的Agent可能不只处理文本
var visionAgent = await CreateA2AAgent("https://vision-agent.com");
var audioAgent = await CreateA2AAgent("https://audio-agent.com");

// 用户上传图片+语音,多个Agent协同处理
var response = await hostAgent.RunAsync(
    messages: [
        new ChatMessage(ChatRole.User, [
            new ImageContent(imageBytes),
            new AudioContent(audioBytes),
            new TextContent("这张图片里的人在说什么?")
        ])
    ]
);

七、总结:重新定义AI应用的构建方式

回到文章开头的问题:如何构建一个既强大又灵活的AI系统?

微软Agent Framework通过A2A和AGUI协议给出的答案是:不要试图造一个无所不能的超级Agent,而是建立一个能够高效协作的Agent网络

这种架构带来的价值是多维度的:

对开发者:

  • 关注点分离:每个Agent只需专注自己的领域

  • 技术栈自由:不同Agent可以用不同语言、不同模型

  • 渐进式演进:新增功能只需添加新Agent,不影响现有系统

对企业:

  • 降低维护成本:业务变更只影响对应的Agent

  • 提高复用性:同一个Agent可以被多个应用调用

  • 增强可扩展性:Agent可以独立扩容和部署

对用户:

  • 更好的体验:流式响应让交互更自然

  • 更强的能力:多Agent协作解决复杂问题

  • 更高的可靠性:单个Agent故障不影响整体服务

当然,这套架构也不是银弹。它引入了分布式系统的复杂性:网络延迟、部分失败、一致性问题等。但就像微服务架构一样,当系统复杂度达到一定程度,这些代价是值得的。

最后的思考:如果说GPT-4让我们看到了单个AI的潜力,那么A2A和AGUI协议让我们看到了AI网络的未来。就像互联网连接了全世界的计算机,Agent协议正在连接全世界的AI。

这不是科幻,这是正在发生的现实。而微软Agent Framework,正是这场变革的重要推动者。


参考资源


更多AIGC文章

RAG技术全解:从原理到实战的简明指南

更多VibeCoding文章

相关推荐
AngelPP21 小时前
OpenClaw 架构深度解析:如何把 AI 助手搬到你的个人设备上
人工智能
宅小年21 小时前
Claude Code 换成了Kimi K2.5后,我再也回不去了
人工智能·ai编程·claude
九狼1 天前
Flutter URL Scheme 跨平台跳转
人工智能·flutter·github
ZFSS1 天前
Kimi Chat Completion API 申请及使用
前端·人工智能
天翼云开发者社区1 天前
春节复工福利就位!天翼云息壤2500万Tokens免费送,全品类大模型一键畅玩!
人工智能·算力服务·息壤
知识浅谈1 天前
教你如何用 Gemini 将课本图片一键转为精美 PPT
人工智能
Ray Liang1 天前
被低估的量化版模型,小身材也能干大事
人工智能·ai·ai助手·mindx
shengjk11 天前
NanoClaw 深度剖析:一个"AI 原生"架构的个人助手是如何运转的?
人工智能
西门老铁1 天前
🦞OpenClaw 让 MacMini 脱销了,而我拿出了6年陈的安卓机
人工智能