1
0
Files
nex/openspec/specs/anthropic-protocol-proxy/spec.md
lanyuanxiaoyao 915b004924 feat: 初始化 AI Gateway 项目
实现支持 OpenAI 和 Anthropic 双协议的统一大模型 API 网关 MVP 版本,包含:
- OpenAI 和 Anthropic 协议代理
- 供应商和模型管理
- 用量统计
- 前端配置界面
2026-04-15 16:53:28 +08:00

6.7 KiB
Raw Blame History

Anthropic 协议代理

Purpose

TBD - 提供 Anthropic Messages API 的代理功能,通过协议转换实现与 OpenAI 兼容供应商的互操作

Requirements

Requirement: 支持 Anthropic Messages API 端点

网关 SHALL 提供 Anthropic Messages API 端点 POST /v1/messages 供外部应用调用。

Scenario: 成功的非流式请求

  • WHEN 应用发送 POST 请求到 /v1/messages,携带有效的 Anthropic 请求格式(非流式)
  • THEN 网关 SHALL 将 Anthropic 请求转换为 OpenAI 格式
  • THEN 网关 SHALL 将转换后的请求转发到配置的供应商
  • THEN 网关 SHALL 将 OpenAI 响应转换回 Anthropic 格式
  • THEN 网关 SHALL 将转换后的响应返回给应用

Scenario: 成功的流式请求

  • WHEN 应用发送 POST 请求到 /v1/messages,携带 stream: true
  • THEN 网关 SHALL 将 Anthropic 请求转换为 OpenAI 格式
  • THEN 网关 SHALL 将转换后的请求转发给供应商
  • THEN 网关 SHALL 将 OpenAI 流事件转换为 Anthropic 流事件
  • THEN 网关 SHALL 使用 SSE 格式将转换后的事件流式返回给应用

Requirement: 将 Anthropic 请求转换为 OpenAI 格式

网关 SHALL 将 Anthropic Messages API 请求转换为 OpenAI Chat Completions API 格式。

Scenario: System 消息转换

  • WHEN Anthropic 请求包含 system 字段
  • THEN 网关 SHALL 将其转换为 messages 数组中 role: "system" 的消息

Scenario: Messages 转换

  • WHEN Anthropic 请求包含 messages 数组
  • THEN 网关 SHALL 在转换后的 OpenAI 请求中保留这些消息
  • THEN 网关 SHALL 保留每条消息的 role 和 content

Scenario: Tools 转换

  • WHEN Anthropic 请求包含带有 input_schematools
  • THEN 网关 SHALL 将每个工具转换为 OpenAI 格式,使用 function.parameters 替代 input_schema
  • THEN 网关 SHALL 保留工具名称和描述

Scenario: Tool choice 转换

  • WHEN Anthropic 请求包含 type: "auto"tool_choice
  • THEN 网关 SHALL 将其转换为 OpenAI 格式的 "auto"
  • WHEN Anthropic 请求包含 type: "any"tool_choice
  • THEN 网关 SHALL 将其转换为 OpenAI 格式的 "auto"
  • WHEN Anthropic 请求包含 type: "tool"nametool_choice
  • THEN 网关 SHALL 将其转换为 OpenAI 格式的 {"type": "function", "function": {"name": <name>}}

Scenario: Tool result 转换

  • WHEN Anthropic 请求包含用户消息,其 content 数组包含 type: "tool_result"
  • THEN 网关 SHALL 将每个工具结果转换为 role: "tool" 的消息
  • THEN 网关 SHALL 从 tool_use_id 设置 tool_call_id
  • THEN 网关 SHALL 保留 content

Scenario: Max tokens 处理

  • WHEN Anthropic 请求包含 max_tokens
  • THEN 网关 SHALL 在 OpenAI 请求中包含它作为 max_tokens
  • WHEN Anthropic 请求不包含 max_tokens
  • THEN 网关 SHALL 设置默认值4096以满足 Anthropic 的要求

Requirement: 将 OpenAI 响应转换为 Anthropic 格式

网关 SHALL 将 OpenAI Chat Completions API 响应转换为 Anthropic Messages API 格式。

Scenario: Content 转换

  • WHEN OpenAI 响应包含 choices[0].message.content
  • THEN 网关 SHALL 将其转换为 Anthropic 格式的 content: [{"type": "text", "text": <content>}]

Scenario: Tool calls 转换

  • WHEN OpenAI 响应包含 choices[0].message.tool_calls
  • THEN 网关 SHALL 将每个工具调用转换为 type: "tool_use" 的内容块
  • THEN 网关 SHALL 从 tool_calls[].id 设置 id
  • THEN 网关 SHALL 从 tool_calls[].function.name 设置 name
  • THEN 网关 SHALL 解析 arguments JSON 字符串并将其设置为 input 对象

Scenario: Finish reason 转换

  • WHEN OpenAI 响应的 finish_reason"stop"
  • THEN 网关 SHALL 在 Anthropic 响应中设置 stop_reason: "end_turn"
  • WHEN OpenAI 响应的 finish_reason"tool_calls"
  • THEN 网关 SHALL 在 Anthropic 响应中设置 stop_reason: "tool_use"

Scenario: Usage 转换

  • WHEN OpenAI 响应包含带有 prompt_tokenscompletion_tokensusage
  • THEN 网关 SHALL 转换为 Anthropic 格式,使用 input_tokensoutput_tokens

Requirement: 转换流式事件

网关 SHALL 实时将 OpenAI 流事件转换为 Anthropic 流事件。

Scenario: Message start 事件

  • WHEN 网关开始流式传输 Anthropic 响应
  • THEN 网关 SHALL 发送带有消息元数据的 message_start 事件

Scenario: Content block start 事件

  • WHEN OpenAI 流开始返回内容
  • THEN 网关 SHALL 发送带有 type: "text"content_block_start 事件

Scenario: Content delta 事件

  • WHEN OpenAI 流发送带有内容的 delta
  • THEN 网关 SHALL 发送带有 type: "text_delta"content_block_delta 事件,包含文本

Scenario: Tool use 流式传输

  • WHEN OpenAI 流发送工具调用 delta
  • THEN 网关 SHALL 缓冲 arguments
  • THEN 网关 SHALL 在工具调用开始时发送带有 type: "tool_use"content_block_start
  • THEN 网关 SHALL 发送带有部分 JSON 的 input_delta 事件

Scenario: Content block stop 事件

  • WHEN 内容块完成
  • THEN 网关 SHALL 发送 content_block_stop 事件

Scenario: Message stop 事件

  • WHEN OpenAI 流完成
  • THEN 网关 SHALL 发送 message_stop 事件

Requirement: 支持 Anthropic 特有功能

网关 SHALL 支持映射到 OpenAI 能力的 Anthropic 特有功能。

Scenario: System prompt 作为独立字段

  • WHEN Anthropic 请求包含 system 字段
  • THEN 网关 SHALL 将其作为 OpenAI 格式的 system 消息处理

Scenario: 必需的 max_tokens

  • WHEN 收到 Anthropic 请求
  • THEN 网关 SHALL 确保 max_tokens 存在(如果未提供则使用默认值)

Requirement: 处理纯文本内容

网关 SHALL 在 Anthropic 请求和响应中支持纯文本内容。

Scenario: 消息中的文本内容

  • WHEN Anthropic 请求在消息中包含文本内容
  • THEN 网关 SHALL 正确处理和转发文本内容

Scenario: 拒绝多模态内容

  • WHEN Anthropic 请求包含多模态内容(图片、文档)
  • THEN 网关 SHALL 返回错误,指示 MVP 不支持多模态内容

Requirement: 保留请求元数据

网关 SHALL 在转换过程中保留请求元数据。

Scenario: 模型名称保留

  • WHEN Anthropic 请求指定模型名称
  • THEN 网关 SHALL 在转换后的 OpenAI 请求中保留模型名称

Scenario: 自定义参数

  • WHEN Anthropic 请求包含自定义参数temperature, top_p 等)
  • THEN 网关 SHALL 在转换后的请求中保留这些参数