AI Gateway 的对接开发中,一个重要的内容就是对接不同厂商推理服务的接口协议。目前,推理服务的接口协议主要分为以下几种类型:

  • 文本对话接口,如 OpenAI 的 chat completions 和 response API 等
  • 向量接口,向量接口用于将输入的文本或者图片、视频(多模态)等转换成向量表示,适用于搜索(文搜图、图搜图、图文混合搜索)、聚类、推荐等场景。

文本对话#

文本对话 API 需要提供如下能力支持:

  1. 模型选择
  2. 用户、系统、模型输入内容角色区分
  3. 模型参数调整
  4. 工具调用
  5. MCP 支持
  6. 用量统计

目前使用最广泛的文本对话接口自然是 OpenAI 的 chat completions API。几乎所有的 LLM 服务提供商都支持 chat completions compatible 调用。

https://platform.openai.com/docs/api-reference/introduction

chat completions#

基本调用:

curl https://api.openai.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "gpt-5",
    "messages": [
      {
        "role": "developer",
        "content": "You are a helpful assistant."
      },
      {
        "role": "user",
        "content": "Hello!"
      }
    ]
  }'
  • model: 请求调用的模型
  • messages:构成对话的消息体。根据消息的来源角色,message 可以分为 developer/system(开发者,系统提供的 prompt),user(用户自身的输入)和 assistant(模型的响应,用于多轮对话时模型的上下文传递)。
    • content 分为两种类型,纯文本即为 string,非纯文本 content 为列表类型,内容根据 type(text,image_url,input_audio 等)有不同的字段
  • stream:采用正常 HTTP 响应还是 sse 响应
  • stream_options: 在 sse 响应时,有些模型默认不会输出 usage 信息,需要显式将 stream_options.include_usage 设置成 true
  • temperature:模型温度,取值范围 0 - 2,值越高,输出的 tokens 随机性越大
  • top_p:和 tempreature 一样对模型输出进行调整的参数,模型会考虑概率质量最高的top_p个tokens的结果。所以0.1意味着只考虑概率质量最高的10%的tokens。
  • reasoning_effort:模型的推理深度,比如对于 OpenAI 模型来说有 minimal,low,medium,high 等多种选择。
  • max_completion_tokens:最大输出 tokens 数,包括 output tokens 和 reasoning tokens。替代原来的 max_tokens 字段。
  • tools:告知大模型本地可调用的工具列表。工具里面定义了工具的名称、描述和 json schema 表示的参数描述。替代原来的 functions 字段。
  • tool_choice:告知模型对于工具的调用选择。none 表示不要调用任何工具直接生成 messages,auto 表示由模型自己决定是否调用 allowed_tools。required 表示模型必须调用至少一个工具。

除此之外,各家可以在 OpenAI 标准的 API 上扩展自己的字段,比如 cherry studio 会使用 thinking 字段来开启/关闭模型思考:

{  
    "model": "glm-4.5-flash",  
    "temperature": 1,  
    "thinking": {  
        "type": "enabled"  
    },  
    "messages": [{  
        "role": "user",  
        "content": "openresty 的 lua http 和 nginx 原生的 转发性能相比怎么样"  
    }],  
    "stream": true,  
    "stream_options": {  
        "include_usage": true  
    }  
}

模型响应示例:

{
  "id": "chatcmpl-B9MBs8CjcvOU2jLn4n570S5qMJKcT",
  "object": "chat.completion",
  "created": 1741569952,
  "model": "gpt-4.1-2025-04-14",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Hello! How can I assist you today?",
        "refusal": null,
        "annotations": []
      },
      "logprobs": null,
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 19,
    "completion_tokens": 10,
    "total_tokens": 29,
    "prompt_tokens_details": {
      "cached_tokens": 0,
      "audio_tokens": 0
    },
    "completion_tokens_details": {
      "reasoning_tokens": 0,
      "audio_tokens": 0,
      "accepted_prediction_tokens": 0,
      "rejected_prediction_tokens": 0
    }
  },
  "service_tier": "default"
}
  • choices:模型提供的多个候选响应,常见在图片生成时提供给用户多个选择。
  • usage:用量统计
    • prompt tokens:提示词(输入)tokens
    • completion_tokens:输出 tokens
    • total_tokens:总消耗 tokens
  • message.tool_calls:模型生成的工具调用列表,包括工具名称和参数

Responses#

Responses API 是 OpenAI 用来替代 chat completions 的文本对话 API。

根据官方文档,Responses API 对比 chat completions 有如下优势:

  • 更好的性能:与 Chat Completions 相比,将推理模型(如 GPT-5)与 Responses 结合使用将带来更好的模型智能。我们的内部评估显示,在相同的提示和设置下,SWE-bench 性能提高了 3%。
  • 默认代理:Responses API 是一个代理循环,允许模型在一个 API 请求的范围内调用多个工具,例如 web_search、image_generation、file_search、code_interpreter、远程 MCP 服务器以及您自己的自定义函数。
  • 更低的成本:由于改进的缓存利用率(在内部测试中,与 Chat Completions 相比,提高了 40% 到 80%),从而降低了成本。
  • 有状态的上下文:使用 store: true 来保持轮次之间的状态,从而保留轮次之间的推理和工具上下文。
  • 灵活的输入:传递带有输入的字符串或消息列表;使用指令进行系统级指导。
  • 加密推理:选择退出有状态,同时仍然受益于高级推理。
  • 面向未来:面向即将推出的模型。

81e15626b9678c199374227859b9d4ef_MD5

总的来说,Responses API 做了如下一些提升:

  1. 提供了一些内置的 tool 如 web-search,file-search,computer-use,code-interpreter 等,使用者可以不用再自己封装 functions
  2. API 的输入输出更加结构化和精炼,取消了 choice,只提供一个输出
  3. 多轮对话场景下请求和响应结构进行了优化

唯一的缺点就是 chat completions 已经被绝大部分模型兼容使用。。。

请求示例:

curl https://api.openai.com/v1/responses \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "o3-mini",
    "input": "How much wood would a woodchuck chuck?",
    "reasoning": {
      "effort": "high"
    }
  }'
  • input:替代原先的 message 参数,用户输入,取消了 role 参数,用户和 system/developer 用不同的参数分开
  • instructions:替代原先的 message 参数,system/developer role
  • max_output_tokens:= max_completions_tokens
  • reasoning:effort = reasoning_effort
  • tools:支持 built-in tools(如 web-search,file-search)mcp,function calls

响应示例:

{
  "id": "resp_67ccd7eca01881908ff0b5146584e408072912b2993db808",
  "object": "response",
  "created_at": 1741477868,
  "status": "completed",
  "error": null,
  "incomplete_details": null,
  "instructions": null,
  "max_output_tokens": null,
  "model": "o1-2024-12-17",
  "output": [
    {
      "type": "message",
      "id": "msg_67ccd7f7b5848190a6f3e95d809f6b44072912b2993db808",
      "status": "completed",
      "role": "assistant",
      "content": [
        {
          "type": "output_text",
          "text": "The classic tongue twister...",
          "annotations": []
        }
      ]
    }
  ],
  "parallel_tool_calls": true,
  "previous_response_id": null,
  "reasoning": {
    "effort": "high",
    "summary": null
  },
  "store": true,
  "temperature": 1.0,
  "text": {
    "format": {
      "type": "text"
    }
  },
  "tool_choice": "auto",
  "tools": [],
  "top_p": 1.0,
  "truncation": "disabled",
  "usage": {
    "input_tokens": 81,
    "input_tokens_details": {
      "cached_tokens": 0
    },
    "output_tokens": 1035,
    "output_tokens_details": {
      "reasoning_tokens": 832
    },
    "total_tokens": 1116
  },
  "user": null,
  "metadata": {}
}
  • output:替代 choice[0].message
  • usage
    • input_tokens: = prompt_tokens
    • ouput_tokens = completion_tokens

Google Gemini#

https://ai.google.dev/api

请求示例:

curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H 'Content-Type: application/json' \
  -X POST \
  -d '{
    "system_instruction": {
      "parts": [
        {
          "text": "You are a cat. Your name is Neko."
        }
      ]
    },
    "contents": [
      {
        "parts": [
          {
            "text": "How does AI work?"
          }
        ]
      }
    ],
    "generationConfig": {
      "thinkingConfig": {
	    "includeThought": true,
        "thinkingBudget": 10000
      }
    }
  }'
  • contents:用于存放 prompt,role 为 user(用户输入)和 model(模型输入)
  • system_instruction:系统提示词
  • generationConfig:模型配置
    • thinkingConfig:includeThought 是否在响应中包含模型思考过程,thinkingBudget 为思考深度(tokens 计量)
  • tools:定义工具调用的名称/参数 schema
  • mcp:目前 gemini 仅在 python 和 js sdk 中支持 mcp

另外 Gemini api models 选择是在 path 中就指定的,而 sse 开启则是在 query 参数中指定 alt=sse

响应示例:

{  
    "candidates": [{  
        "content": {  
            "parts": [{  
                "text": "APISIX 与 Kong 的对比分析\n"  
            }],  
            "role": "model"  
        },  
        "finishReason": "STOP",  
        "avgLogprobs": -0.36287453770637512  
    }],  
    "usageMetadata": {  
        "promptTokenCount": 1760,  
        "candidatesTokenCount": 8,  
        "totalTokenCount": 1768,  
        "promptTokensDetails": [{  
            "modality": "TEXT",  
            "tokenCount": 1760  
        }],  
        "candidatesTokensDetails": [{  
            "modality": "TEXT",  
            "tokenCount": 8  
        }]  
    },  
    "modelVersion": "gemini-2.0-flash-lite",  
    "responseId": "4GcYaYbIDbrUz7IP8qWW2QU"  
}
  • candidates:= choices
  • usageMetadata:用量统计
    • promptTokenCount:= input tokens
    • candidatesTokenCount:= ouput tokens

Claude Code#

https://docs.claude.com/en/api/overview

请求示例:

curl https://api.anthropic.com/v1/messages \
     --header "x-api-key: $ANTHROPIC_API_KEY" \
     --header "anthropic-version: 2023-06-01" \
     --header "content-type: application/json" \
     --data \
'{
    "model": "claude-sonnet-4-5-20250929",
    "max_tokens": 1024,
	"thinking": { "type": "enabled", "budget_tokens": 10000 },
    "messages": [
        {"role": "user", "content": "Hello, world"}
    ]
}'
  • messages:role 只有 user 和 assistant
  • system:等效于 chat completions 中 message 中的 system,不过 Claude Code 将其放在 top level
  • thinking:开启/关闭模型思考,budget_tokens 限制最大 thinking tokens
  • mcp_servers:mcp servers 配置
  • tools:定义工具调用的名称/参数

响应示例:

{
  "content": [
    {
      "citations": null,
      "text": "Hi! My name is Claude.",
      "type": "text"
    }
  ],
  "id": "msg_013Zva2CMHLNnXjNJJKqJ2EF",
  "model": "claude-sonnet-4-5-20250929",
  "role": "assistant",
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "type": "message",
  "usage": {
    "input_tokens": 2095,
    "output_tokens": 503
  }
}

向量接口#

如开局描述,向量接口用于将输入的文本、图片、视频等信息转换成向量表示,因此向量接口基本上有一个固定的模式:输入(文本、图片、视频)-> 输出(向量)。以 OpenAI 的 embeddings 接口为例:

# POST https://api.openai.com/v1/embeddings

# request
curl https://api.openai.com/v1/embeddings \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": "The food was delicious and the waiter...",
    "model": "text-embedding-ada-002",
    "encoding_format": "float"
  }'

# response
{
  "object": "list",
  "data": [
    {
      "object": "embedding",
      "embedding": [
        0.0023064255,
        -0.009327292,
        .... (1536 floats total for ada-002)
        -0.0028842222,
      ],
      "index": 0
    }
  ],
  "model": "text-embedding-ada-002",
  "usage": {
    "prompt_tokens": 8,
    "total_tokens": 8
  }
}