OpenCode LLM 层
核心文件
text
packages/llm/src/
├── llm.ts # LLM.request/stream/client
├── route/
│ ├── protocol.ts # API 协议定义
│ ├── endpoint.ts # Endpoint 构造
│ ├── auth.ts # 认证
│ └── framing.ts # 字节流解帧
└── providers/ # Provider 实现Route Decomposition
OpenCode 最精巧的设计是 LLM Route 的四层分解:
typescript
interface Route<Protocol, Endpoint, Auth, Framing> {
protocol: Protocol; // e.g. OpenAIChatProtocol
endpoint: Endpoint; // e.g. URL builder
auth: Auth; // e.g. Bearer token
framing: Framing; // e.g. SSE parsing
}四层含义
| 层 | 作用 | 示例 |
|---|---|---|
| Protocol | 定义 API 语义 | OpenAI Chat、Anthropic Messages |
| Endpoint | 构造请求 URL | baseURL + /chat/completions |
| Auth | 每个请求认证 | Bearer sk-xxx、x-api-key |
| Framing | 字节流 → 帧 | SSE、AWS Event Stream |
为什么这很妙?
为 DeepSeek 添加支持只需:
typescript
const DeepSeekRoute = Route.make(
OpenAIChatProtocol, // 和 OpenAI 一样的协议
Endpoint.make("https://api.deepseek.com/v1"), // 只换 URL
Auth.bearer("sk-xxx"), // 自己的 key
Framing.sse(), // 相同的 SSE 解帧
);5 行代码。而 Hermes 要写完整的 adapter 类,Pi 要写整个 provider 文件。
统一 LLM Client
LLM.request()
↓
Route → Protocol.toRequest()
↓
fetch() with Auth
↓
Framing.parse() → stream of frames
↓
Protocol.fromResponse() → Message[]对比
| 维度 | OpenCode | Hermes | Pi |
|---|---|---|---|
| 抽象方式 | Route decomposition | OpenAI SDK + transport | AI interface |
| 新增 Provider | 5-15 行 | transport 类 + adapter | provider 文件 |
| 复杂度 | 高(4 层抽象) | 中(2 层) | 低(1 层) |
| 扩展性 | 极好 | 好 | 一般 |
| 最佳适用 | 需要接大量 provider | 以 OpenAI 为主 | 以主流 provider 为主 |