aigateway / ai-gateway
PHP通用AI调用接口 - 对标Python OpenAI SDK风格,支持OpenAI/Claude/Gemini及所有兼容服务
v1.0.2
2026-05-31 08:43 UTC
Requires
- php: >=8.1
- ext-curl: *
- ext-json: *
Requires (Dev)
- phpunit/phpunit: ^10.0
This package is auto-updated.
Last update: 2026-06-22 13:08:16 UTC
README
对标 Python OpenAI SDK 风格的 PHP AI 客户端,支持 OpenAI / Claude / Gemini 及所有兼容 OpenAI 格式的第三方服务。
目录
快速开始
安装地址
composer require aigateway/ai-gateway
<?php
require __DIR__ . '/vendor/autoload.php';
use AiGateway\OpenAI;
$client = new OpenAI(['api_key' => 'sk-your-openai-key']);
$response = $client->chat->completions->create([
'model' => 'gpt-4',
'messages' => [
['role' => 'user', 'content' => '用PHP写一个冒泡排序'],
],
]);
echo $response->choices[0]->message->content;
Python vs PHP 对照
| 操作 | Python OpenAI SDK | 本 PHP 接口 |
|---|---|---|
| 创建客户端 | client = OpenAI(api_key="sk-xxx") | $client = new OpenAI(['api_key' => 'sk-xxx']) |
| 发起对话 | client.chat.completions.create(...) | $client->chat->completions->create([...]) |
| 获取回复内容 | response.choices[0].message.content | $response->choices[0]->message->content |
| 流式输出 | stream=True + for chunk in stream | 'stream' => true + foreach ($stream as $chunk) |
| 流式内容 | chunk.choices[0].delta.content | $chunk->choices[0]->delta->content |
| Token 用量 | response.usage.prompt_tokens | $response->usage->prompt_tokens |
| 模型名称 | response.model | $response->model |
| 结束原因 | response.choices[0].finish_reason | $response->choices[0]->finish_reason |
支持的厂商
| 厂商 | provider 值 | 默认 base_url | 说明 |
|---|---|---|---|
| OpenAI | openai | https://api.openai.com/v1 | 原生 OpenAI API |
| Claude | claude | https://api.anthropic.com/v1 | Anthropic Claude API |
| Gemini | gemini | https://generativelanguage.googleapis.com/v1beta | Google Gemini API |
| 第三方 | openai | 自定义 | DeepSeek、通义千问、Moonshot 等 |
基础用法
创建客户端
use AiGateway\OpenAI;
// 方式一:new 创建
$client = new OpenAI(['api_key' => 'sk-your-openai-key']);
// 方式二:静态工厂方法(等价)
$client = OpenAI::client(['api_key' => 'sk-your-openai-key']);
// 带完整配置
$client = new OpenAI([
'api_key' => 'sk-your-openai-key',
'model' => 'gpt-4',
'base_url' => 'https://api.openai.com/v1',
'temperature' => 0.7,
'max_tokens' => 4096,
'timeout' => 60,
]);
全部配置项
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
api_key | string | '' | API 密钥(必填) |
base_url | string | https://api.openai.com/v1 | API 基础地址 |
provider | string | openai | 服务商标识:openai / claude / gemini |
model | string | gpt-3.5-turbo | 默认模型 |
timeout | int | 60 | HTTP 超时秒数 |
max_tokens | int | 4096 | 最大生成 Token 数 |
temperature | float | 0.7 | 温度参数(0~2) |
api_version | string | '' | API 版本(Claude 专用,默认 2023-06-01) |
default_headers | array | [] | 额外的自定义 HTTP 请求头 |
发起对话
$response = $client->chat->completions->create([
'model' => 'gpt-4',
'messages' => [
['role' => 'user', 'content' => 'Hello!'],
],
]);
// 获取返回内容
echo $response->choices[0]->message->content; // AI 回复文本
echo $response->choices[0]->message->role; // assistant
echo $response->model; // gpt-4
echo $response->choices[0]->finish_reason; // stop
echo $response->provider; // openai
create() 参数列表
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
model | string | 否 | 模型名称,不传则使用配置中的默认值 |
messages | array | 是 | 消息列表,每个元素含 role 和 content |
stream | bool | 否 | 是否流式输出,默认 false |
temperature | float | 否 | 温度参数 |
max_tokens | int | 否 | 最大生成 Token 数 |
tools | array | 否 | Function Calling 工具定义 |
tool_choice | mixed | 否 | 工具选择策略 |
response_format | array | 否 | 响应格式(如 ['type' => 'json_object']) |
top_p | float | 否 | Top-P 采样 |
stop | mixed | 否 | 停止词 |
n | int | 否 | 生成数量 |
presence_penalty | float | 否 | 存在惩罚 |
frequency_penalty | float | 否 | 频率惩罚 |
多轮对话
$response = $client->chat->completions->create([
'model' => 'gpt-4',
'messages' => [
['role' => 'system', 'content' => '你是一个专业的PHP开发助手'],
['role' => 'user', 'content' => 'PHP有哪些主流框架?'],
['role' => 'assistant', 'content' => 'PHP主流框架有Laravel、Symfony、ThinkPHP等...'],
['role' => 'user', 'content' => '请详细介绍Laravel'],
],
]);
echo $response->choices[0]->message->content;
获取 Token 用量
$response = $client->chat->completions->create([
'messages' => [['role' => 'user', 'content' => '你好']],
]);
$usage = $response->usage;
echo $usage->prompt_tokens; // 输入 Token 数
echo $usage->completion_tokens; // 输出 Token 数
echo $usage->total_tokens; // 总 Token 数
流式输出(Streaming)
命令行流式输出
$stream = $client->chat->completions->create([
'model' => 'gpt-4',
'messages' => [
['role' => 'user', 'content' => '写一首关于编程的诗'],
],
'stream' => true,
]);
foreach ($stream as $chunk) {
echo $chunk->choices[0]->delta->content;
}
echo "\n";
SSE 推送到浏览器
在 Web 控制器(如 Laravel Controller)中:
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
$stream = $client->chat->completions->create([
'model' => 'gpt-4',
'messages' => [['role' => 'user', 'content' => '讲个故事']],
'stream' => true,
]);
foreach ($stream as $chunk) {
$content = $chunk->choices[0]->delta->content;
if ($content !== null) {
echo "data: " . json_encode(['content' => $content], JSON_UNESCAPED_UNICODE) . "\n\n";
ob_flush();
flush();
}
}
echo "data: [DONE]\n\n";
各厂商用法
OpenAI
$client = new OpenAI([
'api_key' => 'sk-your-openai-key',
]);
// 默认使用 gpt-3.5-turbo,可按需指定模型
$response = $client->chat->completions->create([
'model' => 'gpt-4',
'messages' => [
['role' => 'user', 'content' => '你好'],
],
]);
Claude (Anthropic)
$client = new OpenAI([
'api_key' => 'sk-ant-your-claude-key',
'base_url' => 'https://api.anthropic.com/v1',
'provider' => 'claude',
'model' => 'claude-3-sonnet-20240229', // 或 claude-3-opus-20240229
'api_version' => '2023-06-01', // API 版本
]);
$response = $client->chat->completions->create([
'model' => 'claude-3-sonnet-20240229',
'messages' => [
['role' => 'user', 'content' => '如何优化Laravel性能?'],
],
'max_tokens' => 2048,
]);
echo $response->choices[0]->message->content;
注意:Claude 的 system 消息会自动从 messages 数组中提取到独立的 system 字段,无需手动处理。
Gemini (Google)
$client = new OpenAI([
'api_key' => 'your-gemini-key',
'base_url' => 'https://generativelanguage.googleapis.com/v1beta',
'provider' => 'gemini',
'model' => 'gemini-pro', // 或 gemini-1.5-pro
]);
$response = $client->chat->completions->create([
'messages' => [
['role' => 'user', 'content' => '什么是RESTful API?'],
],
]);
echo $response->choices[0]->message->content;
兼容 OpenAI 格式的第三方服务
任何兼容 OpenAI Chat Completions API 格式的服务,只需修改 base_url 和 model 即可:
// DeepSeek
$client = new OpenAI([
'api_key' => 'your-deepseek-key',
'base_url' => 'https://api.deepseek.com/v1',
'model' => 'deepseek-chat',
]);
// 通义千问(阿里云 DashScope)
$client = new OpenAI([
'api_key' => 'your-dashscope-key',
'base_url' => 'https://dashscope.aliyuncs.com/compatible-mode/v1',
'model' => 'qwen-plus',
]);
// Moonshot(月之暗面)
$client = new OpenAI([
'api_key' => 'your-moonshot-key',
'base_url' => 'https://api.moonshot.cn/v1',
'model' => 'moonshot-v1-8k',
]);
// 调用方式完全一致
$response = $client->chat->completions->create([
'messages' => [['role' => 'user', 'content' => '你好']],
]);
echo $response->choices[0]->message->content;
高级功能
JSON Mode
$response = $client->chat->completions->create([
'model' => 'gpt-4',
'messages' => [
['role' => 'system', 'content' => 'Return JSON only'],
['role' => 'user', 'content' => '列出3个PHP框架及其特点'],
],
'response_format' => ['type' => 'json_object'],
]);
$data = json_decode($response->choices[0]->message->content, true);
Function Calling / Tools
$tools = [
[
'type' => 'function',
'function' => [
'name' => 'get_weather',
'description' => '获取指定城市的天气',
'parameters' => [
'type' => 'object',
'properties' => [
'city' => [
'type' => 'string',
'description' => '城市名称',
],
],
'required' => ['city'],
],
],
],
];
$response = $client->chat->completions->create([
'model' => 'gpt-4',
'messages' => [
['role' => 'user', 'content' => '北京今天天气怎么样?'],
],
'tools' => $tools,
'tool_choice' => 'auto',
]);
echo $response->choices[0]->message->content;
自定义 HTTP 头
$client = new OpenAI([
'api_key' => 'sk-your-key',
'default_headers' => [
'X-Custom-Header' => 'custom-value',
],
]);
动态切换模型
$client = new OpenAI([
'api_key' => 'sk-your-key',
'model' => 'gpt-3.5-turbo', // 初始模型
]);
// 简单问题用便宜模型
$response = $client->chat->completions->create([
'model' => 'gpt-3.5-turbo',
'messages' => [['role' => 'user', 'content' => '天气怎么样?']],
]);
// 复杂任务切到强模型,只需改 model 参数
$response = $client->chat->completions->create([
'model' => 'gpt-4',
'messages' => [['role' => 'user', 'content' => '帮我分析这段代码的性能瓶颈...']],
]);
动态切换服务商
$client = new OpenAI(['api_key' => 'sk-openai-key']);
// 使用 OpenAI
echo $client->chat->completions->create([
'messages' => [['role' => 'user', 'content' => 'Hello']],
])->choices[0]->message->content;
// 切换到 Claude(同一次请求中可切换)
$client->setProvider('claude')
->setApiKey('sk-ant-claude-key')
->setBaseUrl('https://api.anthropic.com/v1');
echo $client->chat->completions->create([
'model' => 'claude-3-sonnet-20240229',
'messages' => [['role' => 'user', 'content' => 'Hello']],
'max_tokens' => 1024,
])->choices[0]->message->content;
文件结构
ai/
├── composer.json # Composer 配置 + PSR-4 autoload
├── src/ # 源代码(PSR-4: AiGateway\ → src/)
│ ├── OpenAI.php # 主客户端(对标 Python 的 OpenAI())
│ ├── Chat.php # $client->chat 链式调用模块
│ ├── Completions.php # $client->chat->completions + create() 核心方法
│ ├── Response/ # 统一响应对象
│ │ ├── ChatCompletion.php # 非流式响应
│ │ ├── ChatCompletionChunk.php # 流式响应块
│ │ ├── Choice.php # response.choices[0]
│ │ ├── StreamChoice.php # chunk.choices[0]
│ │ ├── Message.php # choice.message
│ │ ├── Delta.php # chunk.choices[0].delta
│ │ └── Usage.php # response.usage
│ └── Provider/ # 各厂商适配器
│ ├── ProviderInterface.php # Provider 接口定义
│ ├── ProviderFactory.php # Provider 工厂
│ ├── OpenAIProvider.php # OpenAI 适配器
│ ├── ClaudeProvider.php # Claude 适配器
│ └── GeminiProvider.php # Gemini 适配器
├── example.php # 完整使用示例
└── README.md # 本文件
架构说明
采用 适配器模式 + 工厂模式:
用户代码
│
▼
OpenAI (客户端配置)
│
▼
Chat → Completions.create() ←── 统一入口,对标 Python SDK
│
▼
ProviderFactory ────────────── 根据 provider 字段自动选择适配器
│
├── OpenAIProvider ─────── 原生 OpenAI 及兼容服务
├── ClaudeProvider ─────── 请求/响应翻译(5 大差异自动处理)
└── GeminiProvider ─────── 请求/响应翻译(6 大差异自动处理)
│
▼
统一响应 (ChatCompletion / ChatCompletionChunk)
核心原则:无论底层使用哪个厂商的 API,上层调用方式和返回结构完全一致(OpenAI 格式)。厂商差异在 Provider 层的 translateRequest() / translateResponse() 方法中完全屏蔽。
扩展开发
如需支持新的 AI 服务商,只需:
- 创建类实现
ProviderInterface接口 - 通过
ProviderFactory::register()注册
use AiGateway\Provider\ProviderFactory;
use AiGateway\Provider\ProviderInterface;
use AiGateway\OpenAI;
use AiGateway\Response\ChatCompletion;
use AiGateway\Response\ChatCompletionChunk;
class MyCustomProvider implements ProviderInterface
{
protected OpenAI $client;
public function __construct(OpenAI $client)
{
$this->client = $client;
}
public function chat(array $params): ChatCompletion
{
// 1. 将 $params 翻译为目标 API 格式
// 2. 发起 HTTP 请求
// 3. 将响应翻译为 OpenAI 格式
// 4. 返回 ChatCompletion::fromProvider($translated, 'my_provider')
}
public function chatStream(array $params): \Generator
{
// 流式处理,翻译每个 chunk 后 yield ChatCompletionChunk
}
}
// 注册
ProviderFactory::register('my_provider', MyCustomProvider::class);
// 使用
$client = new OpenAI([
'api_key' => 'your-key',
'base_url' => 'https://api.example.com/v1',
'provider' => 'my_provider',
'model' => 'custom-model',
]);
$response = $client->chat->completions->create([
'messages' => [['role' => 'user', 'content' => 'Hello']],
]);