# aigateway **Repository Path**: le3691325_admin/aigateway ## Basic Information - **Project Name**: aigateway - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-05-31 - **Last Updated**: 2026-05-31 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # AI Gateway - PHP 通用 AI 调用接口 对标 Python OpenAI SDK 风格的 PHP AI 客户端,支持 **OpenAI / Claude / Gemini** 及所有兼容 OpenAI 格式的第三方服务。 ## 目录 - [快速开始](#快速开始) - [Python vs PHP 对照](#python-vs-php-对照) - [支持的厂商](#支持的厂商) - [基础用法](#基础用法) - [创建客户端](#创建客户端) - [发起对话](#发起对话) - [多轮对话](#多轮对话) - [获取 Token 用量](#获取-token-用量) - [流式输出(Streaming)](#流式输出streaming) - [命令行流式输出](#命令行流式输出) - [SSE 推送到浏览器](#sse-推送到浏览器) - [各厂商用法](#各厂商用法) - [OpenAI](#openai) - [Claude (Anthropic)](#claude-anthropic) - [Gemini (Google)](#gemini-google) - [兼容 OpenAI 格式的第三方服务](#兼容-openai-格式的第三方服务) - [高级功能](#高级功能) - [JSON Mode](#json-mode) - [Function Calling / Tools](#function-calling--tools) - [自定义 HTTP 头](#自定义-http-头) - [动态切换模型](#动态切换模型) - [文件结构](#文件结构) - [架构说明](#架构说明) - [扩展开发](#扩展开发) --- ## 快速开始 ```php '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 等 | --- ## 基础用法 ### 创建客户端 ```php 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 请求头 | ### 发起对话 ```php $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 | 否 | 频率惩罚 | ### 多轮对话 ```php $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 用量 ```php $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) ### 命令行流式输出 ```php $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)中: ```php 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 ```php $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) ```php $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) ```php $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` 即可: ```php // 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 ```php $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 ```php $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 头 ```php $client = new OpenAI([ 'api_key' => 'sk-your-key', 'default_headers' => [ 'X-Custom-Header' => 'custom-value', ], ]); ``` ### 动态切换模型 ```php $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' => '帮我分析这段代码的性能瓶颈...']], ]); ``` ### 动态切换服务商 ```php $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 服务商,只需: 1. 创建类实现 `ProviderInterface` 接口 2. 通过 `ProviderFactory::register()` 注册 ```php 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']], ]); ```