← 返回聊天
新建
删除
Models
gpt5.php
gpt5_file.php
gpt5_mini_file.php
openai_chat.php
Tools
get_time.php
get_weather.php
global_search_messages.php
math.php
memo.php
news.php
search_arxiv.php
search_crossref.php
search_github_code.php
search_pubmed.php
search_semantic_scholar.php
stock_market.php
url.php
<?php declare(strict_types=1); /** * OpenAI 兼容:Chat Completions(tools/tool_calls) * * ✅ 你可以把这个文件复制成多个模型文件,例如: * - openai_fast.php(低 max_tokens) * - openai_deep.php(高 max_tokens / 更详细 system_prompt) * - 也可以改 base_url 指向你自己的 OpenAI 兼容服务(vLLM / one-api / 等) * * 你主要需要改:$BASE_URL / $API_KEY / $MODEL_NAME / 默认参数 */ $BASE_URL = 'https://api.openai.com/v1'; $API_KEY = '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'; $MODEL_NAME = 'gpt-4o-mini-2024-07-18'; // 默认参数(你可以根据“努力程度/详细程度”在这里做逻辑调度) $DEFAULTS = [ 'temperature' => 0.2, 'max_tokens' => 1024, ]; return [ 'id' => 'openai_chat', 'label' => 'gpt-4o-mini-示例', 'supports_tools' => true, /** * @param array $messages OpenAI messages 数组 * @param array $tools OpenAI tools 数组(tool_schemas() 生成) * @param array $options 可选覆盖:model/temperature/max_tokens * @return array ['ok'=>bool, 'message'=>array, 'raw'=>array]|['ok'=>false,'error'=>string] */ 'call' => function(array $messages, array $tools = [], array $options = []) use ($BASE_URL, $API_KEY, $MODEL_NAME, $DEFAULTS): array { $endpoint = rtrim($BASE_URL, '/\\') . '/chat/completions'; $model = (string)($options['model'] ?? $MODEL_NAME); $temperature = $options['temperature'] ?? $DEFAULTS['temperature']; $maxTokens = $options['max_tokens'] ?? $DEFAULTS['max_tokens']; $payload = [ 'model' => $model, 'messages' => $messages, 'temperature' => $temperature, 'max_tokens' => $maxTokens, ]; if (!empty($tools)) { $payload['tools'] = $tools; $payload['tool_choice'] = 'auto'; } $headers = [ 'Content-Type: application/json', ]; if (trim($API_KEY) !== '') { $headers[] = 'Authorization: Bearer ' . $API_KEY; } $ch = curl_init($endpoint); if ($ch === false) { return ['ok' => false, 'error' => 'curl_init failed']; } $json = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => $headers, CURLOPT_POSTFIELDS => $json, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 120, ]); $resp = curl_exec($ch); $errno = curl_errno($ch); $err = curl_error($ch); $status = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($errno !== 0) { return ['ok' => false, 'error' => 'cURL error: ' . $err]; } if ($resp === false || trim((string)$resp) === '') { return ['ok' => false, 'error' => 'Empty response']; } $data = json_decode((string)$resp, true); if (!is_array($data)) { return ['ok' => false, 'error' => 'Invalid JSON response', 'raw' => ['text' => (string)$resp, 'status' => $status]]; } if ($status < 200 || $status >= 300) { $msg = $data['error']['message'] ?? ('HTTP ' . $status); return ['ok' => false, 'error' => (string)$msg, 'raw' => $data]; } $choice0 = $data['choices'][0] ?? null; $msg = is_array($choice0) ? ($choice0['message'] ?? null) : null; if (!is_array($msg)) { return ['ok' => false, 'error' => 'No message in response', 'raw' => $data]; } // 兼容旧格式 function_call(单工具) if (!isset($msg['tool_calls']) && isset($msg['function_call']) && is_array($msg['function_call'])) { $fc = $msg['function_call']; $msg['tool_calls'] = [[ 'id' => 'call_' . bin2hex(random_bytes(6)), 'type' => 'function', 'function' => [ 'name' => (string)($fc['name'] ?? ''), 'arguments' => (string)($fc['arguments'] ?? ''), ], ]]; unset($msg['function_call']); } return [ 'ok' => true, 'message' => $msg, 'raw' => $data, 'status' => $status, ]; }, ];
保存