Skip to content

OpenAI API完全指南

OpenAI是AI应用开发的首选平台,掌握其API是成为AI开发者的必经之路

概述

OpenAI是当前最主流的大模型API服务提供商,其GPT系列模型在自然语言处理领域表现卓越。本教程将带你从零开始掌握OpenAI API的使用方法。

为什么选择OpenAI?

优势说明
模型能力强GPT-4在推理、创作、代码等方面表现优秀
生态完善丰富的SDK、文档和社区支持
功能丰富支持对话、嵌入、图像、语音、微调等
稳定可靠企业级服务稳定性

OpenAI模型概览

OpenAI模型家族:

GPT-4系列(最强能力)
├── gpt-4          # 标准版,128K上下文
├── gpt-4-turbo    # 快速版,性价比高
├── gpt-4o         # 多模态,支持图像
└── gpt-4o-mini    # 轻量版,成本低

GPT-3.5系列(高性价比)
├── gpt-3.5-turbo  # 快速响应,成本低
└── gpt-3.5-turbo-16k  # 长上下文版本

其他模型
├── text-embedding-ada-002  # 文本嵌入
├── whisper                 # 语音识别
├── dall-e-3               # 图像生成
└── tts-1                  # 语音合成

基本概念

API Key

API Key是调用OpenAI API的身份凭证,需要在OpenAI官网申请。

API Key格式:sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

⚠️ 安全提示:
1. 不要在客户端代码中暴露API Key
2. 不要将API Key提交到代码仓库
3. 定期轮换API Key
4. 使用环境变量存储API Key

Token

Token是OpenAI计费和处理文本的基本单位。

Token理解:

英文:1 Token ≈ 4个字符 ≈ 0.75个单词
中文:1 Token ≈ 1.5个汉字

示例:
"Hello World" → 2个Token
"你好世界" → 约3个Token

计算工具:https://platform.openai.com/tokenizer

上下文窗口

上下文窗口是模型一次能处理的最大Token数。

模型上下文窗口
gpt-48,192 tokens
gpt-4-turbo128,000 tokens
gpt-4o128,000 tokens
gpt-3.5-turbo16,385 tokens

环境准备

安装PHP HTTP客户端

php
<?php
// 使用Composer安装Guzzle HTTP客户端
// composer require guzzlehttp/guzzle

require 'vendor/autoload.php';

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

配置环境变量

php
<?php
// .env文件内容
// OPENAI_API_KEY=sk-your-api-key-here

// 读取环境变量
$apiKey = getenv('OPENAI_API_KEY');
// 或使用$_ENV
$apiKey = $_ENV['OPENAI_API_KEY'] ?? null;

if (!$apiKey) {
    throw new Exception('请设置OPENAI_API_KEY环境变量');
}

基础API调用

创建API客户端类

php
<?php
require 'vendor/autoload.php';

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

class OpenAIClient
{
    private $client;
    private $apiKey;
    private $baseUrl = 'https://api.openai.com/v1';

    public function __construct(string $apiKey)
    {
        $this->apiKey = $apiKey;
        $this->client = new Client([
            'base_uri' => $this->baseUrl,
            'timeout' => 30,
            'headers' => [
                'Authorization' => 'Bearer ' . $this->apiKey,
                'Content-Type' => 'application/json',
            ],
        ]);
    }

    public function chat(array $messages, string $model = 'gpt-4o-mini'): array
    {
        try {
            $response = $this->client->post('/chat/completions', [
                'json' => [
                    'model' => $model,
                    'messages' => $messages,
                ],
            ]);

            return json_decode($response->getBody(), true);
        } catch (RequestException $e) {
            $errorBody = $e->getResponse() ? $e->getResponse()->getBody()->getContents() : 'Unknown error';
            throw new Exception('OpenAI API Error: ' . $errorBody);
        }
    }
}

// 使用示例
$apiKey = getenv('OPENAI_API_KEY');
$client = new OpenAIClient($apiKey);

$messages = [
    ['role' => 'user', 'content' => '你好,请介绍一下PHP语言的特点']
];

$result = $client->chat($messages);
echo $result['choices'][0]['message']['content'];

运行结果:

PHP(Hypertext Preprocessor)是一种广泛使用的开源服务器端脚本语言,具有以下主要特点:

1. **易于学习**:语法简洁,入门门槛低
2. **跨平台**:支持Windows、Linux、macOS等操作系统
3. **丰富的扩展**:拥有大量内置函数和第三方库
4. **数据库支持**:原生支持MySQL、PostgreSQL等多种数据库
5. **Web开发友好**:专为Web开发设计,与HTML高度集成

对话消息格式

php
<?php
// 消息角色说明

$messages = [
    // 系统消息:设定AI的行为和角色
    [
        'role' => 'system',
        'content' => '你是一位专业的PHP开发工程师,擅长解答PHP相关问题。'
    ],
    
    // 用户消息:用户的输入
    [
        'role' => 'user',
        'content' => 'PHP中的数组有哪些常用操作?'
    ],
    
    // 助手消息:AI的回复(用于多轮对话历史)
    [
        'role' => 'assistant',
        'content' => 'PHP数组常用操作包括:创建、遍历、排序、合并等...'
    ],
    
    // 用户继续提问
    [
        'role' => 'user',
        'content' => '能详细讲一下数组排序吗?'
    ],
];

高级参数配置

完整参数示例

php
<?php
class OpenAIClient
{
    // ... 前面的代码 ...

    public function chatAdvanced(
        array $messages,
        string $model = 'gpt-4o-mini',
        array $options = []
    ): array {
        $params = [
            'model' => $model,
            'messages' => $messages,
        ];

        // 温度:控制输出随机性,0-2,默认1
        if (isset($options['temperature'])) {
            $params['temperature'] = $options['temperature'];
        }

        // Top P:核采样参数,0-1
        if (isset($options['top_p'])) {
            $params['top_p'] = $options['top_p'];
        }

        // 最大Token数
        if (isset($options['max_tokens'])) {
            $params['max_tokens'] = $options['max_tokens'];
        }

        // 停止词
        if (isset($options['stop'])) {
            $params['stop'] = $options['stop'];
        }

        // 频率惩罚:降低重复内容,0-2
        if (isset($options['frequency_penalty'])) {
            $params['frequency_penalty'] = $options['frequency_penalty'];
        }

        // 存在惩罚:鼓励新话题,0-2
        if (isset($options['presence_penalty'])) {
            $params['presence_penalty'] = $options['presence_penalty'];
        }

        try {
            $response = $this->client->post('/chat/completions', [
                'json' => $params,
            ]);

            return json_decode($response->getBody(), true);
        } catch (RequestException $e) {
            $errorBody = $e->getResponse() ? $e->getResponse()->getBody()->getContents() : 'Unknown error';
            throw new Exception('OpenAI API Error: ' . $errorBody);
        }
    }
}

// 使用示例
$client = new OpenAIClient($apiKey);

$result = $client->chatAdvanced(
    [['role' => 'user', 'content' => '写一首关于程序员的诗']],
    'gpt-4o-mini',
    [
        'temperature' => 0.8,      // 较高温度,更有创意
        'max_tokens' => 500,       // 限制输出长度
        'frequency_penalty' => 0.5, // 减少重复
    ]
);

echo $result['choices'][0]['message']['content'];

参数详解

参数范围默认值说明
temperature0-21控制随机性,0最确定,2最随机
top_p0-11核采样,与temperature二选一
max_tokens1-模型上限无限制最大生成Token数
stop字符串或数组遇到停止词时终止生成
frequency_penalty0-20降低高频词出现概率
presence_penalty0-20鼓励谈论新话题

流式响应处理

实现流式输出

php
<?php
class OpenAIClient
{
    // ... 前面的代码 ...

    public function chatStream(array $messages, string $model = 'gpt-4o-mini'): Generator
    {
        $response = $this->client->post('/chat/completions', [
            'json' => [
                'model' => $model,
                'messages' => $messages,
                'stream' => true,
            ],
            'stream' => true,
        ]);

        $body = $response->getBody();
        $buffer = '';

        while (!$body->eof()) {
            $chunk = $body->read(1024);
            $buffer .= $chunk;

            while (($pos = strpos($buffer, "\n")) !== false) {
                $line = substr($buffer, 0, $pos);
                $buffer = substr($buffer, $pos + 1);

                $line = trim($line);
                if (empty($line) || $line === 'data: [DONE]') {
                    continue;
                }

                if (strpos($line, 'data: ') === 0) {
                    $json = substr($line, 6);
                    $data = json_decode($json, true);

                    if (isset($data['choices'][0]['delta']['content'])) {
                        yield $data['choices'][0]['delta']['content'];
                    }
                }
            }
        }
    }
}

// 使用示例
$client = new OpenAIClient($apiKey);

echo "AI回复:";
foreach ($client->chatStream([['role' => 'user', 'content' => '讲一个简短的程序员笑话']]) as $chunk) {
    echo $chunk;
    flush();
}

运行结果:

AI回复:为什么程序员总是分不清万圣节和圣诞节?

因为 Oct 31 = Dec 25!

(解释:在编程中,Oct代表八进制,Dec代表十进制。八进制的31等于十进制的25。)

多轮对话实现

完整对话管理类

php
<?php
class ChatSession
{
    private OpenAIClient $client;
    private array $messages = [];
    private string $model;
    private int $maxHistory = 10;

    public function __construct(OpenAIClient $client, string $model = 'gpt-4o-mini')
    {
        $this->client = $client;
        $this->model = $model;
    }

    public function setSystemPrompt(string $prompt): void
    {
        $this->messages = [
            ['role' => 'system', 'content' => $prompt]
        ];
    }

    public function chat(string $userMessage): string
    {
        $this->messages[] = ['role' => 'user', 'content' => $userMessage];

        $response = $this->client->chat($this->messages, $this->model);
        $assistantMessage = $response['choices'][0]['message']['content'];

        $this->messages[] = ['role' => 'assistant', 'content' => $assistantMessage];

        $this->trimHistory();

        return $assistantMessage;
    }

    private function trimHistory(): void
    {
        if (count($this->messages) > $this->maxHistory * 2 + 1) {
            $systemMessage = $this->messages[0];
            $recentMessages = array_slice($this->messages, -($this->maxHistory * 2));
            $this->messages = array_merge([$systemMessage], $recentMessages);
        }
    }

    public function getHistory(): array
    {
        return $this->messages;
    }

    public function clearHistory(): void
    {
        $systemMessage = $this->messages[0] ?? null;
        $this->messages = $systemMessage ? [$systemMessage] : [];
    }
}

// 使用示例
$client = new OpenAIClient($apiKey);
$session = new ChatSession($client, 'gpt-4o-mini');
$session->setSystemPrompt('你是一位友好的AI助手,用简洁的语言回答问题。');

echo "用户:什么是MVC架构?\n";
echo "AI:" . $session->chat('什么是MVC架构?') . "\n\n";

echo "用户:它的优点是什么?\n";
echo "AI:" . $session->chat('它的优点是什么?') . "\n\n";

echo "用户:PHP有哪些MVC框架?\n";
echo "AI:" . $session->chat('PHP有哪些MVC框架?') . "\n";

运行结果:

用户:什么是MVC架构?
AI:MVC是一种软件设计模式,将应用分为三个核心部分:
- Model(模型):处理数据和业务逻辑
- View(视图):展示数据给用户
- Controller(控制器):处理用户请求,协调Model和View

用户:它的优点是什么?
AI:MVC架构的主要优点包括:
1. 关注点分离,代码更清晰
2. 便于团队协作开发
3. 易于测试和维护
4. 代码复用性高

用户:PHP有哪些MVC框架?
AI:主流的PHP MVC框架包括:
- Laravel:功能全面,生态丰富
- Symfony:企业级,组件化设计
- CodeIgniter:轻量级,易上手
- Yii:高性能,适合大型应用
- ThinkPHP:国产框架,中文文档完善

常见错误与踩坑点

错误1:API Key暴露

php
<?php
// ❌ 错误做法:硬编码API Key
$client = new OpenAIClient('sk-xxxxx');

// ✅ 正确做法:使用环境变量
$apiKey = getenv('OPENAI_API_KEY');
$client = new OpenAIClient($apiKey);

解决方案:始终使用环境变量或配置文件管理敏感信息,将.env添加到.gitignore

错误2:忽略错误处理

php
<?php
// ❌ 错误做法:不处理异常
$result = $client->chat($messages);
echo $result['choices'][0]['message']['content'];

// ✅ 正确做法:完善的错误处理
try {
    $result = $client->chat($messages);
    if (!isset($result['choices'][0]['message']['content'])) {
        throw new Exception('响应格式异常');
    }
    echo $result['choices'][0]['message']['content'];
} catch (Exception $e) {
    error_log('OpenAI API调用失败: ' . $e->getMessage());
    echo '抱歉,服务暂时不可用,请稍后重试。';
}

错误3:超出Token限制

php
<?php
// ❌ 错误做法:直接发送超长文本
$longText = file_get_contents('large_document.txt');
$messages = [['role' => 'user', 'content' => $longText]];
$result = $client->chat($messages);

// ✅ 正确做法:分块处理或使用长上下文模型
function splitText(string $text, int $maxTokens = 3000): array
{
    $chunks = [];
    $sentences = preg_split('/(?<=[。!?.!?])\s*/', $text);
    $currentChunk = '';
    
    foreach ($sentences as $sentence) {
        if (strlen($currentChunk . $sentence) < $maxTokens * 2) {
            $currentChunk .= $sentence;
        } else {
            if ($currentChunk) {
                $chunks[] = $currentChunk;
            }
            $currentChunk = $sentence;
        }
    }
    
    if ($currentChunk) {
        $chunks[] = $currentChunk;
    }
    
    return $chunks;
}

// 分块处理长文本
$chunks = splitText($longText);
foreach ($chunks as $chunk) {
    $result = $client->chat([['role' => 'user', 'content' => $chunk]]);
    // 处理每个块的结果
}

错误4:忽略速率限制

php
<?php
// ❌ 错误做法:快速连续请求
foreach ($questions as $question) {
    $result = $client->chat([['role' => 'user', 'content' => $question]]);
}

// ✅ 正确做法:添加重试和延迟机制
class RateLimitedClient extends OpenAIClient
{
    private int $lastRequestTime = 0;
    private int $minInterval = 100; // 最小请求间隔(毫秒)

    public function chatWithRateLimit(array $messages, string $model = 'gpt-4o-mini'): array
    {
        $now = (int)(microtime(true) * 1000);
        $elapsed = $now - $this->lastRequestTime;
        
        if ($elapsed < $this->minInterval) {
            usleep(($this->minInterval - $elapsed) * 1000);
        }

        $this->lastRequestTime = (int)(microtime(true) * 1000);
        
        return $this->chat($messages, $model);
    }
}

常见应用场景

场景1:智能客服机器人

php
<?php
class CustomerServiceBot
{
    private ChatSession $session;

    public function __construct(OpenAIClient $client)
    {
        $this->session = new ChatSession($client, 'gpt-4o-mini');
        $this->session->setSystemPrompt(<<<'PROMPT'
你是一个专业的客服机器人,请遵循以下规则:
1. 友好、专业地回答客户问题
2. 如果不确定答案,诚实告知并建议联系人工客服
3. 回答简洁明了,不超过200字
4. 使用礼貌用语
PROMPT);
    }

    public function handleQuery(string $query): string
    {
        return $this->session->chat($query);
    }
}

// 使用示例
$client = new OpenAIClient($apiKey);
$bot = new CustomerServiceBot($client);

echo "客户:我的订单什么时候能到?\n";
echo "客服:" . $bot->handleQuery('我的订单什么时候能到?') . "\n";

场景2:内容生成助手

php
<?php
class ContentGenerator
{
    private OpenAIClient $client;

    public function __construct(OpenAIClient $client)
    {
        $this->client = $client;
    }

    public function generateArticle(string $topic, string $style = '专业', int $wordCount = 500): string
    {
        $prompt = <<<PROMPT
请以{$style}的风格,写一篇关于"{$topic}"的文章。
要求:
1. 字数约{$wordCount}字
2. 结构清晰,分段明确
3. 内容准确,有实用价值
PROMPT;

        $result = $this->client->chatAdvanced(
            [['role' => 'user', 'content' => $prompt]],
            'gpt-4o-mini',
            ['max_tokens' => $wordCount * 2]
        );

        return $result['choices'][0]['message']['content'];
    }

    public function generateSummary(string $content, int $maxLength = 100): string
    {
        $prompt = "请将以下内容总结为不超过{$maxLength}字的摘要:\n\n{$content}";

        $result = $this->client->chat([['role' => 'user', 'content' => $prompt]]);
        return $result['choices'][0]['message']['content'];
    }
}

// 使用示例
$generator = new ContentGenerator($client);
$article = $generator->generateArticle('PHP 8新特性', '技术教程', 300);
echo $article;

场景3:代码助手

php
<?php
class CodeAssistant
{
    private OpenAIClient $client;

    public function __construct(OpenAIClient $client)
    {
        $this->client = $client;
    }

    public function explainCode(string $code): string
    {
        $prompt = "请解释以下PHP代码的功能和实现原理:\n\n```php\n{$code}\n```";
        $result = $this->client->chat([['role' => 'user', 'content' => $prompt]]);
        return $result['choices'][0]['message']['content'];
    }

    public function generateCode(string $description): string
    {
        $prompt = "请根据以下描述生成PHP代码,只输出代码,不要解释:\n\n{$description}";
        $result = $this->client->chat([['role' => 'user', 'content' => $prompt]]);
        return $result['choices'][0]['message']['content'];
    }

    public function reviewCode(string $code): array
    {
        $prompt = <<<PROMPT
请审查以下PHP代码,从以下维度给出建议:
1. 代码质量
2. 安全性
3. 性能
4. 可读性

代码:
```php
{$code}

请以JSON格式返回,格式如下: {"quality": "评价", "security": "评价", "performance": "评价", "readability": "评价", "suggestions": ["建议1", "建议2"]} PROMPT;

    $result = $this->client->chat([['role' => 'user', 'content' => $prompt]]);
    return json_decode($result['choices'][0]['message']['content'], true);
}

}


### 场景4:数据分析助手

```php
<?php
class DataAnalyzer
{
    private OpenAIClient $client;

    public function __construct(OpenAIClient $client)
    {
        $this->client = $client;
    }

    public function analyzeData(string $data, string $question): string
    {
        $prompt = <<<PROMPT
以下是数据内容:
{$data}

请回答问题:{$question}
PROMPT;

        $result = $this->client->chat([['role' => 'user', 'content' => $prompt]]);
        return $result['choices'][0]['message']['content'];
    }

    public function generateSQL(string $schema, string $query): string
    {
        $prompt = <<<PROMPT
数据库表结构:
{$schema}

请根据以下需求生成SQL查询语句:
{$query}

只输出SQL语句,不要解释。
PROMPT;

        $result = $this->client->chat([['role' => 'user', 'content' => $prompt]]);
        return $result['choices'][0]['message']['content'];
    }
}

场景5:翻译助手

php
<?php
class Translator
{
    private OpenAIClient $client;

    public function __construct(OpenAIClient $client)
    {
        $this->client = $client;
    }

    public function translate(string $text, string $from, string $to): string
    {
        $prompt = "请将以下{$from}文本翻译成{$to},保持原文的语气和风格:\n\n{$text}";
        $result = $this->client->chat([['role' => 'user', 'content' => $prompt]]);
        return $result['choices'][0]['message']['content'];
    }

    public function translateWithGlossary(string $text, string $from, string $to, array $glossary): string
    {
        $glossaryStr = '';
        foreach ($glossary as $term => $translation) {
            $glossaryStr .= "- {$term}: {$translation}\n";
        }

        $prompt = <<<PROMPT
请将以下{$from}文本翻译成{$to}。

术语表(请使用以下翻译):
{$glossaryStr}

原文:
{$text}
PROMPT;

        $result = $this->client->chat([['role' => 'user', 'content' => $prompt]]);
        return $result['choices'][0]['message']['content'];
    }
}

企业级进阶应用场景

场景1:构建RAG知识库问答系统

php
<?php
class RAGSystem
{
    private OpenAIClient $client;
    private array $knowledgeBase = [];

    public function __construct(OpenAIClient $client)
    {
        $this->client = $client;
    }

    public function addDocument(string $id, string $content): void
    {
        $this->knowledgeBase[$id] = [
            'content' => $content,
            'embedding' => $this->getEmbedding($content),
        ];
    }

    private function getEmbedding(string $text): array
    {
        $response = $this->client->client->post('/embeddings', [
            'json' => [
                'model' => 'text-embedding-ada-002',
                'input' => $text,
            ],
        ]);

        $result = json_decode($response->getBody(), true);
        return $result['data'][0]['embedding'];
    }

    private function cosineSimilarity(array $a, array $b): float
    {
        $dotProduct = 0;
        $normA = 0;
        $normB = 0;

        for ($i = 0; $i < count($a); $i++) {
            $dotProduct += $a[$i] * $b[$i];
            $normA += $a[$i] * $a[$i];
            $normB += $b[$i] * $b[$i];
        }

        return $dotProduct / (sqrt($normA) * sqrt($normB));
    }

    public function query(string $question, int $topK = 3): string
    {
        $questionEmbedding = $this->getEmbedding($question);
        
        $similarities = [];
        foreach ($this->knowledgeBase as $id => $doc) {
            $similarity = $this->cosineSimilarity($questionEmbedding, $doc['embedding']);
            $similarities[$id] = $similarity;
        }

        arsort($similarities);
        $topDocs = array_slice($similarities, 0, $topK, true);

        $context = '';
        foreach ($topDocs as $id => $score) {
            $context .= $this->knowledgeBase[$id]['content'] . "\n\n";
        }

        $prompt = <<<PROMPT
基于以下参考资料回答问题。如果参考资料中没有相关信息,请诚实说明。

参考资料:
{$context}

问题:{$question}

请给出准确、详细的回答:
PROMPT;

        $result = $this->client->chat([['role' => 'user', 'content' => $prompt]]);
        return $result['choices'][0]['message']['content'];
    }
}

场景2:构建多Agent协作系统

php
<?php
class MultiAgentSystem
{
    private OpenAIClient $client;
    private array $agents = [];

    public function __construct(OpenAIClient $client)
    {
        $this->client = $client;
        $this->initAgents();
    }

    private function initAgents(): void
    {
        $this->agents = [
            'researcher' => [
                'role' => '研究员',
                'prompt' => '你是一个专业的研究员,负责收集和整理信息。请客观、全面地分析问题。',
            ],
            'writer' => [
                'role' => '撰写员',
                'prompt' => '你是一个专业的撰写员,负责将信息整理成清晰、有逻辑的内容。',
            ],
            'reviewer' => [
                'role' => '审核员',
                'prompt' => '你是一个专业的审核员,负责检查内容的准确性、逻辑性和完整性。',
            ],
        ];
    }

    private function runAgent(string $agentKey, string $task): string
    {
        $agent = $this->agents[$agentKey];
        $messages = [
            ['role' => 'system', 'content' => $agent['prompt']],
            ['role' => 'user', 'content' => $task],
        ];

        $result = $this->client->chat($messages);
        return $result['choices'][0]['message']['content'];
    }

    public function processTask(string $task): array
    {
        $results = [];

        // Step 1: 研究员收集信息
        $results['research'] = $this->runAgent('researcher', "请研究以下主题并收集关键信息:\n{$task}");

        // Step 2: 撰写员整理内容
        $results['draft'] = $this->runAgent('writer', "基于以下研究结果,撰写一篇结构清晰的内容:\n{$results['research']}");

        // Step 3: 审核员检查内容
        $results['review'] = $this->runAgent('reviewer', "请审核以下内容,指出需要改进的地方:\n{$results['draft']}");

        // Step 4: 根据审核意见修改
        $results['final'] = $this->runAgent('writer', "请根据以下审核意见修改内容:\n\n原文:\n{$results['draft']}\n\n审核意见:\n{$results['review']}");

        return $results;
    }
}

行业最佳实践

实践1:使用异步处理提升性能

php
<?php
// 使用PHP的异步特性处理批量请求
class AsyncOpenAIClient
{
    private $client;
    private $apiKey;

    public function __construct(string $apiKey)
    {
        $this->apiKey = $apiKey;
        $this->client = new Client([
            'base_uri' => 'https://api.openai.com/v1',
            'timeout' => 60,
        ]);
    }

    public function batchChat(array $prompts): array
    {
        $promises = [];

        foreach ($prompts as $key => $prompt) {
            $promises[$key] = $this->client->postAsync('/chat/completions', [
                'headers' => [
                    'Authorization' => 'Bearer ' . $this->apiKey,
                    'Content-Type' => 'application/json',
                ],
                'json' => [
                    'model' => 'gpt-4o-mini',
                    'messages' => [['role' => 'user', 'content' => $prompt]],
                ],
            ]);
        }

        $results = [];
        $responses = \GuzzleHttp\Promise\Utils::settle($promises)->wait();

        foreach ($responses as $key => $response) {
            if ($response['state'] === 'fulfilled') {
                $body = json_decode($response['value']->getBody(), true);
                $results[$key] = $body['choices'][0]['message']['content'];
            } else {
                $results[$key] = 'Error: ' . $response['reason']->getMessage();
            }
        }

        return $results;
    }
}

实践2:实现缓存机制降低成本

php
<?php
class CachedOpenAIClient
{
    private OpenAIClient $client;
    private string $cacheDir;
    private int $cacheTTL = 3600;

    public function __construct(OpenAIClient $client, string $cacheDir = '/tmp/openai_cache')
    {
        $this->client = $client;
        $this->cacheDir = $cacheDir;
        if (!is_dir($cacheDir)) {
            mkdir($cacheDir, 0755, true);
        }
    }

    private function getCacheKey(array $messages, string $model): string
    {
        return md5($model . serialize($messages));
    }

    public function chatWithCache(array $messages, string $model = 'gpt-4o-mini'): array
    {
        $cacheKey = $this->getCacheKey($messages, $model);
        $cacheFile = $this->cacheDir . '/' . $cacheKey . '.json';

        if (file_exists($cacheFile)) {
            $cache = json_decode(file_get_contents($cacheFile), true);
            if (time() - $cache['timestamp'] < $this->cacheTTL) {
                return $cache['data'];
            }
        }

        $result = $this->client->chat($messages, $model);

        file_put_contents($cacheFile, json_encode([
            'timestamp' => time(),
            'data' => $result,
        ]));

        return $result;
    }
}

实践3:完善的日志记录

php
<?php
class LoggedOpenAIClient
{
    private OpenAIClient $client;
    private string $logFile;

    public function __construct(OpenAIClient $client, string $logFile = '/var/log/openai.log')
    {
        $this->client = $client;
        $this->logFile = $logFile;
    }

    private function log(array $data): void
    {
        $logEntry = json_encode([
            'timestamp' => date('Y-m-d H:i:s'),
            'data' => $data,
        ]) . "\n";

        file_put_contents($this->logFile, $logEntry, FILE_APPEND);
    }

    public function chat(array $messages, string $model = 'gpt-4o-mini'): array
    {
        $startTime = microtime(true);

        try {
            $result = $this->client->chat($messages, $model);

            $this->log([
                'type' => 'success',
                'model' => $model,
                'input_tokens' => $result['usage']['prompt_tokens'] ?? 0,
                'output_tokens' => $result['usage']['completion_tokens'] ?? 0,
                'duration_ms' => round((microtime(true) - $startTime) * 1000, 2),
            ]);

            return $result;
        } catch (Exception $e) {
            $this->log([
                'type' => 'error',
                'model' => $model,
                'error' => $e->getMessage(),
                'duration_ms' => round((microtime(true) - $startTime) * 1000, 2),
            ]);

            throw $e;
        }
    }
}

常见问题答疑(FAQ)

Q1:如何选择合适的模型?

回答:根据任务需求和预算选择:

场景推荐模型原因
简单对话、快速响应gpt-4o-mini成本低,速度快
复杂推理、代码生成gpt-4o能力强,准确度高
长文本处理gpt-4-turbo128K上下文
图像理解gpt-4o支持多模态

Q2:如何降低API调用成本?

回答

php
<?php
// 1. 使用更便宜的模型
$model = 'gpt-4o-mini'; // 比gpt-4便宜很多

// 2. 限制输出长度
$params['max_tokens'] = 500;

// 3. 使用缓存
$cachedClient = new CachedOpenAIClient($client);

// 4. 优化Prompt,减少Token消耗
$prompt = "用50字总结以下内容:{$text}"; // 明确长度要求

// 5. 批量处理减少请求次数
$results = $asyncClient->batchChat($prompts);

Q3:如何处理API超时问题?

回答

php
<?php
class RetryOpenAIClient
{
    private OpenAIClient $client;
    private int $maxRetries = 3;
    private int $retryDelay = 1000;

    public function chatWithRetry(array $messages, string $model = 'gpt-4o-mini'): array
    {
        $lastException = null;

        for ($i = 0; $i < $this->maxRetries; $i++) {
            try {
                return $this->client->chat($messages, $model);
            } catch (Exception $e) {
                $lastException = $e;
                if ($i < $this->maxRetries - 1) {
                    usleep($this->retryDelay * 1000 * ($i + 1));
                }
            }
        }

        throw $lastException;
    }
}

Q4:如何实现多语言支持?

回答

php
<?php
class MultilingualClient
{
    private OpenAIClient $client;

    public function chat(string $message, string $language = '中文'): string
    {
        $systemPrompt = "你是一个多语言助手。请用{$language}回答用户的问题。";

        $result = $this->client->chat([
            ['role' => 'system', 'content' => $systemPrompt],
            ['role' => 'user', 'content' => $message],
        ]);

        return $result['choices'][0]['message']['content'];
    }
}

Q5:如何保护API Key安全?

回答

php
<?php
// 1. 使用环境变量
$apiKey = getenv('OPENAI_API_KEY');

// 2. 使用加密存储
function encryptApiKey(string $key, string $secret): string
{
    return sodium_crypto_secretbox($key, $nonce, $secret);
}

// 3. 使用代理服务器
class ProxyClient
{
    private $proxyUrl = 'https://your-proxy.com/openai';

    public function chat(array $messages): array
    {
        // 请求代理服务器,API Key存储在代理服务器
        $response = $this->client->post($this->proxyUrl, [
            'json' => ['messages' => $messages],
        ]);
        return json_decode($response->getBody(), true);
    }
}

Q6:如何处理敏感内容?

回答

php
<?php
class ContentFilter
{
    private OpenAIClient $client;

    public function filterSensitiveInfo(string $text): string
    {
        // 移除可能的敏感信息
        $patterns = [
            '/\b\d{16,19}\b/' => '[CARD_NUMBER]',
            '/\b\d{17,18}[Xx\d]\b/' => '[ID_NUMBER]',
            '/\b[\w.-]+@[\w.-]+\.\w+\b/' => '[EMAIL]',
            '/\b1[3-9]\d{9}\b/' => '[PHONE]',
        ];

        foreach ($patterns as $pattern => $replacement) {
            $text = preg_replace($pattern, $replacement, $text);
        }

        return $text;
    }

    public function chatSafely(string $message): string
    {
        $filteredMessage = $this->filterSensitiveInfo($message);
        $result = $this->client->chat([['role' => 'user', 'content' => $filteredMessage]]);
        return $result['choices'][0]['message']['content'];
    }
}

实战练习

基础练习

练习1:编写一个简单的聊天程序,实现与AI的基本对话功能。

解题思路

  1. 创建OpenAI客户端类
  2. 实现消息发送和接收
  3. 处理响应结果

参考代码

php
<?php
require 'vendor/autoload.php';

$apiKey = getenv('OPENAI_API_KEY');
$client = new OpenAIClient($apiKey);

echo "欢迎使用AI聊天助手!(输入 'quit' 退出)\n";

while (true) {
    echo "\n你: ";
    $input = trim(fgets(STDIN));

    if ($input === 'quit') {
        echo "再见!\n";
        break;
    }

    $result = $client->chat([['role' => 'user', 'content' => $input]]);
    echo "AI: " . $result['choices'][0]['message']['content'] . "\n";
}

进阶练习

练习2:实现一个文档摘要工具,支持上传长文档并生成摘要。

解题思路

  1. 实现文档分块处理
  2. 对每个块生成摘要
  3. 合并所有摘要生成最终摘要

参考代码

php
<?php
class DocumentSummarizer
{
    private OpenAIClient $client;

    public function summarize(string $document, int $maxLength = 500): string
    {
        $chunks = $this->splitDocument($document, 2000);
        $summaries = [];

        foreach ($chunks as $chunk) {
            $result = $this->client->chat([
                ['role' => 'user', 'content' => "请用简洁的语言总结以下内容:\n\n{$chunk}"]
            ]);
            $summaries[] = $result['choices'][0]['message']['content'];
        }

        if (count($summaries) > 1) {
            $combined = implode("\n\n", $summaries);
            $result = $this->client->chat([
                ['role' => 'user', 'content' => "请将以下摘要整合成一个连贯的总结,不超过{$maxLength}字:\n\n{$combined}"]
            ]);
            return $result['choices'][0]['message']['content'];
        }

        return $summaries[0];
    }

    private function splitDocument(string $text, int $chunkSize): array
    {
        return array_filter(array_map('trim', str_split($text, $chunkSize)));
    }
}

挑战练习

练习3:构建一个智能代码审查系统,能够分析代码质量、安全性和性能问题。

解题思路

  1. 设计多维度审查Prompt
  2. 解析AI返回的结构化结果
  3. 生成详细的审查报告

参考代码

php
<?php
class CodeReviewer
{
    private OpenAIClient $client;

    public function review(string $code, string $language = 'PHP'): array
    {
        $prompt = <<<PROMPT
你是一位资深的{$language}代码审查专家。请从以下维度审查代码:

1. 代码质量(命名规范、代码结构、可读性)
2. 安全性(SQL注入、XSS、敏感信息泄露等)
3. 性能(时间复杂度、内存使用、数据库查询优化)
4. 最佳实践(设计模式、SOLID原则、错误处理)

代码:
```{$language}
{$code}

请以JSON格式返回审查结果: { "quality": {"score": 1-10, "issues": [], "suggestions": []}, "security": {"score": 1-10, "issues": [], "suggestions": []}, "performance": {"score": 1-10, "issues": [], "suggestions": []}, "best_practices": {"score": 1-10, "issues": [], "suggestions": []}, "overall_score": 1-10, "summary": "总体评价" } PROMPT;

    $result = $this->client->chat([['role' => 'user', 'content' => $prompt]]);
    return json_decode($result['choices'][0]['message']['content'], true);
}

public function generateReport(array $review): string
{
    $report = "=== 代码审查报告 ===\n\n";
    $report .= "总体评分:{$review['overall_score']}/10\n\n";
    $report .= "总体评价:{$review['summary']}\n\n";

    $dimensions = ['quality' => '代码质量', 'security' => '安全性', 'performance' => '性能', 'best_practices' => '最佳实践'];

    foreach ($dimensions as $key => $label) {
        $data = $review[$key];
        $report .= "### {$label} ({$data['score']}/10)\n";

        if (!empty($data['issues'])) {
            $report .= "问题:\n";
            foreach ($data['issues'] as $issue) {
                $report .= "- {$issue}\n";
            }
        }

        if (!empty($data['suggestions'])) {
            $report .= "建议:\n";
            foreach ($data['suggestions'] as $suggestion) {
                $report .= "- {$suggestion}\n";
            }
        }
        $report .= "\n";
    }

    return $report;
}

}


---

## 知识点总结

### 核心要点

1. **API基础**:理解Token、上下文窗口、API Key等核心概念
2. **请求构建**:掌握消息格式、参数配置、流式响应
3. **错误处理**:完善的异常处理和重试机制
4. **成本优化**:模型选择、缓存策略、Token优化
5. **安全实践**:API Key保护、敏感信息过滤

### 易错点回顾

| 易错点 | 正确做法 |
|--------|---------|
| API Key硬编码 | 使用环境变量 |
| 忽略错误处理 | try-catch + 重试机制 |
| 超出Token限制 | 分块处理或使用长上下文模型 |
| 忽略速率限制 | 添加请求间隔和重试逻辑 |
| 不做缓存 | 实现缓存机制降低成本 |

---

## 拓展参考资料

### 官方文档

- [OpenAI API文档](https://platform.openai.com/docs)
- [OpenAI Cookbook](https://github.com/openai/openai-cookbook)
- [OpenAI Models](https://platform.openai.com/docs/models)

### 进阶学习路径

1. **本知识点** → OpenAI API基础使用
2. **下一步** → [Anthropic Claude API](/ai/llm-tools/claude)
3. **进阶** → [错误处理与重试](/ai/llm-tools/error-handling)
4. **高级** → [流式响应处理](/ai/llm-tools/streaming)

---

> 💡 **记住**:OpenAI API是AI应用开发的基础,掌握它将为你打开AI应用开发的大门。多实践、多总结,你会发现更多可能性。