根据上一篇文章Neuron AI 学习[1]纠错。
原来认为chat()返回是个guzzle对象是错误的,当时没仔细看源码。
其次之前一直没看懂讯飞开放平台官网Openai sdk是啥意思。

其实就是换个url,估计回执格式不同。
NeuronAI\Providers\OpenAI\HandleChat::chat()
publicfunctionchat(Message ...$messages): Message{ ……………… $response = $this->httpClient->request($this->createChatHttpRequest($body) );return$this->processChatResult($response->json());}chat()会根据processChatResult()返回对应消息类。
NeuronAI\Providers\OpenAI\HandleChat::processChatResult()
protectedfunctionprocessChatResult(array $result): AssistantMessage{if ($result['choices'][0]['finish_reason'] === 'tool_calls') { $block = isset($result['choices'][0]['message']['content']) ? new TextContent($result['choices'][0]['message']['content']) : null; $response = $this->createToolCallMessage($result['choices'][0]['message']['tool_calls'], $block); } else { $response = $this->createAssistantMessage($result['choices'][0]['message']); } ………………return$this->enrichMessage($response, $result);}HandleChat作为trait在OpenAI类中使用,所以可以调用OpenAI类中的参数。 processChatResult()根据回执finish_reason字段判断是否是工具的回执,这个逻辑完全根据回执格式,所以回执格式不符合就不适用需要重写。
processChatResult()中若为工具的回执则调用OpenAi类中createToolCallMessage()方法。
processChatResult()最后OpenAI类中的方法enrichMessage()返回结果。
NeuronAI\Providers\OpenAI\OpenAI::createToolCallMessage()
protected function createToolCallMessage(array $toolCalls, array|ContentBlockInterface|null $blocks = null): ToolCallMessage { ………………$result = new ToolCallMessage($blocks, $tools);$result->addMetadata('tool_calls', $toolCalls);return$result; }createToolCallMessage()返回ToolCallMessage类。
NeuronAI\Providers\OpenAI\OpenAI::enrichMessage()
protectedfunctionenrichMessage(AssistantMessage $message, ?array $response = null): AssistantMessage{// Apply any accumulated streaming metadata if availableif (isset($this->streamState)) {foreach ($this->streamState->getMetadata() as $key => $value) {if ($message->getMetadata($key) === null) { $message->addMetadata($key, $value); } } }return $message;}enrichMessage()中仅处理流式回复的回执,所以非流式直接返回$message。
所以使用工具应该返回ToolCallMessage。
实际应用工具的时候会执行工作流,之后看完代码再解释。
修改processChatResult方法
$iscall = isset($result['choices'][0]['finish_reason']) && $result['choices'][0]['finish_reason'] === 'tool_calls';if (!$iscall) { $iscall = isset($result['choices'][0]['message']['tool_calls']);}if ($iscall) { $block = isset($result['choices'][0]['message']['content']) ? new TextContent($result['choices'][0]['message']['content']) : null; $response = $this->createToolCallMessage($result['choices'][0]['message']['tool_calls'], $block);} else { $response = new AssistantMessage($result['choices'][0]['message']['content']);}重写Provider,修改url和请求设置。
classOpenAIextendsProvidersOpenAI{protected string $baseUri = 'https://spark-api-open.xf-yun.com/x2/';publicfunction__construct( protected string $key, protected string $model, protected array $parameters = [], protected ?HttpClientOptions $httpOptions = null, ){ $config = [// Since Gemini use colon ":" into the URL, guzzle fires an exception using base_uri configuration.'base_uri' => trim($this->baseUri, '/') . '/','headers' => ['Accept' => 'application/json','Content-Type' => 'application/json','Authorization' => "Bearer " . $this->key, ],//设置不校验ssl'verify' => false, ];if ($this->httpOptions instanceof HttpClientOptions) { $config = $this->mergeHttpOptions($config, $this->httpOptions); }$this->client = new Client($config); }}Agent加工具。
protected function tools(): array {$data = Tool::make('get_current_weather','当你想查询指定城市的天气时非常有用。', )->addProperty( new ToolProperty( name: 'location',type: PropertyType::STRING, description: '城市或县区,比如北京市、杭州市、余杭区等。', required: true ) )->setCallable(function (string $location) { var_dump("tool setCallable", $location);$weatherData = ['天津市' => '天津市:晴天,20-28°C,北风2级','上海市' => '上海市:多云,22-30°C,东南风3级','深圳市' => '深圳市:阵雨,25-32°C,南风4级', ];return$weatherData[$location] ?? "{$location}:天气信息暂时不可用"; });return [$data];}$agent = OpenAIAgent::make();$msg = new UserMessage("今天天津的天气怎么样?");$message = $agent->chat($msg);echo$message->getContent();输出
宝子~今天天津是晴天哟!气温在20到28度之间,吹的是北风,风力有2级呢~最后结果实际是根据工作流,再次调用请求返回的结果。
Neuron AI 学习: https://mp.weixin.qq.com/s/-oKlOPrf0U5XzayGn8Dmqw?poc_token=HPMhBGqjhexkymMkoqnZzcA3uIWwsHoXK42AeGFh

扫描识别二维码关注我们获取更多