AI
object
%AI
/phlo/resources/AI/AI.phlo
prop
%AI -> model
line 10
此项定义了一个标识符为'gpt-5.4-mini'的AI模型。
'gpt-5.4-mini'const
AI :: engines
line 11
定义了AI引擎标识符与其各自名称的映射,便于在Phlo应用程序中进行引用和集成。
['claude' => 'Claude', 'gpt' => 'OpenAI', 'chatgpt' => 'OpenAI', 'o1' => 'OpenAI', 'o3' => 'OpenAI', 'o4' => 'OpenAI', 'deepseek' => 'DeepSeek', 'gemini' => 'Gemini', 'grok' => 'Grok']static
AI :: http (string $url, array $headers, bool $json = true, mixed $post = null):string
line 12
向指定的URL发送HTTP请求,带有可选的头部、JSON有效负载和POST数据,并允许自定义超时时间。
HTTP($url, $headers, $json, $post, timeout: 300)method
%AI -> resolve (...$args):array
line 13
根据提供的参数解析要使用的AI引擎,如果未指定特定引擎,则默认为'OpenAI'。
$via = $args['via'] ?? void
unset($args['via'])
$args['model'] ??= $this->model
if ($via) $via = static::engines[strtolower($via)] ?? $via
elseif (isset($args['model'])) $via = static::engines[strtolower(explode(dash, $args['model'])[0])] ?? void
return [$via ?: 'OpenAI', $args]method
%AI -> chat (...$args)
line 21
此方法使用指定的AI引擎和参数启动聊天会话。
[$engine, $args] = $this->resolve(...$args)
return phlo($engine)->chat(...$args)method
%AI -> stream (...$args):Generator
line 25
使用提供的参数从AI引擎流式传输数据。
[$engine, $args] = $this->resolve(...$args)
return phlo($engine)->stream(...$args)method
%AI -> embedding (...$args)
line 29
该函数解析引擎和参数,然后使用提供的参数调用指定引擎上的 embedding 方法。
[$engine, $args] = $this->resolve(...$args)
return phlo($engine)->embedding(...$args)method
%AI -> vision (...$args)
line 33
此函数解析AI引擎和参数,然后使用提供的参数调用指定引擎的vision方法。
[$engine, $args] = $this->resolve(...$args)
return phlo($engine)->vision(...$args)method
%AI -> transcribe (...$args)
line 37
使用指定的AI引擎和参数转录音频输入。
[$engine, $args] = $this->resolve(...$args)
return phlo($engine)->transcribe(...$args)object
%Claude
/phlo/resources/AI/Claude.phlo
const
Claude :: model
line 10
使用 'claude-opus-4-8' 源定义模型,可用于 Phlo 中的各种 AI 任务。
'claude-opus-4-8'static
Claude :: context (...$args)
line 12
通过设置消息和系统参数来初始化Claude的上下文,确保用户和助手消息被正确格式化和存储。
$args['messages'] ??= []
if (isset($args['system'])){
$args['system'] = [['type' => 'text', 'text' => $args['system']]]
}
if (isset($args['assistant']) && array_push($args['messages'], ['role' => 'assistant', 'content' => $args['assistant']])) unset($args['assistant'])
if (isset($args['user']) && array_push($args['messages'], ['role' => 'user', 'content' => $args['user']])) unset($args['user'])
return $argsstatic
Claude :: tool ($tool):array
line 22
这构建了一个关联数组,包含工具的名称和描述,以及其输入模式,定义了工具的属性和必需参数。
[
'name' => $tool->name,
'description' => $tool->desc,
'input_schema' => [
'type' => 'object',
'properties' => loop($tool->args, fn($data, $arg) => array_filter($data, fn($key) => in_array($key, ['type', 'enum', 'description']), ARRAY_FILTER_USE_KEY)),
'required' => array_keys($tool->args),
],
]method
%Claude -> embedding ($input, $model = 'text-embedding-3-small')
line 32
使用指定的模型为给定输入生成嵌入,默认为'text-embedding-3-small'。
%OpenAI->embedding($input, $model)method
%Claude -> vision ($text, $image, $stream = false, ...$args)
line 34
此函数将文本和图像发送到视觉模型,选项是流式传输响应或以聊天格式返回。
$data = is_string($image) && str_starts_with($image, 'http') ? file_get_contents($image) : $image
$messages = [['role' => 'user', 'content' => [['type' => 'text', 'text' => $text], ['type' => 'image', 'source' => ['type' => 'base64', 'media_type' => 'image/jpeg', 'data' => base64_encode($data)]]]]]
if ($stream) return $this->stream(...$args, messages: $messages)
else return $this->chat(...$args, messages: $messages)method
%Claude -> chat (...$args)
line 41
此函数与Claude API交互以发送聊天请求并处理响应,返回一个包含答案、模型信息、令牌使用情况和交互过程中使用的任何工具的对象。
$args['model'] ??= static::model
$args['max_tokens'] ??= 4096
$token = $args['token'] ?? null
unset($args['token'])
$args = static::context(...$args)
$res = $this->request('messages', token: $token, POST: $args)
$return = new obj(answer: void, model: $res->model, finish: $res->stop_reason, tokens: ($res->usage->input_tokens ?? 0) + ($res->usage->output_tokens ?? 0), tokens_in: $res->usage->input_tokens ?? 0, tokens_out: $res->usage->output_tokens ?? 0)
$tools = []
foreach ($res->content AS $block){
if ($block->type === 'text') $return->answer = $block->text
elseif ($block->type === 'tool_use') $tools[] = new obj(name: $block->name, args: (array)$block->input)
}
if ($tools) $return->tools = $tools
return $returnmethod
%Claude -> parseSSE (string $url, array $headers, array $payload):Generator
line 58
从给定的 URL 解析服务器发送的事件 (SSE),发送 JSON 有效负载并处理响应,包括错误管理和在接收数据时进行生成。
$json = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
$ctx = stream_context_create(['http' => ['method' => 'POST', 'header' => implode(nl, [...$headers, 'Content-Type: application/json', 'Content-Length: '.strlen($json)]), 'content' => $json, 'timeout' => 300, 'ignore_errors' => true]])
$stream = fopen($url, 'r', false, $ctx)
$stream || error('SSE connection failed')
$status = (int)explode(space, $http_response_header[0] ?? 'HTTP/1.1 200')[1]
if ($status >= 400){
$err = json_decode((string)stream_get_contents($stream))
fclose($stream)
error('Claude error '.$status.': '.($err->error->message ?? 'unknown'))
}
$finish = null
$usage = null
while (!feof($stream)){
$line = fgets($stream)
if ($line === false) break
$line = rtrim($line, nl)
if (!str_starts_with($line, 'data:')) continue
$data = ltrim(substr($line, 5))
if ($data === void) continue
$p = json_decode($data)
if (!$p) continue
if (isset($p->error)) error('Claude stream error: '.$p->error->message)
if (($p->type ?? null) === 'message_delta'){
$finish = $p->delta->stop_reason ?? $finish
if (isset($p->usage)) $usage = $p->usage
}
if (($p->type ?? null) === 'content_block_delta' && ($p->delta->type ?? null) === 'text_delta' && isset($p->delta->text)) yield obj(text: $p->delta->text)
}
fclose($stream)
yield obj(done: true, finish: $finish, tokens_in: $usage?->input_tokens, tokens_out: $usage?->output_tokens)method
%Claude -> stream (...$args):Generator
line 90
通过服务器发送事件(SSE)从Claude API流式传输消息,实现与模型的实时交互。
%res->streaming = true
$args['model'] ??= static::model
$args['max_tokens'] ??= 4096
$token = $args['token'] ?? null
unset($args['token'], $args['cb'])
$args = static::context(...$args)
$args['stream'] = true
if ($token) $headers = ['anthropic-version: 2023-06-01', 'anthropic-beta: oauth-2025-04-20', 'Authorization: Bearer '.$token]
else $headers = ['anthropic-version: 2023-06-01', 'x-api-key: '.%creds->Claude]
return $this->parseSSE('https://api.anthropic.com/v1/messages', $headers, $args)method
%Claude -> request ($uri, ...$args)
line 103
使用指定的URI和参数向Claude API发送请求,处理使用令牌或API密钥的身份验证,并返回解码的JSON响应。
$token = $args['token'] ?? null
if ($token) $headers = ['anthropic-version: 2023-06-01', 'anthropic-beta: oauth-2025-04-20', 'Authorization: Bearer '.$token]
else $headers = ['anthropic-version: 2023-06-01', 'x-api-key: '.%creds->Claude]
$res = json_decode(AI::http("https://api.anthropic.com/v1/$uri", $headers, true, $args['POST'] ?? null))
if (isset($res->error)) error('Claude Request error: '.$res->error->message)
return $resobject
%DeepSeek
/phlo/resources/AI/DeepSeek.phlo
const
DeepSeek :: model
line 11
DeepSeek::model 是一个组件,便于在 DeepSeek 框架内创建和管理模型,从而实现高效的数据处理和交互。
'deepseek-chat'const
DeepSeek :: endpoint
line 12
定义访问 DeepSeek API 版本 1 的端点 URL。
'https://api.deepseek.com/v1/'const
DeepSeek :: cred
line 13
DeepSeek::cred 用于检索访问 DeepSeek 框架内资源的凭据。
'DeepSeek'const
DeepSeek :: label
line 14
DeepSeek::label用于为DeepSeek资源定义标签,从而在系统内实现更好的组织和识别。
'DeepSeek'method
%DeepSeek -> embedding ($input, $model = 'text-embedding-3-small')
line 16
使用指定的模型为给定输入生成嵌入,默认模型为'text-embedding-3-small'。
%OpenAI->embedding($input, $model)object
%Gemini
/phlo/resources/AI/Gemini.phlo
const
Gemini :: model
line 10
在Gemini框架中创建模型,允许定义和操作数据结构。
'gemini-2.0-flash'const
Gemini :: endpoint
line 11
定义一个用于访问Gemini API的端点,允许与给定URL处的指定模型进行交互。
'https://generativelanguage.googleapis.com/v1beta/models/'static
Gemini :: context (...$args)
line 13
Gemini::$context 处理输入参数以构建对话的结构化上下文,将系统、助手和用户消息组织到内容数组中。
$args['contents'] ??= []
if (isset($args['system'])){
$args['systemInstruction'] = ['parts' => [['text' => $args['system']]]]
unset($args['system'])
}
if (isset($args['assistant']) && array_push($args['contents'], ['role' => 'model', 'parts' => [['text' => $args['assistant']]]])) unset($args['assistant'])
if (isset($args['user']) && array_push($args['contents'], ['role' => 'user', 'parts' => [['text' => $args['user']]]])) unset($args['user'])
return $argsstatic
Gemini :: tool ($tool):array
line 24
Gemini::$tool 获取工具的名称和描述,以及其参数,包括类型、属性和必需的参数。
[
'name' => $tool->name,
'description' => $tool->desc,
'parameters' => [
'type' => 'object',
'properties' => loop($tool->args, fn($data, $arg) => array_filter($data, fn($key) => in_array($key, ['type', 'enum', 'description']), ARRAY_FILTER_USE_KEY)),
'required' => array_keys($tool->args),
],
]method
%Gemini -> embedding ($input, $model = 'text-embedding-004')
line 34
使用指定的模型为给定的输入文本生成嵌入,默认为'text-embedding-004'。
$this->request($model.':embedContent', POST: ['content' => ['parts' => [['text' => $input]]]])->embedding->valuesmethod
%Gemini -> vision ($text, $image, $stream = false, ...$args)
line 36
通过结合文本和图像生成视觉响应,并提供可选的实时输出流功能。
$model = $args['model'] ?? static::model
unset($args['model'])
$contents = [['role' => 'user', 'parts' => [['text' => $text], ['inline_data' => ['mime_type' => 'image/jpeg', 'data' => base64_encode(is_string($image) && str_starts_with($image, 'http') ? file_get_contents($image) : $image)]]]]]
if ($stream) return $this->stream(...$args, model: $model, contents: $contents)
else return $this->chat(...$args, model: $model, contents: $contents)method
%Gemini -> chat (...$args)
line 44
根据指定的模型和参数生成内容,返回一个对象,其中包括生成的答案、使用的模型、结束原因和令牌使用详情。
$model = $args['model'] ?? static::model
unset($args['model'])
$args = static::context(...$args)
$res = $this->request($model.':generateContent', POST: $args)
$return = new obj(answer: void, model: $model, finish: $res->candidates[0]->finishReason ?? void, tokens: ($res->usageMetadata->promptTokenCount ?? 0) + ($res->usageMetadata->candidatesTokenCount ?? 0), tokens_in: $res->usageMetadata->promptTokenCount ?? 0, tokens_out: $res->usageMetadata->candidatesTokenCount ?? 0)
$tools = []
foreach ($res->candidates[0]->content->parts ?? [] AS $part){
if (isset($part->text)) $return->answer = $part->text
elseif (isset($part->functionCall)) $tools[] = new obj(name: $part->functionCall->name, args: (array)$part->functionCall->args)
}
if ($tools) $return->tools = $tools
return $returnmethod
%Gemini -> parseSSE (string $url, array $headers, array $payload):Generator
line 59
从指定的URL解析服务器发送的事件(SSE),发送JSON有效负载并处理响应,生成文本数据和使用元数据。
$json = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
$ctx = stream_context_create(['http' => ['method' => 'POST', 'header' => implode(nl, [...$headers, 'Content-Type: application/json', 'Content-Length: '.strlen($json)]), 'content' => $json, 'timeout' => 300, 'ignore_errors' => true]])
$stream = fopen($url, 'r', false, $ctx)
$stream || error('SSE connection failed')
$status = (int)explode(space, $http_response_header[0] ?? 'HTTP/1.1 200')[1]
if ($status >= 400){
$err = json_decode((string)stream_get_contents($stream))
fclose($stream)
error('Gemini error '.$status.': '.($err->error->message ?? 'unknown'))
}
$finish = null
$usage = null
while (!feof($stream)){
$line = fgets($stream)
if ($line === false) break
$line = rtrim($line, nl)
if (!str_starts_with($line, 'data:')) continue
$data = ltrim(substr($line, 5))
if ($data === void) continue
$p = json_decode($data)
if (!$p) continue
if (isset($p->error)) error('Gemini stream error: '.$p->error->message)
if (isset($p->usageMetadata)) $usage = $p->usageMetadata
if ($p->candidates[0]->finishReason ?? null) $finish = $p->candidates[0]->finishReason
$text = $p->candidates[0]->content->parts[0]->text ?? null
if (!is_null($text)) yield obj(text: $text)
}
fclose($stream)
yield obj(done: true, finish: $finish, tokens_in: $usage?->promptTokenCount, tokens_out: $usage?->candidatesTokenCount)method
%Gemini -> stream (...$args):Generator
line 90
为Gemini中指定的模型启用流式传输,准备必要的参数并返回解析后的服务器发送事件响应。
%res->streaming = true
$model = $args['model'] ?? static::model
unset($args['model'], $args['cb'])
$args = static::context(...$args)
return $this->parseSSE(static::endpoint.$model.':streamGenerateContent?alt=sse', ['x-goog-api-key: '.%creds->Gemini], $args)method
%Gemini -> request ($path, ...$args)
line 98
向指定路径的Gemini API发送请求,带有可选参数,处理错误并返回解码的JSON响应。
$res = json_decode(AI::http(static::endpoint.$path, ['x-goog-api-key: '.%creds->Gemini], true, $args['POST'] ?? null))
if (isset($res->error)) error('Gemini Request error: '.$res->error->message)
return $resobject
%Grok
/phlo/resources/AI/Grok.phlo
const
Grok :: model
line 11
Grok::model 是Grok框架中的一个组件,便于创建和管理数据模型,从而实现与数据库和ORM功能的轻松交互。
'grok-4'const
Grok :: endpoint
line 12
定义一个用于向指定URL发起API请求的端点。
'https://api.x.ai/v1/'const
Grok :: cred
line 13
Grok::cred 是一个模块,提供在 Grok 框架内的凭证管理功能。
'Grok'const
Grok :: label
line 14
为Grok模式创建一个标签,使您能够更好地组织和识别代码中的模式。
'Grok'method
%Grok -> embedding ($input, $model = 'text-embedding-3-small')
line 16
使用指定的模型为给定输入生成嵌入,默认为'text-embedding-3-small'。
%OpenAI->embedding($input, $model)object
%OpenAI
/phlo/resources/AI/OpenAI.phlo
const
OpenAI :: model
line 10
此项指定要使用的OpenAI模型,在这种情况下为'gpt-5.4-mini'。
'gpt-5.4-mini'const
OpenAI :: endpoint
line 11
定义访问OpenAI API的端点,特别是API请求的基本URL。
'https://api.openai.com/v1/'const
OpenAI :: cred
line 12
此项表示用于身份验证和访问OpenAI服务的OpenAI凭证。
'OpenAI'const
OpenAI :: label
line 13
此功能用于使用OpenAI的模型对数据进行标记,以用于各种应用。
'OpenAI'const
OpenAI :: voices
line 14
OpenAI::voices 是可用于 Phlo 应用程序的预定义语音选项列表,包括 'alloy'、'echo'、'fable'、'onyx'、'nova' 和 'shimmer'。
['alloy', 'echo', 'fable', 'onyx', 'nova', 'shimmer']static
OpenAI :: context (...$args):array
line 15
此函数在OpenAI的上下文中初始化'messages'数组,并根据输入参数添加系统、助手和用户消息。
$args['messages'] ??= []
if (isset($args['system']) && array_unshift($args['messages'], ['role' => 'system', 'content' => $args['system']])) unset($args['system'])
if (isset($args['assistant']) && array_push($args['messages'], ['role' => 'assistant', 'content' => $args['assistant']])) unset($args['assistant'])
if (isset($args['user']) && array_push($args['messages'], ['role' => 'user', 'content' => $args['user']])) unset($args['user'])
return $argsstatic
OpenAI :: tool ($tool):array
line 22
在OpenAI中定义一个具有指定参数的函数,包括类型、枚举和描述,同时强制执行参数的严格验证。
[
'type' => 'function',
'function' => [
'name' => $tool->name,
'description' => $tool->desc,
'parameters' => [
'type' => 'object',
'properties' => loop($tool->args, fn($data, $arg) => array_filter($data, fn($key) => in_array($key, ['type', 'enum', 'desc']), ARRAY_FILTER_USE_KEY)),
'additionalProperties' => false,
'required' => array_keys($tool->args),
],
'strict' => true,
],
]method
%OpenAI -> chat (...$args):obj
line 36
此函数与OpenAI API交互,根据提供的参数生成聊天完成,返回一个包含响应详细信息的对象,例如生成的答案、使用的模型和令牌使用统计信息。
$args['model'] ??= static::model
$token = $args['token'] ?? null
unset($args['token'])
$args = static::context(...$args)
$res = $this->request('chat/completions', token: $token, POST: $args)
$return = new obj(answer: $res->choices[0]->message->content, model: $res->model, finish: $res->choices[0]->finish_reason, tokens: $res->usage->total_tokens, tokens_in: $res->usage->prompt_tokens, tokens_out: $res->usage->completion_tokens)
if (isset($res->choices[0]->message->tool_calls)) $return->tools = array_map(fn($tool) => new obj(name: $tool->function->name, args: json_decode($tool->function->arguments, true)), (array)$res->choices[0]->message->tool_calls)
return $returnmethod
%OpenAI -> embedding ($input, $model = 'text-embedding-3-small')
line 46
使用OpenAI指定的模型为给定输入生成嵌入。
$this->request('embeddings', POST: ['input' => $input, 'model' => $model])->data[0]->embeddingmethod
%OpenAI -> parseSSE (string $url, array $headers, array $payload):Generator
line 47
建立与指定 URL 的服务器推送事件 (SSE) 连接,发送 JSON 有效负载和头部,并生成从流中接收到的数据。
$json = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
$ctx = stream_context_create(['http' => ['method' => 'POST', 'header' => implode(nl, [...$headers, 'Content-Type: application/json', 'Content-Length: '.strlen($json)]), 'content' => $json, 'timeout' => 300, 'ignore_errors' => true]])
$stream = fopen($url, 'r', false, $ctx)
$stream || error('SSE connection failed')
$status = (int)explode(space, $http_response_header[0] ?? 'HTTP/1.1 200')[1]
if ($status >= 400){
$err = json_decode((string)stream_get_contents($stream))
fclose($stream)
error(static::label.' error '.$status.': '.($err->error->message ?? 'unknown'))
}
$finish = null
$usage = null
while (!feof($stream)){
$line = fgets($stream)
if ($line === false) break
$line = rtrim($line, nl)
if (!str_starts_with($line, 'data:')) continue
$data = ltrim(substr($line, 5))
if ($data === '[DONE]' || $data === void) continue
$p = json_decode($data)
if (!$p) continue
if (isset($p->error)) error(static::label.' stream error: '.$p->error->message)
if (isset($p->usage)) $usage = $p->usage
$text = $p->choices[0]->delta->content ?? null
if (!is_null($text)) yield obj(text: $text)
if ($p->choices[0]->finish_reason ?? null) $finish = $p->choices[0]->finish_reason
}
fclose($stream)
yield obj(done: true, finish: $finish, tokens_in: $usage?->prompt_tokens, tokens_out: $usage?->completion_tokens)method
%OpenAI -> stream (...$args):Generator
line 78
通过服务器发送事件(SSE)从OpenAI API流式传输响应,允许与模型进行实时交互。
%res->streaming = true
$args['model'] ??= static::model
$token = $args['token'] ?? null
unset($args['token'], $args['cb'])
$args = static::context(...$args)
$args['stream'] = true
$bearer = $token ?? %creds->{static::cred};
return $this->parseSSE(static::endpoint.'chat/completions', ['Authorization: Bearer '.$bearer], $args)method
%OpenAI -> transcribe ($file, $model = 'whisper-1', ...$args):obj
line 88
使用指定模型对给定文件中的音频进行转录,返回持续时间、语言和转录文本等详细信息。
if (is_string($file)) $file = new CURLFile($file)
elseif (is_a($file, 'file')) $file = $file->curl
$res = $this->request('audio/transcriptions', false, POST: [...$args, 'model' => $model, 'file' => $file, 'response_format' => 'verbose_json'])
return obj (
model: $model,
duration: $res->duration,
lang: $res->language,
text: $res->text,
)method
%OpenAI -> vision ($text, $image, $stream = false, ...$args):obj
line 99
此函数将文本和图像发送到OpenAI视觉模型,选项是流式传输响应或以聊天格式返回。
$args['model'] ??= static::model
$messages = [['role' => 'user', 'content' => [['type' => 'text', 'text' => $text], ['type' => 'image_url', 'image_url' => ['url' => $image]]]]]
if ($stream) return $this->stream(...$args, messages: $messages)
else return $this->chat(...$args, messages: $messages)method
%OpenAI -> request ($uri, $JSON = true, $token = null, ...$args)
line 105
向指定的URI发送请求到OpenAI API,可选择包含JSON有效负载和授权令牌,并返回解码后的响应。
$bearer = $token ?? %creds->{static::cred};
$res = json_decode(AI::http(static::endpoint.$uri, ['Authorization: Bearer '.$bearer], $JSON, $args['POST'] ?? null))
if (isset($res->error)) error(static::label.' Request error: '.$res->error->message)
return $resFunctions
function
answer($question, ...$options)
/phlo/resources/AI/answer.phlo line 10
生成对给定问题的简短直接回答,可以从指定选项中选择,或提供不带额外文本的简洁回答。
$prompt = 'You are an AI answer machine. '
$prompt .= 'You give short, direct answers without repeating the subject. '
$prompt .= 'You add no explanation, no extra text, and no quotation marks. '
$prompt .= 'Always answer in the same language as the question.'.lf
if ($options){
$prompt .= 'The user asks a question. You choose exactly one of the options below as the answer. '
$prompt .= 'Your answer matches exactly one of the options, with no extra words or punctuation. '
$prompt .= 'If none of the options apply, answer with "-".'.lf.lf
$prompt .= 'Question:'.lf.$question.lf.lf
$prompt .= 'Options:'.lf
$prompt .= implode(lf, $options)
}
else {
$prompt .= 'Give a short and precise answer to the question. '
$prompt .= 'No introduction, no explanation, no list, and no final period.'.lf.lf
$prompt .= 'Question:'.lf.$question
}
$answer = %AI->chat(user: $prompt, temperature: .1)->answer
return $answer === dash ? null : $answer