初识 ACP (Agent Client Protocol)

初识 ACP 协议:AI 编码助手的标准化通信协议

从 MCP 到 ACP,探索 AI Agent 生态的标准化之路

目录

  • [一、引言:AI Agent 生态的标准化挑战](#一、引言:AI Agent 生态的标准化挑战 "#%E4%B8%80%E5%BC%95%E8%A8%80ai-agent-%E7%94%9F%E6%80%81%E7%9A%84%E6%A0%87%E5%87%86%E5%8C%96%E6%8C%91%E6%88%98")
  • [二、从 MCP 说起:理解 AI 协议的演进](#二、从 MCP 说起:理解 AI 协议的演进 "#%E4%BA%8C%E4%BB%8E-mcp-%E8%AF%B4%E8%B5%B7%E7%90%86%E8%A7%A3-ai-%E5%8D%8F%E8%AE%AE%E7%9A%84%E6%BC%94%E8%BF%9B")
  • [三、ACP 是什么?](#三、ACP 是什么? "#%E4%B8%89acp-%E6%98%AF%E4%BB%80%E4%B9%88")
  • [四、ACP 核心架构设计](#四、ACP 核心架构设计 "#%E5%9B%9Bacp-%E6%A0%B8%E5%BF%83%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A1")
  • [五、ACP 协议详解](#五、ACP 协议详解 "#%E4%BA%94acp-%E5%8D%8F%E8%AE%AE%E8%AF%A6%E8%A7%A3")
  • [六、ACP 实战:从代码看实现](#六、ACP 实战:从代码看实现 "#%E5%85%ADacp-%E5%AE%9E%E6%88%98%E4%BB%8E%E4%BB%A3%E7%A0%81%E7%9C%8B%E5%AE%9E%E7%8E%B0")
  • [七、ACP vs MCP:两个协议的对比与互补](#七、ACP vs MCP:两个协议的对比与互补 "#%E4%B8%83acp-vs-mcp%E4%B8%A4%E4%B8%AA%E5%8D%8F%E8%AE%AE%E7%9A%84%E5%AF%B9%E6%AF%94%E4%B8%8E%E4%BA%92%E8%A1%A5")
  • 八、生态系统与实际应用
  • 九、最佳实践与安全考量
  • 十、未来展望

一、引言:AI Agent 生态的标准化挑战

1.1 当前 AI 开发工具面临的问题

在 AI 辅助编程工具快速发展的今天,我们看到了各种强大的 AI 编码助手:

  • GitHub Copilot:微软的 AI 代码补全工具
  • Cursor:AI 驱动的代码编辑器
  • Claude Code:Anthropic 的智能编码助手
  • Codex CLI:OpenAI 的命令行编码工具
  • Gemini Code Assist:Google 的编码助手

然而,这些工具之间存在严重的互操作性问题

graph TB subgraph "现状:信息孤岛" VSCode[VS Code] -->|锁定| Copilot[Copilot] Zed[Zed] -->|锁定| Agent[Agent] Claude[Claude] Gemini[Gemini] VSCode -.X.- Claude VSCode -.X.- Gemini Zed -.X.- Claude Zed -.X.- Copilot style VSCode fill:#e1f5ff style Zed fill:#e1f5ff style Copilot fill:#fff4e6 style Agent fill:#fff4e6 style Claude fill:#f3e5f5 style Gemini fill:#f3e5f5 end Note["每个编辑器只能用特定的 Agent
用户无法自由选择和切换"] style Note fill:#ffebee,stroke:#c62828

核心挑战:

  1. 编辑器锁定:用户必须为特定 AI Agent 切换编辑器
  2. 重复开发:每个编辑器都要为每个 Agent 单独开发集成
  3. 用户体验割裂:不同 Agent 的交互方式完全不同
  4. 生态碎片化:难以形成统一的开发者社区

1.2 标准化协议的价值

正如 Language Server Protocol (LSP) 将语言智能从单一 IDE 中解放出来,我们需要一个类似的标准来解决 AI Agent 的互操作性问题。

这就是 Agent Client Protocol (ACP) 诞生的背景。


二、从 MCP 说起:理解 AI 协议的演进

2.1 什么是 MCP?

在介绍 ACP 之前,我们需要先了解 MCP (Model Context Protocol)

MCP 是 Anthropic 推出的开源标准协议,用于连接 AI 模型外部系统(数据源、工具、API 等)。

graph TD AIModel["AI Model
(Claude, GPT, etc.)"] AIModel -->|MCP Protocol| MCPServers subgraph MCPServers["MCP Servers"] DB[Database Server] FS[File System] API[API Services] KB[Knowledge Base] end style AIModel fill:#e3f2fd style MCPServers fill:#f3e5f5 style DB fill:#fff3e0 style FS fill:#fff3e0 style API fill:#fff3e0 style KB fill:#fff3e0

MCP 的三大核心原语:

2.1.1 Resources(资源)

类似文件系统的只读数据源,供 AI 模型读取上下文。

typescript 复制代码
// MCP Resource 示例
{
  "uri": "file:///workspace/README.md",
  "name": "项目文档",
  "mimeType": "text/markdown",
  "description": "项目需求和架构文档"
}
2.1.2 Tools(工具)

AI 模型可调用的可执行函数。

python 复制代码
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("code-tools")

@mcp.tool()
async def run_tests(test_file: str) -> str:
    """运行指定的测试文件"""
    result = subprocess.run(['pytest', test_file], capture_output=True)
    return result.stdout.decode()
2.1.3 Prompts(提示模板)

预编写的任务模板,标准化常见操作。

typescript 复制代码
{
  "name": "code_review",
  "description": "代码审查提示模板",
  "arguments": [
    {
      "name": "language",
      "description": "编程语言",
      "required": true
    }
  ]
}

2.2 MCP 的局限性

虽然 MCP 解决了 AI 模型与工具的连接问题,但它并不解决编辑器与 AI Agent 的通信问题

graph LR Editor["编辑器
(Zed)"] -.->|"❓ 没有标准协议"| Agent["AI Agent
(Claude)"] Agent -->|"✓ MCP 协议"| Tools["工具
(DB/API)"] style Editor fill:#ffebee style Agent fill:#e8f5e9 style Tools fill:#e8f5e9

这就是 ACP 要解决的问题。


三、ACP 是什么?

3.1 定义

Agent Client Protocol (ACP) 是一个开放标准协议 ,用于规范代码编辑器与 **AI 编码助手(Coding Agent)**之间的通信。

graph LR Editor["Editor
(Zed)"] Agent["Agent
(Claude)"] Tools["Tools & Resources"] Editor <-->|ACP Protocol| Agent Agent -->|MCP Protocol| Tools style Editor fill:#e3f2fd style Agent fill:#fff3e0 style Tools fill:#e8f5e9

核心理念:

就像 USB-C 接口可以连接任何设备,ACP 让任何编辑器都能使用任何 AI Agent。

3.2 设计目标

目标 说明
通用性 任何编辑器都能集成任何符合 ACP 的 Agent
隐私优先 本地通信,不经过第三方服务器
开源开放 Apache 2.0 许可证,任何人都可以实现
可扩展性 支持未来的新功能和新场景

3.3 与 LSP 的类比

如果你熟悉 Language Server Protocol (LSP),可以这样理解 ACP:

LSP 之于语言智能 = ACP 之于 AI 编码助手

graph LR subgraph LSP["LSP 模式"] E1[VS Code] <-->|LSP| L1[TypeScript] E2[Vim] <-->|LSP| L2[Python] E3[Emacs] <-->|LSP| L3[Go] end subgraph ACP["ACP 模式"] E4[Zed] <-->|ACP| A1[Claude Code] E5[Neovim] <-->|ACP| A2[Gemini] E6[JetBrains] <-->|ACP| A3[Codex] end style LSP fill:#e3f2fd style ACP fill:#fff3e0

四、ACP 核心架构设计

4.1 通信模型

ACP 采用 JSON-RPC 2.0 协议,基于 **stdio(标准输入输出)**进行通信。

graph TD Editor["Editor
(主进程)"] Agent["Agent
(子进程)"] Editor -->|"spawn()"| Agent Editor -->|"写入 stdin
(JSON-RPC 2.0)"| Agent Agent -->|"写入 stdout
(JSON-RPC 2.0)"| Editor style Editor fill:#e3f2fd style Agent fill:#fff3e0 Note["通信方式:
• Editor 写入 Agent 的 stdin
• Agent 写入 stdout 返回给 Editor
• 消息格式:JSON-RPC 2.0"] style Note fill:#e8f5e9

优势:

  1. 简单高效:无需网络层,直接进程间通信
  2. 隐私安全:所有数据都在本地,不经过外部服务器
  3. 跨平台:stdin/stdout 是所有操作系统的标准

4.2 协议层次

ACP 分为两个核心层:

graph TD subgraph Application["应用层 (Application Layer)"] SM[Session Management] TC[Tool Calls] PR[Permission Requests] FO[File Operations] end subgraph Protocol["协议层 (Protocol Layer)"] JSON[JSON-RPC 2.0] RR[Request/Response] NT[Notifications] EH[Error Handling] end subgraph Transport["传输层 (Transport Layer)"] STDIO[stdio - stdin/stdout] end Application --> Protocol Protocol --> Transport style Application fill:#e3f2fd style Protocol fill:#fff3e0 style Transport fill:#e8f5e9

4.3 消息类型

ACP 支持三种消息类型:

4.3.1. Request(请求)

客户端向服务器发送请求,期待响应。

json 复制代码
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "0.1.0",
    "clientInfo": {
      "name": "Zed",
      "version": "0.158.0"
    }
  }
}
4.3.2. Response(响应)

服务器对请求的响应。

json 复制代码
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "0.1.0",
    "serverInfo": {
      "name": "Claude Code",
      "version": "1.0.0"
    },
    "capabilities": {
      "tools": true,
      "resources": true
    }
  }
}
4.3.3. Notification(通知)

单向消息,不期待响应。

json 复制代码
{
  "jsonrpc": "2.0",
  "method": "session/update",
  "params": {
    "sessionId": "session-123",
    "update": {
      "sessionUpdate": "agent_message_chunk",
      "content": {
        "type": "text",
        "text": "正在分析代码..."
      }
    }
  }
}

五、ACP 协议详解

5.1 核心方法

ACP 定义了一系列标准方法:

方法 类型 说明
initialize Request 初始化连接,交换能力信息
authenticate Request 身份验证(可选)
session/new Request 创建新的对话会话
session/prompt Request 向 Agent 发送用户消息
session/update Notification Agent 推送会话更新
session/request_permission Notification Agent 请求用户权限
fs/read_text_file Request 读取文件内容
fs/write_text_file Request 写入文件内容
end_turn Notification Agent 完成一轮响应

5.2 初始化流程

sequenceDiagram participant Editor participant Agent Editor->>Agent: spawn(agent-cli) Note over Editor,Agent: 启动 Agent 子进程 Editor->>Agent: initialize request Note right of Editor: {clientInfo, version} Agent-->>Editor: initialize response Note left of Agent: {serverInfo, capabilities} Editor->>Agent: authenticate (optional) Agent-->>Editor: auth response Editor->>Agent: session/new Note right of Editor: {cwd, mcpServers} Agent-->>Editor: session created Note left of Agent: {sessionId} Note over Editor,Agent: ● 连接建立完成,可以开始对话

详细说明:

步骤 1:启动 Agent 进程
typescript 复制代码
// AionUi 项目中的实际代码
// src/agent/acp/AcpConnection.ts

async connect(backend: AcpBackend, cliPath?: string, workingDir?: string) {
  const command = cliPath || this.getDefaultCliPath(backend);

  // 使用 spawn 启动 Agent 子进程
  this.agentProcess = spawn(command, [], {
    cwd: workingDir,
    env: process.env,
  });

  // 监听 stdout(Agent 的输出)
  this.agentProcess.stdout.on('data', this.handleStdout.bind(this));

  // 监听 stderr(Agent 的日志)
  this.agentProcess.stderr.on('data', this.handleStderr.bind(this));

  // 初始化协议
  await this.initialize();
}
步骤 2:发送初始化请求
typescript 复制代码
private async initialize(): Promise<AcpResponse> {
  return await this.sendRequest('initialize', {
    protocolVersion: '0.1.0',
    clientInfo: {
      name: 'AionUi',
      version: '1.0.0',
    },
  });
}
步骤 3:接收能力信息
json 复制代码
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "0.1.0",
    "serverInfo": {
      "name": "Claude Code",
      "version": "1.0.128"
    },
    "capabilities": {
      "tools": true,
      "resources": true,
      "streaming": false
    }
  }
}

5.3 会话更新类型

ACP 定义了丰富的会话更新类型,让编辑器能实时显示 Agent 的思考和操作过程。

typescript 复制代码
// AionUi 项目中的类型定义
// src/types/acpTypes.ts

export type AcpSessionUpdate =
  | AgentMessageChunkUpdate // Agent 消息块
  | AgentThoughtChunkUpdate // Agent 思考过程
  | ToolCallUpdate // 工具调用
  | ToolCallUpdateStatus // 工具状态更新
  | PlanUpdate // 任务计划
  | AvailableCommandsUpdate // 可用命令列表
  | UserMessageChunkUpdate; // 用户消息块
5.3.1. Agent 消息块(AgentMessageChunkUpdate)

Agent 向用户发送的普通消息。

json 复制代码
{
  "method": "session/update",
  "params": {
    "sessionId": "sess-123",
    "update": {
      "sessionUpdate": "agent_message_chunk",
      "content": {
        "type": "text",
        "text": "我已经分析了你的代码,发现了以下问题..."
      }
    }
  }
}
5.3.2. Agent 思考过程(AgentThoughtChunkUpdate)

Agent 的内部思考过程,类似 "思维链"。

json 复制代码
{
  "method": "session/update",
  "params": {
    "sessionId": "sess-123",
    "update": {
      "sessionUpdate": "agent_thought_chunk",
      "content": {
        "type": "text",
        "text": "首先,我需要检查 package.json 中的依赖版本..."
      }
    }
  }
}
5.3.3. 工具调用(ToolCallUpdate)

最重要的更新类型,表示 Agent 要执行某个操作。

typescript 复制代码
interface ToolCallUpdate {
  sessionUpdate: 'tool_call';
  toolCallId: string; // 工具调用唯一 ID
  status: 'pending' | 'in_progress' | 'completed' | 'failed';
  title: string; // 操作描述
  kind: 'read' | 'edit' | 'execute'; // 操作类型
  rawInput?: any; // 原始输入参数
  content?: Array<{
    type: 'content' | 'diff';
    // ... 内容详情
  }>;
  locations?: Array<{
    path: string; // 受影响的文件路径
  }>;
}

示例:读取文件

json 复制代码
{
  "method": "session/update",
  "params": {
    "sessionId": "sess-123",
    "update": {
      "sessionUpdate": "tool_call",
      "toolCallId": "tool-001",
      "status": "pending",
      "title": "读取 src/index.ts",
      "kind": "read",
      "locations": [{ "path": "/workspace/src/index.ts" }]
    }
  }
}

示例:编辑文件

json 复制代码
{
  "method": "session/update",
  "params": {
    "sessionId": "sess-123",
    "update": {
      "sessionUpdate": "tool_call",
      "toolCallId": "tool-002",
      "status": "in_progress",
      "title": "修复 TypeScript 类型错误",
      "kind": "edit",
      "content": [
        {
          "type": "diff",
          "diff": "--- a/src/index.ts\n+++ b/src/index.ts\n@@ -10,7 +10,7 @@\n-function add(a, b) {\n+function add(a: number, b: number): number {\n   return a + b;\n }"
        }
      ],
      "locations": [{ "path": "/workspace/src/index.ts" }]
    }
  }
}
5.3.4. 计划更新(PlanUpdate)

Agent 的任务执行计划。

json 复制代码
{
  "method": "session/update",
  "params": {
    "sessionId": "sess-123",
    "update": {
      "sessionUpdate": "plan",
      "entries": [
        {
          "content": "分析现有代码结构",
          "status": "completed"
        },
        {
          "content": "识别类型错误位置",
          "status": "in_progress"
        },
        {
          "content": "修复类型定义",
          "status": "pending",
          "priority": "high"
        },
        {
          "content": "运行 TypeScript 编译检查",
          "status": "pending"
        }
      ]
    }
  }
}

5.4 权限请求机制

ACP 的一个重要安全特性是权限请求机制。Agent 在执行敏感操作前必须获得用户许可。

sequenceDiagram participant Agent participant Editor participant User Agent->>Editor: session/request_permission Note right of Agent: {toolCall, options} Editor->>User: 显示对话框 Note right of Editor: 用户选择:
• 仅此一次允许
• 始终允许
• 拒绝 User-->>Editor: 选择权限选项 Editor-->>Agent: permission response Note left of Editor: {optionId: "allow_once"}

权限请求消息格式:

typescript 复制代码
interface AcpPermissionRequest {
  sessionId: string;
  options: Array<{
    optionId: string;
    name: string;
    kind: 'allow_once' | 'allow_always' | 'reject_once' | 'reject_always';
  }>;
  toolCall: {
    toolCallId: string;
    title: string;
    kind: 'read' | 'edit' | 'execute';
    content?: Array<any>;
    locations?: Array<{ path: string }>;
  };
}

示例:请求写入文件权限

json 复制代码
{
  "method": "session/request_permission",
  "params": {
    "sessionId": "sess-123",
    "options": [
      {
        "optionId": "allow_once",
        "name": "仅此一次允许",
        "kind": "allow_once"
      },
      {
        "optionId": "allow_always",
        "name": "始终允许对此文件的写入",
        "kind": "allow_always"
      },
      {
        "optionId": "reject",
        "name": "拒绝",
        "kind": "reject_once"
      }
    ],
    "toolCall": {
      "toolCallId": "tool-003",
      "title": "写入文件 src/config.ts",
      "kind": "edit",
      "locations": [{ "path": "/workspace/src/config.ts" }],
      "content": [
        {
          "type": "diff",
          "diff": "... (修改内容) ..."
        }
      ]
    }
  }
}

AionUi 中的权限 UI 实现:

typescript 复制代码
// src/renderer/messages/acp/MessageAcpPermission.tsx

const MessageAcpPermission: React.FC<Props> = ({ message }) => {
  const handleConfirm = async (optionId: string) => {
    // 调用 IPC Bridge 确认权限
    await ipcBridge.acpConversation.confirmMessage.invoke({
      confirmKey: message.confirmKey,
      msg_id: message.msg_id,
      conversation_id: message.conversation_id,
      callId: message.toolCall.toolCallId,
    });
  };

  return (
    <div className="permission-dialog">
      <h3>{message.toolCall.title}</h3>
      <div className="options">
        {message.options.map(option => (
          <button key={option.optionId} onClick={() => handleConfirm(option.optionId)}>
            {option.name}
          </button>
        ))}
      </div>
    </div>
  );
};

六、ACP 实战:从代码看实现

让我们通过 AionUi 项目的实际代码,深入理解 ACP 的实现细节。

6.1 AcpConnection 类:协议通信层

这是 ACP 客户端的核心实现,负责与 Agent 进程的通信。

完整实现流程:

typescript 复制代码
// src/agent/acp/AcpConnection.ts (605 行)

export class AcpConnection {
  private agentProcess: ChildProcess | null = null;
  private pendingRequests: Map<number, PendingRequest> = new Map();
  private requestIdCounter = 0;

  // 事件回调
  public onSessionUpdate?: (data: AcpSessionUpdate) => void;
  public onPermissionRequest?: (data: AcpPermissionRequest) => Promise<{ optionId: string }>;
  public onEndTurn?: () => void;
  public onFileOperation?: (operation: any) => void;

  /**
   * 连接到 Agent
   */
  async connect(backend: AcpBackend, cliPath?: string, workingDir?: string) {
    const command = cliPath || this.getDefaultCliPath(backend);

    // 启动 Agent 子进程
    this.agentProcess = spawn(command, [], {
      cwd: workingDir,
      env: process.env,
      stdio: ['pipe', 'pipe', 'pipe'], // stdin, stdout, stderr
    });

    // 监听输出
    this.agentProcess.stdout.on('data', this.handleStdout.bind(this));
    this.agentProcess.stderr.on('data', this.handleStderr.bind(this));

    // 初始化协议
    await this.initialize();
  }

  /**
   * 发送 JSON-RPC 请求
   */
  private async sendRequest(method: string, params: any, timeout = 60000): Promise<AcpResponse> {
    const id = ++this.requestIdCounter;

    const request: AcpRequest = {
      jsonrpc: JSONRPC_VERSION,
      id,
      method,
      params,
    };

    // 创建 Promise,等待响应
    return new Promise((resolve, reject) => {
      const timer = setTimeout(() => {
        this.pendingRequests.delete(id);
        reject(new Error(`Request ${method} timeout after ${timeout}ms`));
      }, timeout);

      this.pendingRequests.set(id, { resolve, reject, timer });

      // 写入 Agent 的 stdin
      const message = JSON.stringify(request) + '\n';
      this.agentProcess.stdin.write(message);
    });
  }

  /**
   * 处理 Agent 的输出
   */
  private handleStdout(data: Buffer) {
    const lines = data
      .toString()
      .split('\n')
      .filter((line) => line.trim());

    for (const line of lines) {
      try {
        const message = JSON.parse(line);

        if ('id' in message && 'result' in message) {
          // Response: 匹配请求并 resolve
          const pending = this.pendingRequests.get(message.id);
          if (pending) {
            clearTimeout(pending.timer);
            pending.resolve(message);
            this.pendingRequests.delete(message.id);
          }
        } else if ('method' in message) {
          // Notification: 触发回调
          this.handleNotification(message);
        }
      } catch (error) {
        console.error('Failed to parse message:', line, error);
      }
    }
  }

  /**
   * 处理通知消息
   */
  private handleNotification(notification: AcpNotification) {
    const { method, params } = notification;

    switch (method) {
      case 'session/update':
        if (this.onSessionUpdate) {
          this.onSessionUpdate(params.update);
        }
        break;

      case 'session/request_permission':
        if (this.onPermissionRequest) {
          this.handlePermissionRequest(params);
        }
        break;

      case 'end_turn':
        if (this.onEndTurn) {
          this.onEndTurn();
        }
        break;

      case 'fs/read_text_file':
        this.handleReadOperation(params);
        break;

      case 'fs/write_text_file':
        this.handleWriteOperation(params);
        break;
    }
  }

  /**
   * 创建新会话
   */
  async newSession(cwd: string): Promise<AcpResponse> {
    return await this.sendRequest(
      'session/new',
      {
        cwd,
        mcpServers: [], // 可配置 MCP 服务器
      },
      120000
    ); // 120 秒超时
  }

  /**
   * 发送用户消息
   */
  async sendPrompt(prompt: string): Promise<AcpResponse> {
    return await this.sendRequest(
      'session/prompt',
      {
        prompt,
      },
      120000
    );
  }

  /**
   * 断开连接
   */
  async disconnect() {
    if (this.agentProcess) {
      this.agentProcess.kill();
      this.agentProcess = null;
    }
    this.pendingRequests.clear();
  }
}

6.2 AcpAgent 类:业务逻辑层

typescript 复制代码
// src/agent/acp/index.ts (607 行)

export class AcpAgent {
  private connection: AcpConnection;
  private sessionId: string | null = null;
  private onStreamEvent: (event: any) => void;

  constructor(options: { id: string; backend: AcpBackend; cliPath?: string; workingDir?: string; onStreamEvent: (event: any) => void }) {
    this.onStreamEvent = options.onStreamEvent;

    // 创建连接
    this.connection = new AcpConnection();

    // 注册回调
    this.connection.onSessionUpdate = this.handleSessionUpdate.bind(this);
    this.connection.onPermissionRequest = this.handlePermissionRequest.bind(this);
    this.connection.onEndTurn = this.handleEndTurn.bind(this);
    this.connection.onFileOperation = this.handleFileOperation.bind(this);
  }

  /**
   * 启动 Agent
   */
  async start() {
    await this.connection.connect(this.backend, this.cliPath, this.workingDir);

    // 创建会话
    const response = await this.connection.newSession(this.workingDir);
    this.sessionId = response.result.sessionId;
  }

  /**
   * 发送消息
   */
  async sendMessage(data: { content: string; files?: string[]; msg_id?: string }): Promise<AcpResult> {
    try {
      await this.connection.sendPrompt(data.content);
      return { success: true };
    } catch (error) {
      return { success: false, error: error.message };
    }
  }

  /**
   * 处理会话更新
   */
  private handleSessionUpdate(update: AcpSessionUpdate) {
    // 使用适配器转换为统一格式
    const event = AcpAdapter.convertUpdate(update);

    // 触发流事件
    this.onStreamEvent(event);
  }

  /**
   * 处理权限请求
   */
  private async handlePermissionRequest(params: AcpPermissionRequest): Promise<{ optionId: string }> {
    // 创建权限消息,显示给用户
    const permissionMessage = {
      role: 'permission_request',
      options: params.options,
      toolCall: params.toolCall,
      confirmKey: generateConfirmKey(),
    };

    this.onStreamEvent(permissionMessage);

    // 等待用户响应(通过 confirmMessage 方法)
    return new Promise((resolve) => {
      this.pendingPermissionResolve = resolve;
    });
  }

  /**
   * 确认权限(用户选择后调用)
   */
  async confirmMessage(data: { confirmKey: string; msg_id: string; callId: string }) {
    // 将用户选择的 optionId 返回给 Agent
    if (this.pendingPermissionResolve) {
      this.pendingPermissionResolve({ optionId: data.confirmKey });
      this.pendingPermissionResolve = null;
    }
  }
}

6.3 前端 UI 集成

聊天界面:

typescript 复制代码
// src/renderer/pages/conversation/acp/AcpChat.tsx

const AcpChat: React.FC<{
  conversation_id: string;
  workspace?: string;
  backend: AcpBackend;
}> = ({ conversation_id, workspace, backend }) => {
  return (
    <ConversationProvider value={{
      conversationId: conversation_id,
      workspace,
      type: 'acp',
    }}>
      {/* 消息列表 */}
      <MessageList />

      {/* 输入框 */}
      <AcpSendBox conversation_id={conversation_id} backend={backend} />
    </ConversationProvider>
  );
};

工具调用 UI:

typescript 复制代码
// src/renderer/messages/acp/MessageAcpToolCall.tsx

const MessageAcpToolCall: React.FC<{ toolCall: ToolCallUpdate }> = ({ toolCall }) => {
  return (
    <div className="tool-call">
      {/* 工具图标 */}
      <div className="tool-icon">
        {toolCall.kind === 'read' && <FileIcon />}
        {toolCall.kind === 'edit' && <EditIcon />}
        {toolCall.kind === 'execute' && <TerminalIcon />}
      </div>

      {/* 工具标题 */}
      <div className="tool-title">{toolCall.title}</div>

      {/* 状态指示器 */}
      <div className={`tool-status tool-status-${toolCall.status}`}>
        {toolCall.status === 'pending' && <ClockIcon />}
        {toolCall.status === 'in_progress' && <SpinnerIcon />}
        {toolCall.status === 'completed' && <CheckIcon />}
        {toolCall.status === 'failed' && <XIcon />}
      </div>

      {/* 文件路径 */}
      {toolCall.locations && (
        <div className="tool-locations">
          {toolCall.locations.map(loc => (
            <span key={loc.path}>{loc.path}</span>
          ))}
        </div>
      )}

      {/* Diff 内容 */}
      {toolCall.content && toolCall.content[0]?.type === 'diff' && (
        <DiffViewer diff={toolCall.content[0].diff} />
      )}
    </div>
  );
};

6.4 IPC Bridge 集成

typescript 复制代码
// src/process/bridge/acpConversationBridge.ts

export function initAcpConversationBridge() {
  // 确认权限
  ipcBridge.acpConversation.confirmMessage.provider(async ({ confirmKey, msg_id, conversation_id, callId }) => {
    const task = WorkerManage.getTaskById(conversation_id) as AcpAgentManager;
    await task.confirmMessage({ confirmKey, msg_id, callId });
    return { success: true };
  });

  // 检测可用的 Agent
  ipcBridge.acpConversation.getAvailableAgents.provider(async () => {
    const agents = acpDetector.getDetectedAgents();
    return { success: true, data: agents };
  });

  // 检测 CLI 路径
  ipcBridge.acpConversation.detectCliPath.provider(async ({ backend }) => {
    const agents = acpDetector.getDetectedAgents();
    const agent = agents.find((a) => a.backend === backend);
    return {
      success: !!agent?.cliPath,
      data: { path: agent?.cliPath },
    };
  });
}

七、ACP vs MCP:两个协议的对比与互补

7.1 核心区别

graph TB subgraph ACP["ACP (Agent Client Protocol)"] A1["作用:编辑器 ←→ AI Agent"] A2["场景:代码编辑、重构、调试"] A3["通信:双向(请求/响应 + 通知)"] A4["传输:stdio (本地进程通信)"] A5["创建者:Zed Industries"] end subgraph MCP["MCP (Model Context Protocol)"] M1["作用:AI 模型 ←→ 工具/资源"] M2["场景:数据库查询、API调用、文件系统操作"] M3["通信:主要是单向(模型调用工具)"] M4["传输:stdio / HTTP with SSE"] M5["创建者:Anthropic"] end style ACP fill:#e3f2fd style MCP fill:#fff3e0

7.2 详细对比表

维度 ACP MCP
完整名称 Agent Client Protocol Model Context Protocol
主要用途 编辑器与 AI 编码助手的通信 AI 模型与外部工具/资源的通信
通信方向 双向(编辑器 ↔ Agent) 主要单向(Model → Tools)
协议基础 JSON-RPC 2.0 over stdio JSON-RPC 2.0 over stdio/HTTP
传输方式 stdio(标准输入输出) stdio / HTTP with SSE
生命周期 编辑器启动 Agent 子进程 Host 启动 MCP Server
状态管理 有状态(会话持久化) 有状态(连接生命周期)
权限控制 内置权限请求机制 依赖 Host 实现
典型场景 代码生成、重构、调试 数据库查询、API 调用
作者 Zed Industries Anthropic
发布时间 2025 年 2024 年
开源协议 Apache 2.0 MIT

7.3 协作关系

ACP 和 MCP 不是竞争关系,而是互补关系

graph TD Editor["Editor
(Zed)"] Agent["AI Agent
(Claude Code)"] subgraph MCPServers["MCP Servers"] DB[Database Server] FS[File System] Git[Git Server] Web[Web Fetch] Mem[Memory/Knowledge] end Editor <-->|ACP Protocol| Agent Agent -->|MCP Protocol| MCPServers style Editor fill:#e3f2fd style Agent fill:#fff3e0 style MCPServers fill:#e8f5e9

实际工作流程:

  1. 用户 在 Zed 编辑器中输入:"帮我重构这个函数,并将结果保存到数据库"
  2. Zed 通过 ACP 将消息发送给 Claude Code Agent
  3. Claude 分析代码,生成重构后的代码
  4. Claude 通过 MCP 调用 Database Server 将结果保存
  5. Claude 通过 ACP 将结果返回给 Zed
  6. Zed 在编辑器中显示重构后的代码和执行结果

7.4 在 AionUi 中的集成

AionUi 项目同时支持 ACP 和 MCP:

typescript 复制代码
// src/agent/acp/AcpConnection.ts

async newSession(cwd: string): Promise<AcpResponse> {
  return await this.sendRequest('session/new', {
    cwd,
    // 可以在创建 ACP 会话时配置 MCP 服务器
    mcpServers: [
      {
        name: 'database',
        command: 'node',
        args: ['./mcp-servers/database-server.js'],
      },
      {
        name: 'git',
        command: 'node',
        args: ['./mcp-servers/git-server.js'],
      },
    ],
  });
}

这样,Claude Code Agent 就可以同时:

  • 通过 ACP 与编辑器通信
  • 通过 MCP 访问数据库、Git 等工具

八、生态系统与实际应用

8.1 支持 ACP 的编辑器

mindmap root((ACP 编辑器生态)) 已支持 Zed 官方支持 原生集成 Neovim 社区插件 JetBrains IDEs 官方合作 Marimo 数据科学笔记本 计划中 VS Code Emacs 社区开发中

Zed 的 ACP 配置示例:

json 复制代码
// ~/.config/zed/settings.json
{
  "agents": {
    "claude": {
      "command": "claude-code",
      "args": [],
      "env": {
        "ANTHROPIC_API_KEY": "sk-ant-..."
      }
    },
    "gemini": {
      "command": "gemini-cli",
      "args": ["--model", "gemini-1.5-pro"]
    },
    "codex": {
      "command": "codex",
      "args": ["--api-key", "sk-..."]
    }
  }
}

8.2 支持 ACP 的 AI Agent

Agent 厂商 模型 特性
Claude Code Anthropic Claude 3.5 Sonnet 长上下文、思维链、代码理解强
Gemini CLI Google Gemini 1.5 Pro 多模态、快速响应
Codex CLI OpenAI GPT-4 广泛的编程语言支持
Qwen Code 阿里云 Qwen Coder 中文编程、本地化
goose Block 多模型支持 开源、可定制

8.3 实际应用场景

场景 1:代码重构

用户输入:

"将这个组件从 Class 组件重构为 Function 组件,使用 Hooks"

ACP 工作流程:

sql 复制代码
1. [Agent Message] "我会帮你重构这个组件..."

2. [Tool Call - Read]
   读取 src/components/UserList.tsx

3. [Agent Thought]
   "这是一个 Class 组件,有三个生命周期方法和一个状态..."

4. [Tool Call - Edit]
   生成重构后的代码(使用 useState、useEffect)

5. [Permission Request]
   "是否允许修改 UserList.tsx?"

6. [User] 点击"允许"

7. [Tool Call - Execute]
   运行 `npm run lint` 检查语法

8. [Agent Message]
   "重构完成!代码已通过 lint 检查。"
场景 2:Bug 修复

用户输入:

"修复这个 TypeScript 类型错误"

ACP 工作流程:

css 复制代码
1. [Tool Call - Read]
   读取当前文件

2. [Agent Thought]
   "类型错误是因为函数返回值类型不匹配..."

3. [Plan Update]
   - [✓] 分析类型错误
   - [→] 修改函数签名
   - [ ] 添加类型注解
   - [ ] 运行 tsc 检查

4. [Tool Call - Edit]
   修改函数类型定义

5. [Tool Call - Execute]
   运行 `tsc --noEmit`

6. [Agent Message]
   "类型错误已修复!TypeScript 编译通过。"
场景 3:集成 MCP 的复杂场景

用户输入:

"从数据库中查询用户列表,生成一个 React 表格组件"

ACP + MCP 协作流程:

css 复制代码
1. [ACP] Agent 收到请求

2. [MCP] Agent 调用 Database Server
   Tool: query_users()

3. [MCP] Database Server 返回数据
   Result: [{id: 1, name: "Alice"}, ...]

4. [ACP] Agent 思考如何生成组件

5. [ACP] Agent 创建新文件
   Tool Call: write_file("UserTable.tsx")

6. [ACP] Agent 生成组件代码
   基于数据库结构生成 TypeScript 类型

7. [ACP] Agent 运行测试
   Tool Call: execute("npm test UserTable")

8. [ACP] Agent 返回结果
   "组件已创建,所有测试通过!"

九、最佳实践与安全考量

9.1 实现 ACP Agent 的最佳实践

9.1.1. 日志处理

❌ 错误做法:

typescript 复制代码
// 不要写入 stdout!
console.log('Agent is processing...');

✅ 正确做法:

typescript 复制代码
// 使用 stderr 或文件日志
import fs from 'fs';

const logFile = fs.createWriteStream('/tmp/agent.log');

function log(message: string) {
  logFile.write(`[${new Date().toISOString()}] ${message}\n`);
}

log('Agent is processing...');

原因: ACP 使用 stdout 传输 JSON-RPC 消息,任何非 JSON 输出都会破坏协议。

9.1.2. 错误处理
typescript 复制代码
try {
  await executeToolCall(toolCall);
} catch (error) {
  // 返回标准错误格式
  return {
    jsonrpc: '2.0',
    id: requestId,
    error: {
      code: -32603,
      message: error.message,
      data: {
        stack: error.stack,
      },
    },
  };
}
9.1.3. 超时管理
typescript 复制代码
const TOOL_CALL_TIMEOUT = 30000; // 30 秒

async function executeToolCallWithTimeout(toolCall: ToolCall) {
  return Promise.race([executeToolCall(toolCall), new Promise((_, reject) => setTimeout(() => reject(new Error('Tool call timeout')), TOOL_CALL_TIMEOUT))]);
}
9.1.4. 流式响应

对于长时间的操作,使用流式更新:

typescript 复制代码
async function generateCode(prompt: string) {
  // 发送进度更新
  sendNotification('session/update', {
    update: {
      sessionUpdate: 'agent_thought_chunk',
      content: { type: 'text', text: '正在分析需求...' },
    },
  });

  // 生成代码
  const code = await llm.generate(prompt);

  // 发送代码块
  sendNotification('session/update', {
    update: {
      sessionUpdate: 'agent_message_chunk',
      content: { type: 'text', text: code },
    },
  });
}

9.2 安全考量

9.2.1. 文件系统访问控制
typescript 复制代码
// 定义允许的工作目录
const ALLOWED_WORKSPACE = process.env.WORKSPACE_DIR;

function validateFilePath(path: string): boolean {
  const resolvedPath = path.resolve(path);

  // 检查路径是否在允许的工作目录内
  if (!resolvedPath.startsWith(ALLOWED_WORKSPACE)) {
    throw new Error('Access denied: path outside workspace');
  }

  // 检查是否访问敏感文件
  const sensitivePatterns = ['.env', '.git/config', 'id_rsa'];
  if (sensitivePatterns.some((pattern) => resolvedPath.includes(pattern))) {
    throw new Error('Access denied: sensitive file');
  }

  return true;
}
9.2.2. 命令执行安全
typescript 复制代码
// 白名单机制
const ALLOWED_COMMANDS = ['npm test', 'npm run lint', 'tsc --noEmit', 'git status'];

function validateCommand(command: string): boolean {
  return ALLOWED_COMMANDS.some((allowed) => command.startsWith(allowed));
}

async function executeCommand(command: string) {
  if (!validateCommand(command)) {
    throw new Error('Command not allowed');
  }

  // 执行命令
  return execAsync(command, {
    timeout: 30000,
    cwd: WORKSPACE_DIR,
  });
}
9.2.3. 权限请求实现
typescript 复制代码
async function requestPermission(toolCall: ToolCall): Promise<boolean> {
  // 发送权限请求
  sendNotification('session/request_permission', {
    sessionId: currentSessionId,
    options: [
      { optionId: 'allow_once', name: '仅此一次允许', kind: 'allow_once' },
      { optionId: 'allow_always', name: '始终允许', kind: 'allow_always' },
      { optionId: 'reject', name: '拒绝', kind: 'reject_once' },
    ],
    toolCall,
  });

  // 等待用户响应
  const response = await waitForPermissionResponse();

  // 缓存权限决策
  if (response.kind === 'allow_always') {
    permissionCache.set(toolCall.kind, true);
  } else if (response.kind === 'reject_always') {
    permissionCache.set(toolCall.kind, false);
  }

  return response.kind.startsWith('allow');
}
9.2.4. 敏感信息处理
typescript 复制代码
// 过滤敏感信息
function sanitizeContent(content: string): string {
  // 移除 API 密钥
  content = content.replace(/sk-[a-zA-Z0-9]{48}/g, '***API_KEY***');

  // 移除密码
  content = content.replace(/password\s*=\s*['"][^'"]+['"]/gi, 'password=***');

  // 移除 Token
  content = content.replace(/Bearer\s+[a-zA-Z0-9._-]+/g, 'Bearer ***');

  return content;
}

9.3 性能优化

9.3.1. 批量操作
typescript 复制代码
// 批量读取文件
async function readMultipleFiles(paths: string[]): Promise<Map<string, string>> {
  const results = new Map();

  await Promise.all(
    paths.map(async (path) => {
      const content = await fs.readFile(path, 'utf-8');
      results.set(path, content);
    })
  );

  return results;
}
9.3.2. 增量更新
typescript 复制代码
// 只发送变化的内容
let lastContent = '';

function sendDiffUpdate(newContent: string) {
  const diff = computeDiff(lastContent, newContent);

  if (diff) {
    sendNotification('session/update', {
      update: {
        sessionUpdate: 'agent_message_chunk',
        content: { type: 'diff', diff },
      },
    });
  }

  lastContent = newContent;
}
9.3.3. 缓存机制
typescript 复制代码
// 缓存文件内容
const fileCache = new LRU<string, string>({
  max: 100,
  maxAge: 5 * 60 * 1000, // 5 分钟
});

async function readFileWithCache(path: string): Promise<string> {
  const cached = fileCache.get(path);
  if (cached) return cached;

  const content = await fs.readFile(path, 'utf-8');
  fileCache.set(path, content);

  return content;
}

十、未来展望

10.1 协议演进方向

10.1.1. 更丰富的内容类型
typescript 复制代码
// 未来可能支持的内容类型
interface FutureContent {
  type: 'text' | 'image' | 'video' | 'audio' | 'diagram' | '3d-model';
  // ...
}

// 示例:Agent 生成架构图
{
  sessionUpdate: 'agent_message_chunk',
  content: {
    type: 'diagram',
    format: 'mermaid',
    data: `
      graph TD
        A[Client] -->|HTTP| B[Server]
        B --> C[Database]
    `
  }
}
10.1.2. 多 Agent 协作
graph TD Editor[Editor] CodeAgent[Code Agent
负责代码生成] TestAgent[Test Agent
负责测试] ReviewAgent[Review Agent
负责代码审查] DeployAgent[Deploy Agent
负责部署] Editor --> CodeAgent Editor --> TestAgent Editor --> ReviewAgent Editor --> DeployAgent CodeAgent <-.协作.-> TestAgent TestAgent <-.协作.-> ReviewAgent ReviewAgent <-.协作.-> DeployAgent style Editor fill:#e3f2fd style CodeAgent fill:#fff3e0 style TestAgent fill:#e8f5e9 style ReviewAgent fill:#f3e5f5 style DeployAgent fill:#fce4ec Note["Agent 之间可以互相通信和协作"] style Note fill:#fffde7
10.1.3. 增强的上下文管理
typescript 复制代码
// 未来的会话上下文
interface EnhancedSessionContext {
  // 项目元数据
  project: {
    name: string;
    language: string[];
    framework: string[];
    dependencies: Record<string, string>;
  };

  // 代码图谱
  codeGraph: {
    files: FileNode[];
    imports: ImportEdge[];
    exports: ExportEdge[];
  };

  // 历史操作
  history: Operation[];

  // 用户偏好
  preferences: {
    codingStyle: string;
    testFramework: string;
    // ...
  };
}

10.2 生态系统建设

10.2.1. ACP Agent 市场
mindmap root((ACP Agent 市场)) Agent类型 官方Agent Claude Gemini Codex 社区Agent 开源 定制化 企业Agent 私有部署 定制模型 用户功能 浏览和搜索Agent 查看评分和评论 一键安装和配置 分享自己的Agent
10.2.2. 标准化的 Agent 能力声明
json 复制代码
// agent-manifest.json
{
  "name": "my-custom-agent",
  "version": "1.0.0",
  "description": "A custom coding agent for Rust projects",
  "author": "Your Name",
  "capabilities": {
    "languages": ["rust", "toml"],
    "frameworks": ["tokio", "actix"],
    "tools": {
      "code_generation": true,
      "refactoring": true,
      "testing": true,
      "debugging": false
    }
  },
  "requirements": {
    "model": "gpt-4",
    "apiKey": "required",
    "minEditorVersion": "0.158.0"
  }
}
10.2.3. 跨编辑器同步
typescript 复制代码
// 未来的跨编辑器配置同步
interface AgentConfig {
  agents: {
    [name: string]: {
      command: string;
      args: string[];
      env: Record<string, string>;
      settings: any;
    };
  };
  preferences: {
    defaultAgent: string;
    autoStart: boolean;
    // ...
  };
}

// 同步到云端
await syncConfigToCloud(config);

// 在另一台设备上
const config = await loadConfigFromCloud();

10.3 与其他标准的集成

10.3.1. 与 LSP 的深度集成
graph TD Editor[Editor] subgraph LSP["LSP (提供语言智能)"] L1[自动补全] L2[类型检查] L3[重构建议] end subgraph ACP["ACP (提供 AI 能力)"] A1[理解 LSP 的诊断信息] A2[生成符合项目规范的代码] A3[自动修复 LSP 报告的错误] end Editor --> LSP Editor --> ACP ACP -.读取诊断.-> LSP style Editor fill:#e3f2fd style LSP fill:#fff3e0 style ACP fill:#e8f5e9
10.3.2. 与 Debug Adapter Protocol (DAP) 集成
typescript 复制代码
// Agent 可以理解调试信息
{
  sessionUpdate: 'debug_analysis',
  breakpoint: {
    file: 'src/index.ts',
    line: 42,
    variables: {
      user: { id: 123, name: 'Alice' },
      error: new Error('Invalid token')
    }
  },
  suggestion: "错误是因为 token 已过期,建议添加 token 刷新逻辑"
}

10.4 AI 原生编程范式

ACP 正在推动一种新的编程范式:AI 原生编程(AI-Native Programming)

graph LR subgraph Traditional["传统编程"] T1[人类] --> T2[手写代码] --> T3[编译器] --> T4[可执行程序] end subgraph Current["AI 辅助编程(现在)"] C1[人类] --> C2[AI 生成代码片段] --> C3[人类修改] --> C4[编译器] --> C5[可执行程序] end subgraph Future["AI 原生编程(未来)"] F1[人类描述需求] --> F2[AI Agent 理解] --> F3[AI 设计架构] F3 --> F4[AI 实现] --> F5[AI 测试] --> F6[AI 部署] F6 -.人类审查和指导.-> F1 end style Traditional fill:#ffebee style Current fill:#fff3e0 style Future fill:#e8f5e9

关键特征:

  1. 声明式编程:人类只需描述"要什么",而不是"怎么做"
  2. 持续对话:编程变成与 AI 的持续对话过程
  3. 多层抽象:从需求 → 架构 → 实现 → 优化,每层都有 AI 辅助
  4. 自动化流程:测试、部署、监控都由 AI 自动化

十一、总结

11.1 ACP 的核心价值

标准化:统一的协议规范,消除编辑器与 Agent 的互操作壁垒

开放性:开源协议,任何人都可以实现和扩展

隐私优先:本地通信,不经过第三方服务器

可组合性:与 MCP 等协议协同工作,构建完整的 AI 生态

易用性:基于成熟的 JSON-RPC 2.0,简单高效

11.2 适用场景

  • 代码编辑器开发者:希望集成多个 AI 编码助手
  • AI Agent 开发者:希望让自己的 Agent 被更多编辑器支持
  • 企业开发团队:需要在统一的编辑器环境中使用不同的 AI 工具
  • 开源社区:构建开放、协作的 AI 辅助编程生态

11.3 开始使用 ACP

11.3.1. 作为编辑器开发者
bash 复制代码
# 安装 ACP SDK
npm install @agentclientprotocol/sdk

# 参考 Zed 的实现
git clone https://github.com/zed-industries/zed
11.3.2. 作为 Agent 开发者
bash 复制代码
# 选择你喜欢的语言 SDK
npm install @agentclientprotocol/sdk       # TypeScript
pip install agent-client-protocol          # Python
cargo add agent-client-protocol            # Rust
11.3.3. 作为用户
bash 复制代码
# 下载支持 ACP 的编辑器
# Zed
curl https://zed.dev/install.sh | sh

# 配置你喜欢的 Agent
zed --config agents.claude.command="claude-code"

11.4 学习资源


附录:ACP 与 MCP 协议对比速查表

特性 ACP MCP
完整名称 Agent Client Protocol Model Context Protocol
主要作用 编辑器 ↔ AI Agent AI Model ↔ Tools
协议基础 JSON-RPC 2.0 JSON-RPC 2.0
传输方式 stdio stdio / HTTP+SSE
通信方向 双向 主要单向
生命周期管理 编辑器控制 Host 控制
权限控制 内置机制 依赖 Host
流式响应 支持 支持
作者 Zed Industries Anthropic
开源协议 Apache 2.0 MIT
发布时间 2025 2024
典型场景 代码生成、重构 数据库、API 调用

关于本文

本文结合了:

  • MCP 官方文档和社区实践
  • ACP 官方规范和 Zed 实现
  • AionUi 项目的实际代码
  • 行业最佳实践和未来趋势

希望能帮助你深入理解 ACP 协议,并在实际项目中应用。

作者 :基于掘金文章《MCP 深度解析》、ACP 官方文档、以及 AionUi 开源项目分析,感兴趣可以关注我!

相关阅读

相关推荐
周末程序猿1 小时前
开源项目|不一样的思维导图
人工智能·后端
yaocheng的ai分身1 小时前
可验证性是极限
ai编程
Wgrape1 小时前
一文了解常见AI搜索方案的代码实现
人工智能·后端
Vadaski1 小时前
私有 Context 工程如何落地:从方法论到实战
人工智能·程序员
刘国华-平价IT运维课堂2 小时前
红帽企业Linux 10.1发布:AI命令行助手、量子安全加密和混合云创新
linux·运维·服务器·人工智能·云计算
Xiaok10182 小时前
在 Jupyter Notebook 中启动 TensorBoard
人工智能·python·jupyter
亚马逊云开发者2 小时前
相得益彰:Mem0 记忆框架与亚马逊云科技的企业级 AI 实践
人工智能
AAA修煤气灶刘哥2 小时前
Y-Agent Studio :打破 DAG 的“无环”铁律?揭秘有向有环图如何让智能体真正“活”起来
人工智能·低代码·agent
WWZZ20252 小时前
快速上手大模型:深度学习9(池化层、卷积神经网络1)
人工智能·深度学习·神经网络·算法·机器人·大模型·具身智能