Grok API 和 OpenAI API 到底有什么区别?一篇文章搞懂协议兼容、Responses API、流式输出与完整接入代码

最近很多开发者开始接入 Grok,但第一次看到 Grok API 时,经常会产生一个疑问:
Grok API 是不是就是 OpenAI API?
答案是:
不是同一个 API,但 Grok 的 xAI API 对 OpenAI REST API 做了高度兼容。
这意味着,如果你的项目本来就已经接入了 OpenAI,那么接入 Grok 通常不需要重新写一套客户端。
很多情况下,只需要修改:
Base URL
API Key
Model
就可以完成切换。
xAI 官方 REST API 文档明确说明,其 Inference API 提供 OpenAI REST API compatibility,而且同时支持 Chat Completions 和 Responses API。当前 xAI 官方更推荐使用 Responses API。
本文将从协议、请求格式、流式输出、Function Calling、Responses API、Python、Node.js、Go、curl 等多个角度完整介绍 Grok API。
本文示例统一使用:
Base URL:
https://ai.silicogrove.com
因此完整接口地址通常为:
https://ai.silicogrove.com/v1/chat/completions
https://ai.silicogrove.com/v1/responses
如果你使用 OpenAI SDK,则通常配置:
https://ai.silicogrove.com/v1
一、先说结论:Grok API 和 OpenAI API 是什么关系?
可以简单理解成:
OpenAI API Protocol
│
┌────────────┴────────────┐
│ │
Chat Completions Responses API
│ │
/v1/chat/completions /v1/responses
│ │
┌──────┼───────┐ ┌─────┼──────┐
│ │ │ │ │ │
OpenAI Grok 其他兼容商 OpenAI Grok 其他兼容商
Grok 并不是运行在 OpenAI 的服务器上。
它是 xAI 自己的模型、自己的基础设施、自己的 API。
但是 xAI 在 API 设计上主动兼容了 OpenAI。
所以你可以使用:
from openai import OpenAI
来调用 Grok。
也可以使用:
import OpenAI from "openai";
调用 Grok。
甚至很多原本为 OpenAI 编写的 Agent、CLI、AI SDK,只要支持自定义:
base_url
api_key
model
理论上都可以非常方便地接入 Grok。
xAI 官方文档自己的示例也直接使用 OpenAI SDK,并通过修改 base_url 接入 Grok。
二、Grok 支持哪些 OpenAI 风格接口?
最重要的两个是:
POST /v1/chat/completions
以及:
POST /v1/responses
其中:
Chat Completions
也就是大家最熟悉的:
/v1/chat/completions
请求结构类似:
{
"model": "grok-4.5",
"messages": [
{
"role": "user",
"content": "你好"
}
]
}
xAI 官方 REST API 目前仍然提供 /v1/chat/completions,支持文本以及图片理解等场景。
Responses API
新项目更建议使用:
/v1/responses
请求结构变成:
{
"model": "grok-4.5",
"input": "你好"
}
xAI 官方目前明确将 Responses API 作为推荐交互方式,而 Chat Completions 更多作为兼容已有系统的旧式接口存在。
如果现在从零开发一个新的 AI 项目,我更建议直接围绕:
Responses API
设计。
三、最简单的 curl 调用 Grok
先来看最简单的方式。
假设已经有 API Key:
export API_KEY="sk-xxxxxxxxxxxxxxxx"
请求:
curl https://ai.silicogrove.com/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "grok-4.5",
"messages": [
{
"role": "user",
"content": "你好,请用一句话介绍一下 Grok。"
}
]
}'
你会得到类似:
{
"id": "chatcmpl_xxxxxxxxx",
"object": "chat.completion",
"created": 1786896000,
"model": "grok-4.5",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Grok 是 xAI 开发的大语言模型系列。"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 18,
"completion_tokens": 16,
"total_tokens": 34
}
}
是不是非常熟悉?
因为这就是典型的 OpenAI Chat Completions 风格。
四、加上 System Prompt
实际开发基本不会只有 user 消息。
完整请求可以这样写:
curl https://ai.silicogrove.com/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "grok-4.5",
"messages": [
{
"role": "system",
"content": "你是一名资深 Go 后端工程师,回答问题时优先提供可以直接运行的代码。"
},
{
"role": "user",
"content": "使用 Go 写一个 HTTP Server。"
}
]
}'
对于以前已经接入 OpenAI 的程序,这种代码通常完全不用重新设计。
五、Responses API curl 完整示例
现在我们换成比较新的 Responses API。
curl https://ai.silicogrove.com/v1/responses \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "grok-4.5",
"input": "请用简单的语言解释什么是大语言模型。"
}'
和 Chat Completions 最大的区别之一,就是:
以前:
{
"messages": []
}
现在可以直接:
{
"input": "..."
}
Responses API 非常适合:
AI Agent
工具调用
多模态
Web Search
复杂推理
多轮执行
这种新一代 AI 应用。
六、Responses API 使用消息数组
当然,input 不一定必须是字符串。
也可以写成:
curl https://ai.silicogrove.com/v1/responses \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "grok-4.5",
"input": [
{
"role": "system",
"content": "你是一名专业程序员。"
},
{
"role": "user",
"content": "解释一下 Redis 分布式锁。"
}
]
}'
所以从设计思路来看:
Chat Completions
messages
↓
model
↓
assistant message
逐渐演化成:
Responses
input
↓
model
↓
tools
↓
reasoning
↓
output
这对于 Agent 系统明显更加友好。
七、流式输出 curl
AI 聊天程序一般都不会等待整个回答生成完成。
而是:
你
↓
发送请求
↓
模型开始输出
↓
前端逐字展示
这就是 Streaming。
例如:
curl -N https://ai.silicogrove.com/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "grok-4.5",
"stream": true,
"messages": [
{
"role": "user",
"content": "写一篇关于 Go 协程的简短介绍。"
}
]
}'
关键参数只有:
"stream": true
curl 中建议加:
-N
避免 curl 对返回内容进行缓冲。
输出大致会变成连续 SSE 数据:
data: {...}
data: {...}
data: {...}
然后客户端不断读取增量内容。
八、Python 调用 Grok
如果以前用过 OpenAI Python SDK,基本不需要学习新的东西。
安装:
pip install openai
完整代码:
from openai import OpenAI
API_KEY = "sk-xxxxxxxxxxxxxxxx"
client = OpenAI(
api_key=API_KEY,
base_url="https://ai.silicogrove.com/v1"
)
response = client.chat.completions.create(
model="grok-4.5",
messages=[
{
"role": "system",
"content": "你是一名专业的 Python 工程师。"
},
{
"role": "user",
"content": "写一个 Python 快速排序,并解释实现原理。"
}
]
)
print(response.choices[0].message.content)
注意这里:
base_url="https://ai.silicogrove.com/v1"
而 curl 使用的是完整接口:
https://ai.silicogrove.com/v1/chat/completions
这是很多开发者第一次配置时容易搞错的地方。
九、Python Responses API
推荐的新方式:
from openai import OpenAI
client = OpenAI(
api_key="sk-xxxxxxxxxxxxxxxx",
base_url="https://ai.silicogrove.com/v1"
)
response = client.responses.create(
model="grok-4.5",
input="使用 Python 写一个简单的 HTTP Server。"
)
print(response.output_text)
可以看到代码非常简单:
response = client.responses.create(...)
甚至比:
client.chat.completions.create(...)
更加直观。
十、Python 流式输出
完整程序:
from openai import OpenAI
client = OpenAI(
api_key="sk-xxxxxxxxxxxxxxxx",
base_url="https://ai.silicogrove.com/v1"
)
stream = client.chat.completions.create(
model="grok-4.5",
messages=[
{
"role": "user",
"content": "详细介绍一下 Kubernetes。"
}
],
stream=True
)
for chunk in stream:
if not chunk.choices:
continue
delta = chunk.choices[0].delta
if delta.content:
print(delta.content, end="", flush=True)
print()
运行:
python app.py
终端就会像 ChatGPT 一样不断显示内容。
十一、Python 完整命令行聊天机器人
我们直接做一个能连续聊天的程序。
from openai import OpenAI
client = OpenAI(
api_key="sk-xxxxxxxxxxxxxxxx",
base_url="https://ai.silicogrove.com/v1"
)
messages = [
{
"role": "system",
"content": "你是一名专业的 AI 编程助手。"
}
]
print("Grok CLI Chat")
print("输入 exit 退出")
print("-" * 50)
while True:
user_input = input("\nYou: ")
if user_input.lower() in ["exit", "quit"]:
break
messages.append({
"role": "user",
"content": user_input
})
stream = client.chat.completions.create(
model="grok-4.5",
messages=messages,
stream=True
)
print("\nGrok: ", end="")
assistant_content = ""
for chunk in stream:
if not chunk.choices:
continue
content = chunk.choices[0].delta.content
if content:
assistant_content += content
print(
content,
end="",
flush=True
)
messages.append({
"role": "assistant",
"content": assistant_content
})
print()
现在运行:
python chat.py
就可以直接:
You: Redis 和 Memcached 有什么区别?
Grok: Redis 和 Memcached 都属于内存缓存系统,但是……
然后继续:
You: 那 Go 项目应该选哪个?
由于:
messages
一直保存着,所以模型可以理解之前的上下文。
十二、Node.js 调用 Grok
安装:
npm install openai
package.json:
{
"type": "module",
"dependencies": {
"openai": "^5.0.0"
}
}
创建:
app.js
完整代码:
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.API_KEY,
baseURL: "https://ai.silicogrove.com/v1"
});
async function main() {
const completion =
await client.chat.completions.create({
model: "grok-4.5",
messages: [
{
role: "system",
content: "你是一名专业 Node.js 工程师。"
},
{
role: "user",
content: "使用 Express 写一个 REST API。"
}
]
});
console.log(
completion.choices[0].message.content
);
}
main();
配置 Key:
export API_KEY="sk-xxxxxxxxxxxxxxxx"
运行:
node app.js
十三、Node.js Responses API
Responses API 更简单:
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.API_KEY,
baseURL: "https://ai.silicogrove.com/v1"
});
async function main() {
const response =
await client.responses.create({
model: "grok-4.5",
input: "使用 Node.js 写一个 WebSocket Server。"
});
console.log(response.output_text);
}
main();
十四、Node.js 流式输出
完整实现:
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.API_KEY,
baseURL: "https://ai.silicogrove.com/v1"
});
async function main() {
const stream =
await client.chat.completions.create({
model: "grok-4.5",
messages: [
{
role: "user",
content: "详细介绍微服务架构。"
}
],
stream: true
});
for await (const chunk of stream) {
const content =
chunk.choices?.[0]?.delta?.content;
if (content) {
process.stdout.write(content);
}
}
process.stdout.write("\n");
}
main();
这也是现在 Web AI 应用最常见的实现方式。
十五、Go 调用 Grok
Go 开发者其实不一定非要安装 SDK。
因为 OpenAI 协议本质就是:
HTTP + JSON
所以直接使用标准库就可以。
完整代码:
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
const (
BaseURL = "https://ai.silicogrove.com"
APIKey = "sk-xxxxxxxxxxxxxxxx"
)
type Message struct {
Role string `json:"role"`
Content string `json:"content"`
}
type ChatRequest struct {
Model string `json:"model"`
Messages []Message `json:"messages"`
}
type ChatResponse struct {
ID string `json:"id"`
Object string `json:"object"`
Created int64 `json:"created"`
Choices []struct {
Index int `json:"index"`
Message struct {
Role string `json:"role"`
Content string `json:"content"`
} `json:"message"`
FinishReason string `json:"finish_reason"`
} `json:"choices"`
Usage struct {
PromptTokens int `json:"prompt_tokens"`
CompletionTokens int `json:"completion_tokens"`
TotalTokens int `json:"total_tokens"`
} `json:"usage"`
}
func main() {
requestBody := ChatRequest{
Model: "grok-4.5",
Messages: []Message{
{
Role: "system",
Content: "你是一名资深 Go 工程师。",
},
{
Role: "user",
Content: "使用 Gin 写一个 REST API。",
},
},
}
data, err := json.Marshal(requestBody)
if err != nil {
panic(err)
}
req, err := http.NewRequest(
http.MethodPost,
BaseURL+"/v1/chat/completions",
bytes.NewBuffer(data),
)
if err != nil {
panic(err)
}
req.Header.Set(
"Authorization",
"Bearer "+APIKey,
)
req.Header.Set(
"Content-Type",
"application/json",
)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
panic(err)
}
if resp.StatusCode != http.StatusOK {
fmt.Println(
"HTTP Error:",
resp.StatusCode,
)
fmt.Println(string(body))
return
}
var result ChatResponse
err = json.Unmarshal(
body,
&result,
)
if err != nil {
panic(err)
}
if len(result.Choices) == 0 {
fmt.Println("没有返回内容")
return
}
fmt.Println(
result.Choices[0].
Message.
Content,
)
fmt.Println()
fmt.Printf(
"Tokens: %d\n",
result.Usage.TotalTokens,
)
}
运行:
go run main.go
这种方式的最大优势就是:
完全不依赖任何第三方 SDK。
十六、Go 封装成客户端
真正项目里肯定不能每次都手写:
http.NewRequest()
可以自己封装一个客户端。
例如:
package grok
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"time"
)
type Client struct {
BaseURL string
APIKey string
HTTPClient *http.Client
}
type Message struct {
Role string `json:"role"`
Content string `json:"content"`
}
type ChatRequest struct {
Model string `json:"model"`
Messages []Message `json:"messages"`
Temperature float64 `json:"temperature,omitempty"`
}
type ChatResponse struct {
ID string `json:"id"`
Choices []struct {
Message struct {
Role string `json:"role"`
Content string `json:"content"`
} `json:"message"`
FinishReason string `json:"finish_reason"`
} `json:"choices"`
Usage struct {
PromptTokens int `json:"prompt_tokens"`
CompletionTokens int `json:"completion_tokens"`
TotalTokens int `json:"total_tokens"`
} `json:"usage"`
}
func NewClient(
baseURL string,
apiKey string,
) *Client {
return &Client{
BaseURL: baseURL,
APIKey: apiKey,
HTTPClient: &http.Client{
Timeout: 120 * time.Second,
},
}
}
func (c *Client) Chat(
model string,
messages []Message,
) (*ChatResponse, error) {
payload := ChatRequest{
Model: model,
Messages: messages,
}
data, err := json.Marshal(payload)
if err != nil {
return nil, err
}
url :=
c.BaseURL +
"/v1/chat/completions"
req, err := http.NewRequest(
http.MethodPost,
url,
bytes.NewReader(data),
)
if err != nil {
return nil, err
}
req.Header.Set(
"Authorization",
"Bearer "+c.APIKey,
)
req.Header.Set(
"Content-Type",
"application/json",
)
resp, err :=
c.HTTPClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err :=
io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if resp.StatusCode < 200 ||
resp.StatusCode >= 300 {
return nil, fmt.Errorf(
"API error status=%d body=%s",
resp.StatusCode,
string(body),
)
}
var result ChatResponse
if err := json.Unmarshal(
body,
&result,
); err != nil {
return nil, err
}
if len(result.Choices) == 0 {
return nil,
errors.New(
"empty choices",
)
}
return &result, nil
}
使用:
package main
import (
"fmt"
"example.com/project/grok"
)
func main() {
client :=
grok.NewClient(
"https://ai.silicogrove.com",
"sk-xxxxxxxxxxxxxxxx",
)
response, err :=
client.Chat(
"grok-4.5",
[]grok.Message{
{
Role: "system",
Content:
"你是一名资深后端工程师。",
},
{
Role: "user",
Content:
"解释什么是 API Gateway。",
},
},
)
if err != nil {
panic(err)
}
fmt.Println(
response.
Choices[0].
Message.
Content,
)
}
这样整个项目就只需要:
client.Chat(...)
了。
十七、为什么最好不要设计一个 GrokProtocol?
如果你正在开发 API Gateway、中转 API、AI SDK 或类似 new-api 的平台,一个非常重要的问题是:
到底应该把 Grok 单独作为一个协议,还是把它归类到 OpenAI Compatible?
例如千万不要设计成:
Protocol
├── OpenAI
├── Claude
├── Gemini
├── DeepSeek
├── Grok
├── OpenRouter
└── ...
这会造成大量重复代码。
更合理的是:
Protocol
│
├── OpenAI Chat Completions
│
├── OpenAI Responses
│
├── Anthropic Messages
│
└── Gemini GenerateContent
然后 Provider 再分:
Provider
│
├── OpenAI
├── xAI
├── DeepSeek
├── OpenRouter
├── SiliconFlow
└── Other OpenAI Compatible
也就是:
Protocol != Provider
这是设计 AI Gateway 非常关键的一点。
十八、一个更合理的 Go Provider 设计
例如:
type Provider interface {
Name() string
BaseURL() string
APIKey() string
Headers() map[string]string
}
OpenAI:
type OpenAIProvider struct {
Key string
}
func (p *OpenAIProvider) Name() string {
return "openai"
}
func (p *OpenAIProvider) BaseURL() string {
return "https://api.openai.com"
}
func (p *OpenAIProvider) APIKey() string {
return p.Key
}
func (p *OpenAIProvider) Headers() map[string]string {
return map[string]string{
"Authorization":
"Bearer " + p.Key,
}
}
Grok:
type GrokProvider struct {
Key string
}
func (p *GrokProvider) Name() string {
return "grok"
}
func (p *GrokProvider) BaseURL() string {
return "https://ai.silicogrove.com"
}
func (p *GrokProvider) APIKey() string {
return p.Key
}
func (p *GrokProvider) Headers() map[string]string {
return map[string]string{
"Authorization":
"Bearer " + p.Key,
}
}
可以发现:
Request Protocol
完全可以复用。
真正变的只有:
BaseURL
APIKey
Model
Provider 特有能力
十九、Function Calling
Grok 同样支持 Function Calling。
xAI 官方目前还支持将自定义 Function Calling 与服务器端工具组合使用。
例如定义一个天气函数:
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市天气",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称"
}
},
"required": [
"city"
]
}
}
}
完整 curl:
curl https://ai.silicogrove.com/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "grok-4.5",
"messages": [
{
"role": "user",
"content": "北京现在天气怎么样?"
}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市天气",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称"
}
},
"required": [
"city"
]
}
}
}
]
}'
模型可能不会直接回答天气。
而是返回:
{
"tool_calls": [
{
"id": "call_xxx",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\":\"北京\"}"
}
}
]
}
你的程序读取:
get_weather
然后执行真正的代码。
比如:
def get_weather(city):
return {
"city": city,
"temperature": "31°C",
"weather": "晴"
}
再把结果交给模型。
这其实就是现在绝大多数 AI Agent 的底层逻辑:
User
↓
LLM
↓
决定调用工具
↓
Function Call
↓
程序执行
↓
Function Result
↓
LLM
↓
最终回答
二十、Structured Outputs
开发 AI 应用经常遇到一个问题。
你告诉模型:
返回 JSON
结果它返回:
```json
{
...
}
```
或者突然多说一句:
当然可以,以下是结果:
这样程序:
json.loads()
直接炸掉。
Structured Outputs 就是解决这个问题的。
xAI 官方目前提供 Structured Outputs,可以让支持的模型按照给定 JSON Schema 返回数据。
例如:
{
"name": "王小明",
"age": 25,
"skills": [
"Go",
"Python"
]
}
这种功能特别适合:
简历解析
发票识别
实体提取
数据清洗
Agent 参数生成
API 参数生成
爬虫数据结构化
二十一、Grok 和 OpenAI 最大的不同:x_search
虽然 Grok 高度兼容 OpenAI API,但是:
不要理解成 Grok 与 OpenAI 100% 一模一样。
因为 Grok 有自己的能力。
其中一个非常有代表性的功能就是:
x_search
也就是搜索 X 平台。
xAI 官方目前在 Responses API 中支持 x_search,并且该工具可以通过 OpenAI Responses API 兼容 SDK 使用。
例如概念上可以:
response = client.responses.create(
model="grok-4.5",
input="最近 X 上大家都在讨论哪些 AI Agent?",
tools=[
{
"type": "x_search"
}
]
)
这就不是普通 OpenAI 模型完全对应的能力了。
二十二、Grok Web Search
除了 X Search,还有:
web_search
Grok 可以在生成回答过程中搜索互联网和访问网页,从而回答需要实时信息的问题。xAI 官方把 Web Search 作为服务器端工具提供。
例如:
from openai import OpenAI
client = OpenAI(
api_key="sk-xxxxxxxxxxxxxxxx",
base_url="https://ai.silicogrove.com/v1"
)
response = client.responses.create(
model="grok-4.5",
input=
"搜索最近 AI Agent 领域发生的重要新闻。",
tools=[
{
"type": "web_search"
}
]
)
print(response.output_text)
还可以同时:
tools=[
{
"type": "web_search"
},
{
"type": "x_search"
}
]
xAI 官方文档也给出了使用 OpenAI SDK同时配置 web_search 和 x_search 的示例。
二十三、为什么 Responses API 对 Agent 更重要?
过去 Chat Completions 的核心设计思路其实就是:
聊天
所以核心结构是:
messages
但现在 AI 已经不只是聊天机器人。
现在越来越多应用是:
AI Agent
Agent 需要:
搜索互联网
调用 API
执行代码
读文件
操作数据库
调用 MCP
浏览网页
调用 Function
执行多轮任务
所以接口结构自然会从:
messages → completion
升级为:
input
↓
model
↓
reasoning
↓
tool
↓
tool result
↓
model
↓
output
因此现在如果开发:
AI Agent Framework
AI Gateway
AI SDK
MCP Client
CLI Agent
Coding Agent
最好同时考虑:
Chat Completions
+
Responses API
而不是只实现:
/v1/chat/completions
二十四、OpenAI 和 Grok 协议对比
简单整理一下:
| 能力 | OpenAI | Grok |
|---|---|---|
| Chat Completions | 支持 | 支持 |
| Responses API | 支持 | 支持 |
| OpenAI SDK | 原生 | 兼容 |
| Streaming | 支持 | 支持 |
| Function Calling | 支持 | 支持 |
| Structured Outputs | 支持 | 支持 |
| 图片理解 | 支持 | 支持,取决于模型 |
| Web Search | 支持相关工具能力 | 支持 |
| X Search | 无直接同名对应能力 | 支持 |
| Base URL | OpenAI 地址 | xAI 或兼容 Gateway |
| 模型 | GPT 系列 | Grok 系列 |
因此:
协议高度兼容,但模型能力和 Provider 扩展并不完全相同。
二十五、为什么有些 OpenAI 客户端换 Base URL 就能使用 Grok?
现在很多软件都有类似配置:
{
"api_key": "sk-xxx",
"base_url": "https://ai.silicogrove.com/v1",
"model": "grok-4.5"
}
原因就在这里。
因为客户端真正做的事情只是:
POST /v1/chat/completions
Body:
{
"model": "...",
"messages": []
}
Header:
Authorization: Bearer xxx
只要服务器实现了相同协议,客户端通常根本不关心服务器背后到底运行的是:
GPT
Grok
DeepSeek
Qwen
Llama
Mistral
这也是 OpenAI Compatible API 能成为今天 AI 行业事实标准之一的重要原因。
二十六、API Gateway 应该怎么设计?
如果让我设计一个 AI API Gateway,我会至少分三层。
第一层:Protocol
Protocol
│
├── OpenAI Chat Completions
├── OpenAI Responses
├── Anthropic Messages
└── Gemini GenerateContent
第二层:Provider
Provider
│
├── OpenAI
├── xAI
├── Anthropic
├── Google
├── DeepSeek
├── OpenRouter
└── Other
第三层:Model
Provider: xAI
Models
│
├── grok-4.5
├── ...
└── ...
因此一条请求经过 Gateway:
Client
↓
OpenAI Protocol
↓
Gateway
↓
Model Router
↓
Provider
↓
xAI
客户端甚至不需要知道真正的上游是谁。
二十七、一个统一 AI Client 的 Go 设计
可以设计:
type AIClient struct {
BaseURL string
APIKey string
}
func NewAIClient(
baseURL string,
apiKey string,
) *AIClient {
return &AIClient{
BaseURL: baseURL,
APIKey: apiKey,
}
}
然后:
grokClient :=
NewAIClient(
"https://ai.silicogrove.com",
"sk-xxx",
)
以后如果切到其他 OpenAI Compatible Provider:
otherClient :=
NewAIClient(
"https://example.com",
"sk-xxx",
)
业务层仍然调用:
client.Chat(...)
这就是为什么:
协议与 Provider 一定要解耦。
二十八、环境变量推荐配置
实际项目千万别写:
api_key="sk-xxxxx"
应该放环境变量。
Linux/macOS:
export AI_API_KEY="sk-xxxxxxxx"
export AI_BASE_URL="https://ai.silicogrove.com/v1"
export AI_MODEL="grok-4.5"
Python:
import os
from openai import OpenAI
client = OpenAI(
api_key=os.getenv("AI_API_KEY"),
base_url=os.getenv("AI_BASE_URL")
)
MODEL = os.getenv("AI_MODEL")
response = client.responses.create(
model=MODEL,
input="你好"
)
print(response.output_text)
Node.js:
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.AI_API_KEY,
baseURL: process.env.AI_BASE_URL
});
const response =
await client.responses.create({
model:
process.env.AI_MODEL,
input:
"你好"
});
console.log(
response.output_text
);
这样以后换模型根本不用改代码:
export AI_MODEL="grok-4.5"
二十九、curl 最小模板
如果只是测试接口,保存下面这份基本够用了。
Chat Completions:
curl https://ai.silicogrove.com/v1/chat/completions \
-H "Authorization: Bearer sk-xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"model": "grok-4.5",
"messages": [
{
"role": "user",
"content": "你好"
}
]
}'
Responses:
curl https://ai.silicogrove.com/v1/responses \
-H "Authorization: Bearer sk-xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"model": "grok-4.5",
"input": "你好"
}'
Streaming:
curl -N https://ai.silicogrove.com/v1/chat/completions \
-H "Authorization: Bearer sk-xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"model": "grok-4.5",
"stream": true,
"messages": [
{
"role": "user",
"content": "介绍一下 Grok"
}
]
}'
基本上只要这三个请求成功,就已经能证明一个 OpenAI Compatible Grok 接口的核心聊天能力已经跑通了。
三十、常见错误
1. Base URL 多写了一层 /v1
比如 SDK 配置:
base_url=
"https://ai.silicogrove.com/v1"
SDK 自己会追加:
/chat/completions
最终:
https://ai.silicogrove.com/v1/chat/completions
这是正确的。
如果你的 Gateway SDK 配置逻辑本身还会添加 /v1,就需要根据具体客户端调整。
所以最终判断标准永远是:
实际发出的 URL 是什么?
2. 模型不存在
例如:
{
"model": "grok-xxxxx"
}
但是 Gateway 没配置这个模型。
就可能返回:
model_not_found
因此文章里的:
grok-4.5
只是调用示例。
真正使用时应以对应 API 服务当前开放的模型列表为准。
3. 401
一般是:
API Key 错误
或者:
Authorization Header 没传
正确格式:
Authorization: Bearer sk-xxxx
不是:
Authorization: sk-xxxx
4. 404
重点检查:
/v1
例如:
https://ai.silicogrove.com/chat/completions
和:
https://ai.silicogrove.com/v1/chat/completions
不是同一个地址。
5. Streaming 没有逐字显示
先检查:
"stream": true
curl 再加:
-N
如果中间还有:
Nginx
Cloudflare
Gateway
则还要检查中间层有没有对 SSE 进行 Buffer。

三十一、到底应该使用 Chat Completions 还是 Responses?
如果是维护老项目:
Chat Completions
完全可以继续使用。
尤其你的系统里面已经大量使用:
messages
choices
delta
tool_calls
没必要为了“新”强行全部重写。
但如果现在开发一个新的:
Agent
Coding Agent
MCP Client
AI Assistant
自动化系统
Deep Research
我会优先考虑:
Responses API
因为 xAI 自己目前也推荐 Responses API。
三十二、最终总结
回到文章最开始的问题:
Grok API 和 OpenAI API 一样吗?
最准确的说法应该是:
Grok API 不是 OpenAI API,但 Grok 所使用的 xAI API 高度兼容 OpenAI REST API。
因此:
OpenAI SDK
通常可以直接调用 Grok。
原来:
client = OpenAI(
api_key="OPENAI_API_KEY"
)
现在:
client = OpenAI(
api_key="API_KEY",
base_url=
"https://ai.silicogrove.com/v1"
)
然后把:
model
换成对应 Grok 模型即可。
从工程设计来看,更应该理解为:
OpenAI Protocol
│
├── OpenAI Provider
├── xAI / Grok Provider
├── DeepSeek Provider
├── OpenRouter Provider
└── Other Compatible Provider
而不是:
OpenAI Protocol
Grok Protocol
DeepSeek Protocol
全部各写一遍。
如果正在开发 AI Gateway、API 中转平台或者统一 AI SDK,那么最合理的架构应该是:
Protocol
↓
Provider Adapter
↓
Model Router
↓
Upstream
这样未来接入新的 OpenAI Compatible 模型时,很多时候只需要:
新增 Provider
+
配置 Base URL
+
配置模型
而完全不需要重新开发一整套协议。
这才是 OpenAI Compatible API 对今天 AI 开发最大的价值。

浙公网安备 33010602011771号