PHP调用DeepSeek API实现流式对话与记录保存指南
本文将深入探讨如何利用PHP语言结合cURL扩展,实现对DeepSeek大模型API的高效调用。内容涵盖环境配置、面向对象代码架构设计、流式响应(SSE)的处理逻辑,以及对话记录的本地持久化保存方法。通过具体代码示例,展示如何配置模型参数、处理终端交互并进行异常捕获,为开发者提供一套完整的可运行解决方案。
实现原理与环境准备
要实现PHP与DeepSeek API的无缝对接,核心在于构建HTTP请求并使用cURL库处理数据流。由于大模型通常采用服务器发送事件(SSE)机制返回结果,PHP脚本需要实时读取分块数据进行解析和渲染。
系统基础要求
- PHP版本:建议使用7.0或更高版本,确保支持现代异步I/O特性及JSON处理函数。
- cURL扩展:必须在php.ini中启用curl扩展,用于发起POST请求和处理底层网络传输。
- 文件系统权限:执行脚本的用户需具备在当前工作目录创建和追加写入文本文件的权限。
项目结构规划
为方便维护,建议采用清晰的目录结构。主要包含一个主入口文件和一个日志存储文件:
deepseek-project/
├── main.php # 包含类定义与逻辑的主程序
└── conversation.txt # 自动生成的对话历史存档
核心代码实现详解
以下是一个封装良好的面向对象示例。该类负责管理API密钥、组装JSON请求体、处理流式数据流以及将对话落盘保存。
完整代码结构
<?php
class DeepSeekChat {
// 使用SiliconFlow兼容接口路径
private $url = 'https://api.siliconflow.cn/v1/chat/completions';
private $apiKey = 'YOUR_API_KEY'; // 替换为你的实际 Key
private $logFile = 'conversation.txt';
public function __construct() {
// 初始化检查日志文件是否存在,若不存在则创建空文件
if (!file_exists($this->logFile)) {
touch($this->logFile);
}
}
// 私有方法:负责格式化并追加写入文件
private function saveToFile($content, $isQuestion = false) {
$timestamp = date('Y-m-d H:i:s');
if ($isQuestion) {
// 用户提问格式
$text = "\n[$timestamp] Question:\n$content\n\n[$timestamp] Answer:\n";
} else {
// AI回答直接追加
$text = $content;
}
file_put_contents($this->logFile, $text, FILE_APPEND);
}
// 私有方法:解析流式响应数据块
private function processStreamingResponse($handle) {
$buffer = '';
// 逐块读取直到数据结束
while (!feof($handle)) {
$chunk = fread($handle, 1024);
$buffer .= $chunk;
// 按行分割处理
while (($pos = strpos($buffer, "\n")) !== false) {
$line = substr($buffer, 0, $pos);
$buffer = substr($buffer, $pos + 1);
if (strlen(trim($line)) > 0) {
// SSE数据以data:开头
if (strpos($line, 'data: ') === 0) {
$data = substr($line, 6); // 去掉前缀
if ($data === '[DONE]') continue;
$json = json_decode($data, true);
// 提取delta content字段进行输出
if ($json && isset($json['choices'][0]['delta']['content'])) {
$content = $json['choices'][0]['delta']['content'];
echo $content;
flush(); // 强制刷新输出缓冲区
$this->saveToFile($content); // 实时保存片段
}
}
}
}
}
}
public function chat() {
while (true) {
echo "\n请输入您的问题 (输入 q 退出): ";
$question = trim(fgets(STDIN));
if ($question === 'q') {
echo "程序已退出\n";
break;
}
// 保存用户问题
$this->saveToFile($question, true);
// 构建符合OpenAI标准的请求JSON
$data = [
'model' => 'deepseek-ai/DeepSeek-V3',
'messages' => [
[
'role' => 'user',
'content' => $question
]
],
'stream' => true,
'max_tokens' => 2048,
'temperature' => 0.7,
'top_p' => 0.7,
'top_k' => 50,
'frequency_penalty' => 0.5,
'response_format' => [
'type' => 'text'
]
];
// 初始化cURL会话
$ch = curl_init($this->url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_RETURNTRANSFER => true, // 此处设为true配合手动处理回调
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Authorization: Bearer ' . $this->apiKey
],
// 注意:若要实时接收数据,CURLOPT_WRITEFUNCTION可能更灵活
// 但上述processStreamingResponse依赖句柄,此处为了兼容性调整写法:
// 在实际生产环境中,建议使用CURLOPT_WRITEFUNCTION直接回调,
// 或者将下面改为CURLOPT_RETURNTRANSFER=false配合读取。
// *修正*:为了匹配上方processStreamingResponse的逻辑,这里应关闭ReturnTransfer
]);
// 修正点:开启返回原始数据流以便read
curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
try {
// 执行请求
$handle = curl_exec($ch);
if (curl_errno($ch)) {
throw new Exception(curl_error($ch));
}
echo "\n----------------------------------------\n";
$this->saveToFile("\n----------------------------------------\n");
} catch (Exception $e) {
$error_msg = "请求发生错误: " . $e->getMessage() . "\n";
echo $error_msg;
$this->saveToFile($error_msg);
} finally {
curl_close($ch);
}
}
}
}
// 实例化并启动
$chatbot = new DeepSeekChat();
$chatbot->chat();
关键功能模块解析
对话记录持久化
利用saveToFile方法,我们实现了自动归档。该方法会根据传入的$isQuestion标志位,智能判断当前内容是“提问”还是“回答”。若是提问,则写入带有时间戳的头部标签;若是回答,则直接拼接至上一问之后。这确保了conversation.txt具有良好的可读性。
流式响应处理机制
SSE协议的数据是源源不断到达的。代码中的processStreamingResponse采用了缓冲区策略:
1. 每次从cURL句柄读取固定大小的字节块。
2. 在缓冲区中寻找换行符\n作为分隔线。
3. 识别以data: 开头的行,截取JSON负载。
4. 如果收到[DONE]标记,则终止解析循环。
API参数配置说明
- model:指定调用的大模型ID,如
deepseek-ai/DeepSeek-V3。 - stream:必须设置为
true才能触发流式返回模式。 - temperature:控制生成内容的创造性,值越大越随机。此处设为0.7。
- max_tokens:限制单次生成的最大Token数,防止响应过长截断,这里设为2048。
部署与使用方法
第1步:获取并配置API密钥
访问硅基流动(SiliconFlow)或其他支持DeepSeek模型的API提供商控制台,申请有效的API Key。将代码中的'YOUR_API_KEY'替换为你真实的密钥字符串。
第2步:环境验证
确保服务器终端可访问外部域名。运行以下命令测试连接性:
php -r "echo (new Curl_Curl()->setOpt(CURLOPT_URL, 'https://api.siliconflow.cn/v1/chat/completions')->execute()) ? 'Connected' : 'Failed';"
第3步:运行脚本
在命令行中进入项目目录,执行:
php main.php
进入交互模式后,直接键入中文或英文指令即可开始对话。输入q并回车退出程序。
常见错误排查与优化
权限与网络连接
如果出现Permission denied错误,请检查conversation.txt的归属权及写入权限(建议使用chmod修改)。若出现超时或连接拒绝,请检查防火墙是否放行了443端口出站流量。
内存管理与并发写入
对于高频调用的场景,频繁的文件IO操作可能会成为瓶颈:
- **文件锁**:建议在file_put_contents中加入LOCK_EX标志,防止多进程并发导致的文本覆盖。
- **数据库替代**:当历史记录达到数万条时,建议将SQLite或MySQL接入取代纯文本文件,以提升检索效率。
异常捕获增强
除了基础的curl_errno检测,实际生产中还应增加对HTTP状态码的判断(非200时的解析),并对JSON解析失败的情况做兜底处理,避免程序意外中断。
总结
通过本指南,您可以掌握利用PHP原生cURL库对接DeepSeek大模型的核心技术。该方案不仅实现了实时的流式文字输出,还兼顾了对话历史的本地备份,非常适合用于个人助理、客服自动化脚本等内部工具开发。代码遵循面向对象规范,结构清晰,您可根据业务需求在此基础上扩展更多交互逻辑。
以上就是PHP调用DeepSeek API实现流式对话与记录保存的详细教程,更多关于PHP AI应用开发的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









