前言

AI Agent 正在成为软件架构的重要组件。但如何让 Agent 能够被远程访问,是一个容易被低估的技术决策。

不同的协议选择,会直接影响:

  • 用户体验:延迟、流畅度
  • 开发成本:实现难度、调试复杂度
  • 运维成本:资源占用、可扩展性
  • 应用场景:能做什么、不能做什么

本文从技术角度深度分析几种主流协议,帮助你做出最佳选择。


协议全景图

┌─────────────┬──────────────┬──────────────┬─────────────┐
│   协议      │  连接类型    │  通信模式    │  适用场景    │
├─────────────┼──────────────┼──────────────┼─────────────┤
│ HTTP/REST   │ 短连接       │ 请求-响应    │ API 服务    │
│ WebSocket   │ 长连接       │ 全双工       │ 实时交互    │
│ SSE         │ 长连接       │ 单向推送     │ 流式输出    │
│ gRPC        │ 长连接       │ 全双工       │ 内部服务    │
│ SSH         │ 长连接       │ 终端交互     │ CLI 工具    │
└─────────────┴──────────────┴──────────────┴─────────────┘

一、HTTP/HTTPS + RESTful API

1.1 工作原理

最传统的方式。客户端发送 HTTP 请求,服务器返回 Agent 的响应。

客户端                服务器
  │                     │
  │─── POST /agent ────>│
  │                     │ AI 处理
  │<── 200 OK + body ───│
  │                     │

1.2 优点

简单性

  • 无需额外库,curl 就能测试
  • 开发者熟悉度高
  • 调试工具丰富(Postman、Insomnia)

通用性

  • 跨平台、跨语言
  • 防火墙友好
  • 移动端支持完善

生态完善

  • 认证:OAuth2、JWT、API Key
  • 加密:HTTPS
  • 限流:标准中间件

1.3 缺点

无状态

每次请求独立,Agent 需要自己管理会话状态。常见做法:

POST /agent/chat
{
  "session_id": "abc123",
  "message": "你好"
}

不支持流式输出

AI 生成内容需要时间。如果 Agent 要生成 1000 字,用户要等所有内容生成完才能看到第一个字。

解决方案:

  • 轮询:定期查询状态(效率低)
  • 回调:Agent 完成后主动通知(复杂)

1.4 代码示例

服务端(Node.js + Express)

const express = require('express');
const app = express();

app.post('/agent/chat', async (req, res) => {
  const { message, session_id } = req.body;
  
  // 调用 AI Agent
  const response = await agent.process(session_id, message);
  
  res.json({
    success: true,
    response: response
  });
});

app.listen(3000);

客户端(Python)

import requests

def chat(message, session_id):
    response = requests.post(
        'https://api.example.com/agent/chat',
        json={
            'message': message,
            'session_id': session_id
        }
    )
    return response.json()['response']

# 使用
answer = chat("帮我写一段代码", "session-123")
print(answer)

1.5 适用场景

  • API 服务:提供给第三方调用
  • 简单问答:一次请求,一次响应
  • 批量处理:异步任务提交

二、WebSocket

2.1 工作原理

WebSocket 建立全双工通信通道,客户端和服务器可以随时互相发送消息。

客户端                    服务器
  │                         │
  │─── WebSocket 握手 ─────>│
  │<── 101 Switching ───────│
  │                         │
  │═════ 连接建立 ═══════════│
  │                         │
  │─── "你好" ─────────────>│
  │                         │ AI 处理
  │<── "你好!有什么可以..." │
  │                         │
  │─── "帮我写代码" ────────>│
  │<── "正在生成..." ───────│
  │<── "```python..." ──────│
  │<── "def hello..." ──────│
  │<── [DONE] ──────────────│

2.2 优点

全双工通信

双向实时通信,不需要轮询。

流式输出

AI 生成的内容可以逐字推送,用户体验流畅。

低延迟

连接保持,省去重复建立连接的开销。

2.3 缺点

实现复杂

需要处理:

  • 连接管理(断线重连)
  • 心跳检测
  • 消息序列化

调试困难

不能像 HTTP 一样用 curl 测试,需要专门工具(如 wscat)。

2.4 代码示例

服务端(Node.js + ws)

const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', (ws, req) => {
  const sessionId = generateSessionId();
  
  ws.on('message', async (message) => {
    const data = JSON.parse(message);
    
    // 流式生成
    for await (const chunk of agent.stream(sessionId, data.content)) {
      ws.send(JSON.stringify({
        type: 'chunk',
        content: chunk
      }));
    }
    
    ws.send(JSON.stringify({
      type: 'done'
    }));
  });
  
  ws.on('close', () => {
    agent.cleanup(sessionId);
  });
});

客户端(JavaScript)

const ws = new WebSocket('wss://api.example.com/agent');

ws.onopen = () => {
  ws.send(JSON.stringify({
    content: '帮我写一段代码'
  }));
};

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  
  if (data.type === 'chunk') {
    // 逐字显示
    document.getElementById('output').textContent += data.content;
  } else if (data.type === 'done') {
    console.log('生成完成');
  }
};

ws.onerror = (error) => {
  console.error('WebSocket error:', error);
};

2.5 适用场景

  • Web 聊天界面:类似 ChatGPT
  • 实时协作:多人同时与 Agent 交互
  • 长对话:需要保持上下文

三、SSE (Server-Sent Events)

3.1 工作原理

SSE 基于 HTTP,服务器可以向客户端单向推送消息。

客户端                    服务器
  │                         │
  │─── GET /stream ────────>│
  │<── 200 OK ──────────────│
  │   Content-Type: text/event-stream
  │                         │
  │<── data: 你好\n\n ──────│
  │<── data: !\n\n ────────│
  │<── data: 有什么\n\n ────│
  │<── data: [DONE]\n\n ────│

3.2 优点

简单

基于 HTTP,不需要特殊协议。

自动重连

浏览器原生支持断线重连。

流式输出

适合 AI 生成内容的逐字推送。

3.3 缺点

单向通信

只能服务器→客户端。如果需要双向,需要配合 HTTP 请求。

不支持二进制

只能传输文本(UTF-8)。

3.4 代码示例

服务端(Node.js + Express)

app.get('/agent/stream', async (req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');
  
  const { message, session_id } = req.query;
  
  // 流式生成
  for await (const chunk of agent.stream(session_id, message)) {
    res.write(`data: ${JSON.stringify({ content: chunk })}\n\n`);
  }
  
  res.write('data: [DONE]\n\n');
  res.end();
});

客户端(JavaScript)

const eventSource = new EventSource(
  '/agent/stream?message=你好&session_id=abc'
);

eventSource.onmessage = (event) => {
  if (event.data === '[DONE]') {
    eventSource.close();
    return;
  }
  
  const data = JSON.parse(event.data);
  document.getElementById('output').textContent += data.content;
};

eventSource.onerror = (error) => {
  console.error('SSE error:', error);
  eventSource.close();
};

3.5 适用场景

  • AI 流式输出:类似 OpenAI 的流式 API
  • 日志实时推送:Agent 执行日志
  • 状态更新:任务进度通知

四、gRPC

4.1 工作原理

gRPC 基于 HTTP/2,使用 Protocol Buffers 序列化,支持双向流。

syntax = "proto3";

service AgentService {
  rpc Chat (stream ChatRequest) returns (stream ChatResponse);
}

message ChatRequest {
  string session_id = 1;
  string message = 2;
}

message ChatResponse {
  string content = 1;
  bool done = 2;
}

4.2 优点

高性能

  • HTTP/2 多路复用
  • 二进制序列化
  • 强类型

双向流

客户端和服务器都可以流式发送。

代码生成

.proto 文件自动生成多语言代码。

4.3 缺点

浏览器支持差

需要 gRPC-Web 代理,不能直接在浏览器中使用。

学习曲线陡

需要学习 Protocol Buffers、gRPC 概念。

调试困难

不能直接用 curl 测试。

4.4 代码示例

服务端(Node.js)

const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');

const packageDefinition = protoLoader.loadSync('agent.proto');
const agentProto = grpc.loadPackageDefinition(packageDefinition);

const server = new grpc.Server();

server.addService(agentProto.AgentService.service, {
  Chat: (call) => {
    call.on('data', async (request) => {
      // 流式生成
      for await (const chunk of agent.stream(request.session_id, request.message)) {
        call.write({ content: chunk, done: false });
      }
      call.write({ content: '', done: true });
      call.end();
    });
  }
});

server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure());

客户端(Python)

import grpc
import agent_pb2
import agent_pb2_grpc

channel = grpc.insecure_channel('localhost:50051')
stub = agent_pb2_grpc.AgentServiceStub(channel)

def generate_requests():
    yield agent_pb2.ChatRequest(
        session_id='session-123',
        message='你好'
    )

responses = stub.Chat(generate_requests())
for response in responses:
    print(response.content, end='', flush=True)
    if response.done:
        break

4.5 适用场景

  • 内部服务调用:微服务架构
  • 高性能场景:低延迟要求
  • 跨语言系统:多语言协作

五、SSH + TTY

5.1 工作原理

通过 SSH 连接到服务器,运行 Agent CLI 程序,通过终端交互。

客户端                    服务器
  │                         │
  │─── SSH 连接 ───────────>│
  │<── Shell 提示符 ────────│
  │                         │
  │─── "你好" + Enter ──────>│
  │                         │ Agent CLI 处理
  │<── "你好!有什么..." ────│
  │                         │

5.2 优点

零开发

如果 Agent 已经是 CLI 程序,无需任何开发。

加密传输

SSH 协议自带加密。

终端体验

适合开发者,可以直接在终端操作。

5.3 缺点

仅限命令行

不适合图形界面。

权限管理复杂

需要管理 SSH 密钥、用户权限。

5.4 示例

Agent CLI(Python)

import readline

def main():
    print("Agent CLI v1.0")
    print("输入 'exit' 退出")
    
    while True:
        try:
            user_input = input("You: ")
            
            if user_input.lower() == 'exit':
                break
            
            response = agent.process(user_input)
            print(f"Agent: {response}")
            
        except KeyboardInterrupt:
            print("\n再见!")
            break

if __name__ == '__main__':
    main()

使用方式

# 本地运行
python agent_cli.py

# 远程访问
ssh user@server "python agent_cli.py"

# 或者 SSH 后手动运行
ssh user@server
python agent_cli.py

5.5 适用场景

  • 开发者工具:CLI Agent
  • 运维场景:服务器上的 Agent
  • 快速原型:无需 Web 开发

六、协议对比矩阵

维度HTTP/RESTWebSocketSSEgRPCSSH
实现难度⭐⭐⭐⭐⭐⭐⭐⭐⭐
流式输出
双向通信
浏览器支持⚠️
性能⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
调试难度⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
跨平台⚠️

七、选型决策树

开始
  ├─ 需要浏览器访问?
  │   ├─ 是
  │   │   ├─ 需要流式输出?
  │   │   │   ├─ 是
  │   │   │   │   ├─ 需要双向通信?
  │   │   │   │   │   ├─ 是 → WebSocket
  │   │   │   │   │   └─ 否 → SSE
  │   │   │   └─ 否 → HTTP/REST
  │   └─ 否(内部服务)
  │       ├─ 性能要求高?
  │       │   ├─ 是 → gRPC
  │       │   └─ 否 → HTTP/REST
  │       └─ 是 CLI 工具? → SSH

八、安全考虑

无论选择哪种协议,安全都是重中之重。

9.1 认证

协议推荐认证方式
HTTP/RESTAPI Key / JWT / OAuth2
WebSocketJWT(在握手时传递)
SSEToken(在 URL 参数或 Header)
gRPCMetadata(类似 HTTP Header)
SSHSSH 密钥

9.2 加密

  • HTTP/REST、WebSocket、SSE:强制 HTTPS(WSS)
  • gRPC:使用 TLS
  • SSH:自带加密

9.3 限流

防止 Agent 被滥用:

// 示例:基于 IP 的限流
const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 分钟
  max: 100 // 最多 100 次请求
});

app.use('/agent/', limiter);

九、性能优化建议

10.1 HTTP/REST

  • 使用 Keep-Alive 复用连接
  • 启用 Gzip 压缩
  • 合理设置超时时间

10.2 WebSocket

  • 实现心跳检测
  • 消息压缩(如 permessage-deflate)
  • 连接池管理

10.3 SSE

  • 设置合理的 retry 时间
  • 使用 Last-Event-ID 支持断点续传

10.4 gRPC

  • 启用流控(Flow Control)
  • 调整消息大小限制
  • 使用连接池

十、总结

选择远程访问 AI Agent 的协议,没有银弹。关键是要根据实际需求权衡:

需求推荐方案
Web 聊天界面WebSocket
API 服务HTTPS + REST
流式输出优先SSE 或 WebSocket
内部微服务gRPC
CLI 工具SSH
快速原型HTTP/REST

最重要的原则

  1. 从简单开始:能用 HTTP 解决的,不要上 WebSocket
  2. 用户体验优先:如果流式输出能显著提升体验,就支持它
  3. 考虑扩展性:选择成熟的、生态完善的协议
  4. 安全性第一:认证、加密、限流,一个都不能少

参考资料


本文写于2026年2月26日。