楼主
主要是php端没什么我很喜欢的api请求器,所以我做了这个。
然后,在这里,所有数据结构都是开放的array,让你可以用php的array生态管理上下文。
请求了之后需要你主动把消息塞到上下文,非常自由开放。
演示请求代码:
$chat = DeepSeekChat::getInstance();
$systemMessage = $chat->createMessage('', 0, '你是一个有帮助的AI助手');
$chat->messages[] = $systemMessage;
$toolDefinition = $chat->registerFunction(
function ($params) {
return "查询结果:php无需学习";
},
'search',
'搜索函数,用于查询信息',
[
'type' => 'object',
'properties' => [
'query' => ['type' => 'string', 'description' => '搜索关键词']
],
'required' => ['query']
]
);
$chat->tools[] = $toolDefinition;
$userMessage = $chat->createMessage('user1', 1, "帮我搜索'PHP是否需要学习'");
$chat->messages[] = $userMessage;
for (;;) {
$response = $chat->requestDeepSeek(
'cs-sk-ecfeb2a3-6721-422a-a313-935173adce2c',
'http://192.168.1.20:55566/v1/chat/completions',
'zhipu:glm-5',
0.7
);
$chat->messages[] = $response['message'];
if ($response['called']) {
echo "DS调用了函数,结果:" . json_encode($response, JSON_UNESCAPED_UNICODE) . "\n";
$chat->messages[] = $chat->createMessage('tool_return', 1, $response["result"]);
} else {
echo "AI回复: " . $response['message']['content'] . "\n";
break;
}
}驱动代码:
<?php
class DeepSeekChat
{
public $messages = [];
public $tools = [];
public $functions = [];
private static $instance = null;
private function __construct() {}
public static function getInstance()
{
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
/**
* 注册一个可以被DS调用的函数(如果函数名已存在,则覆盖旧的)
* @param callable $function 被调用的函数
* @param string $name 函数名称
* @param string $description 函数描述
* @param array $parameters 参数定义
* @return array 返回完整的toolDefinition
*/
public function registerFunction($function, $name, $description, $parameters)
{
$toolDefinition = [
"type" => "function",
"function" => [
"name" => $name,
"description" => $description,
"parameters" => $parameters
]
];
$this->functions[$name] = [
'function' => $function,
'definition' => $toolDefinition
];
return $toolDefinition;
}
/**
* 创建一条消息(不自动添加到messages)
* @param string $name 消息名称
* @param int $roleType 0=system, 1=user, 2=assistant
* @param string|array $content 消息内容(字符串或带图片的多模态数组)
* @param array $toolCalls 可选的tool_calls数组
* @param array $images 图片数组,格式 [["bin"=>"二进制数据", "mime"=>"image/png"], ...]
* @return array 返回message数组
*/
public function createMessage($name, $roleType, $content, $toolCalls = [], $images = [])
{
$roles = ['system', 'user', 'assistant'];
$finalContent = $content;
if (!empty($images)) {
$finalContent = [];
if (!empty($content)) {
$finalContent[] = [
'type' => 'text',
'text' => $content
];
}
foreach ($images as $image) {
$base64Data = base64_encode($image['bin']);
$finalContent[] = [
'type' => 'image_url',
'image_url' => [
'url' => 'data:' . $image['mime'] . ';base64,' . $base64Data
]
];
}
}
$message = [
'role' => $roles[$roleType],
'content' => $finalContent
];
if (!empty($name)) {
$message['name'] = $name;
}
if (!empty($toolCalls)) {
$message['tool_calls'] = $toolCalls;
}
return $message;
}
/**
* 请求DS API
* @param string $apiKey API密钥
* @param string $apiUrl API地址
* @param string $model 模型名称
* @param float $temperature 温度参数,默认0.9
* @return array 返回 ["message" => 消息数组, "called" => bool, "result" => toolcall结果]
* @throws Exception
*/
public function requestDeepSeek($apiKey, $apiUrl, $model = 'qwen/qwen3-next-80b', $temperature = 0.9)
{
$response = $this->makeApiRequest($apiKey, $apiUrl, $model, $temperature);
if ($response && isset($response['choices'][0]['message'])) {
$assistantMessage = $response['choices'][0]['message'];
$called = false;
$result = null;
if (isset($assistantMessage['tool_calls']) && !empty($assistantMessage['tool_calls'])) {
$called = true;
$results = [];
foreach ($assistantMessage['tool_calls'] as $toolCall) {
$functionName = $toolCall['function']['name'];
$arguments = json_decode($toolCall['function']['arguments'], true);
if (isset($this->functions[$functionName])) {
$registered = $this->functions[$functionName];
$functionResult = call_user_func($registered['function'], $arguments);
$results[] = $functionResult;
}
}
$result = $results;
}
// 处理think标签(仅当content为字符串时)
if (isset($assistantMessage['content']) && is_string($assistantMessage['content'])) {
$content = $assistantMessage['content'];
if (strpos($content, "</think>") !== false) {
$content = explode("</think>", $content);
array_shift($content);
$content = implode("", $content);
$assistantMessage['content'] = $content;
}
}
return [
'message' => $assistantMessage,
'called' => $called,
'result' => $result
];
}
throw new Exception('API请求失败: ' . ($response['error']['message'] ?? '未知错误'));
}
public function getMessages()
{
return $this->messages;
}
public function clearMessages()
{
$systemMessage = [];
if (!empty($this->messages) && $this->messages[0]['role'] === 'system') {
$systemMessage = [$this->messages[0]];
}
$this->messages = $systemMessage;
return $this;
}
private function makeApiRequest($apiKey, $apiUrl, $model, $temperature)
{
$data = [
'model' => $model,
'messages' => $this->messages,
'temperature' => $temperature,
'stream' => false
];
if (!empty($this->tools)) {
$data['tools'] = $this->tools;
}
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $apiUrl,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Authorization: Bearer ' . $apiKey
],
CURLOPT_TIMEOUT => 300
]);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($error) {
throw new Exception('cURL错误: ' . $error);
}
if ($httpCode !== 200) {
throw new Exception('HTTP错误代码: ' . $httpCode . " $response");
}
return json_decode($response, true);
}
private function __clone() {}
private function __wakeup() {}
}更多演示:
$chat = DeepSeekChat::getInstance();
$systemMessage = $chat->createMessage('', 0, '你是一个有帮助的AI助手');
$chat->messages[] = $systemMessage;
$toolDefinition = $chat->registerFunction(
function ($params) {
try{
$a=eval($params["phpcode"]);
}catch (Throwable $e){
$a = "Error: " . $e->getMessage();
}
return $a;
},
'phpeval',
'运行php代码',
[
'type' => 'object',
'properties' => [
'phpcode' => ['type' => 'string', 'description' => 'php代码,使用return获取输出。']
],
'required' => ['phpcode']
]
);
$chat->tools[] = $toolDefinition;
$userMessage = $chat->createMessage('user1', 1, "你是使用php连接的,帮我查查你的环境,例如使用什么东西连接你、电脑环境。查看用于连接你的代码。如果你觉得没调查清楚,请调用函数调查,否则不要调用函数,调查结束。'");
$chat->messages[] = $userMessage;
for (;;) {
//echo json_encode($chat->messages, JSON_UNESCAPED_UNICODE)."\n".json_encode($chat->tools, JSON_UNESCAPED_UNICODE)."\n";
$response = $chat->requestDeepSeek(
'cs-sk-ecfeb2a3-6721-422a-a313-935173adce2c',
'http://192.168.1.20:55566/v1/chat/completions',
'zhipu:glm-5',
0.7
);
$chat->messages[] = $response['message'];
if ($response['called']) {
echo "DS调用了函数:" . $response['message']['content'] . "\n";;
$chat->messages[] = $chat->createMessage('tool_return', 1, json_encode($response["result"], JSON_UNESCAPED_UNICODE));
} else {
echo "AI回复: " . $response['message']['content'] . "\n";
break;
}
}$chat = DeepSeekChat::getInstance();
$systemMessage = $chat->createMessage('', 0, '你是一个有帮助的AI助手,可以识别图片内容');
$chat->messages[] = $systemMessage;
$imageData = file_get_contents('C:\Users\nint\Desktop\新建文件夹\W (19).jpg');
$userMessage = $chat->createMessage(
'user1',
1,
'请描述这张图片的内容',
[],
[['bin' => $imageData, 'mime' => 'image/jpeg']]
);
$chat->messages[] = $userMessage;
$response = $chat->requestDeepSeek(
'cs-sk-ecfeb2a3-6721-422a-a313-935173adce2c',
'http://192.168.1.20:55566/v1/chat/completions',
'zhipu:glm-5v-turbo',
0.7
);
echo "AI回复: " . $response['message']['content'] . "\n";