注意:本产品是独立开发的,不隶属于 OpenAI、不认可或赞助。
使用 Composer 安装此包作为依赖项。
composer require manuelkiessling/ai-tool-bridge
将人工智能集成到任何项目中时的主要挑战是管理人工智能与应用程序其余部分之间的交互。当 AI 需要调用 API 来检索信息或触发操作时,这变得尤其复杂。
PHP 的 AI Tool Bridge 通过提供一个简单的接口来定义 AI 在需要与外部系统交互时可以使用的“工具功能”,从而优雅地解决了这个问题。
一个重要的优化是该库能够为工具函数生成所需的 JSON 结构。它通过仅从 AI 请求所需的值,然后根据提供的 JSON 模式生成 JSON 来实现这一点。这种方法保证了到达应用程序代码的最终 JSON 的有效性。
该库的主要功能包括:
假设您有一家电子商务企业,并且您希望提供一个允许浏览产品目录的 AI 聊天界面。为此,您决定通过 ChatGPT API 与 OpenAI 的 GPT-4 模型集成。
您可能会提示人工智能助理“您是一位友好且乐于助人的购物助理,可以向用户介绍我们的产品目录......”等等。
但是,您无法将整个产品目录添加到提示中。因此,当您的用户要求人工智能“告诉我一些提供的厨房帮手”时,您需要确定在对话的这一点上,人工智能需要来自您的电子商务后端系统的信息(例如,通过向您的产品发出请求)通过查询“厨房助手”搜索 API),您需要为 AI 检索此信息,并且需要将结果信息提供回 AI 助手,然后 AI 助手可以为用户汇总产品信息。
人工智能最清楚何时需要从外部世界检索这些信息。因为让您自己的代码监听对话并让它猜测何时进行 Product Search API 调用非常复杂且容易出错,并且使得使用强大的 AI 的想法变得毫无意义。
最好的方法是让人工智能认识到是时候与外界对话了,并让它以结构化且明确的方式进行对话。
解决方案是在最初的系统提示中告诉人工智能,它拥有一个或多个可以随意使用的工具。
这是通过首先编写所谓的工具函数定义来完成的,如下所示:
<?php
declare (strict_types= 1 );
namespace ManuelKiessling AiToolBridge Example ;
use ManuelKiessling AiToolBridge ToolFunctionCallResult ;
use ManuelKiessling AiToolBridge ToolFunctionCallResultStatus ;
use ManuelKiessling AiToolBridge ToolFunction ;
class MyProductSearchToolFunction implements ToolFunction
{
public function getName (): string
{
return ' productSearch ' ;
}
public function getDescription (): string
{
return ' allows to search the product catalogue and retrieve information about products ' ;
}
public function getInputJsonSchema (): string
{
return <<<'JSON'
{
"type": "object",
"properties": {
"searchterms": {
"type": "string"
}
},
"required": [
"searchterms"
]
}
JSON;
}
public function invoke ( string $ json ): ToolFunctionCallResult
{
// we will talk about this in a minute
return new ToolFunctionCallResult (
$ this ,
ToolFunctionCallResultStatus :: SUCCESS ,
'' ,
[]
);
}
}
确保 JSON 模式中的名称、描述和对象键有用且具有描述性 - 这有助于 AI 理解何时以及如何使用此工具功能。
您可以定义多个工具功能定义 - 例如,可以添加另一个工具功能,使人工智能能够在用户要求时将产品放入结帐篮中。不过,我们将保持这个例子简单。
接下来,您需要将工具桥与现有的 AI 设置集成。这是使用AiToolBridge
帮助程序完成的:
class Example
{
private AiToolBridge $ aiToolBridge ;
private MyAiService $ myAiService ;
public function __construct ()
{
$ this -> myAiService = new MyAiService ();
$ myProductSearchToolFunction = new MyProductSearchToolFunction ();
$ this -> aiToolBridge = new AiToolBridge (
new $ this -> myAiService ,
[ $ myProductSearchToolFunction ],
);
$ this -> myAiService -> setSystemPrompt (
" You are a friendly and helpful shopping assistant that informs the user about our product catalog...
{ $ this -> aiToolBridge -> getPrompt ()}"
);
}
}
这显然做出了几个假设——应用程序的构建方式和集成人工智能服务的方式可能会有很大不同。
不过,集成点始终是相同的。由于该库需要能够与 AI 助手对话,因此您必须提供一个实现AiAssistantMessenger
接口的对象。有关简单示例,请参阅 src/Example/MyAiService.php。
您还需要附加在创建 AiToolBridge 对象时定义的工具函数。
接下来,为了让 AI 理解它可以使用您的工具,您需要使用该库生成的提示来扩展您自己的 AI“系统”提示。为此,请使用方法AiToolBridge::getPrompt
如上所示。
您的应用程序和该库现已完全集成和设置。然而,缺少一个核心部分——人工智能使用你的工具功能时应该触发的实际行为。
我们再看一下MyProductSearchToolFunction
类的方法invoke
:
public function invoke ( string $ json ): ToolFunctionCallResult
{
return new ToolFunctionCallResult (
$ this ,
ToolFunctionCallResultStatus :: SUCCESS ,
'' ,
[]
);
}
这就是魔法需要发生的地方 - 也就是说,这是实现实际产品搜索所需的所有逻辑(您的逻辑)的地方。
在这里,您不需要以任何方式考虑人工智能集成——这正是这个库的目的,为您完成繁重的工作。
更准确地说,当调用invoke
方法时,繁重的工作已经完成 - 您可以放心,该方法将使用 JSON 字符串调用,一方面具有您在方法中使用 JSON Schema 定义的精确结构MyProductSearchToolFunction::getInputJsonSchema
,另一方面填充了 AI 在使用工具函数时认为有用的值。
例如,如果人工智能与用户的对话是这样的:
AI: Hello, how can I help you?
User: Tell me about some kitchen helpers on offer.
那么 AI 将认识到它应该使用工具函数productSearch
来搜索kitchen helpers
,这最终会导致使用以下 JSON 字符串调用MyProductSearchToolFunction::invoke
:
{
"searchterms" : " kitchen helpers "
}
对于如何实现此方法,您拥有完全的自由(只要返回ToolFunctionCallResult
对象)。在我们的示例中,实际进行产品搜索显然是有意义的,但如何执行此操作完全取决于您。查询数据库、与 API 对话或任何其他检索有关“厨房助手”生产信息的操作。
ToolFunctionCallResult
对象上您需要返回的两个感兴趣的字段是message
和data
。在我们的示例中,可能如下所示:
public function invoke ( string $ json ): ToolFunctionCallResult
{
$ jsonAsArray = json_decode ( $ json , true );
// use $jsonAsArray['searchterm'] when talking to a DB or an API...
return new ToolFunctionCallResult (
$ this ,
ToolFunctionCallResultStatus :: SUCCESS ,
' Found 2 matching products ' ,
[
[
' id ' => 84 ,
' name ' => ' Kawaii Chick Egg Separator ' ,
' price ' => 14.99 ,
' description ' => ' Whether you’re a beginner baker or an experienced cook, the Kawaii Chick Egg Separator is a must-have kitchen tool that will make separating eggs a breeze. '
],
[
' id ' => 2389 ,
' name ' => ' BlendJet 2 ' ,
' price ' => 49.99 ,
' description ' => ' Imagine the freedom of being able to go anywhere and blend your favorite smoothies, shakes, margaritas, frappés, or baby food without the limitations of a regular blender. '
]
]
);
}
data
格式不限于任何特定模式。
让我们看一下最后的部分,然后返回到我们的Example
类。我们假设在您的实现中,有一个方法handleAssistantMessage
,每当您的应用程序检索新的AI助手消息时就会调用该方法 - 同样,这是您的应用程序的一个非常具体的实现细节。
这就是我们向用户发送消息之前的地方! ——我们需要“融入”对话的地方。这使得工具库能够检测来自 AI 的任何工具功能请求,并进行相应的处理。
如果工具功能被调用并且成功,我们需要将结果反馈给人工智能助手——这样,它就能了解与其产品搜索相匹配的产品:
<?php
declare (strict_types= 1 );
class Example
{
// ...
public function handleAssistantMessage ( string $ message ): void
{
$ toolFunctionCallResult = $ this -> aiToolBridge -> handleAssistantMessage ( $ message );
if ( is_null ( $ toolFunctionCallResult )) {
// The AI didn't use a tool function, thus its message is meant for the user
$ this -> sendAssistantMessageToUser ( $ message );
} else {
// The AI used a tool function, we now need to send the result to the AI
$ dataAsJson = json_encode ( $ toolFunctionCallResult -> data );
$ this -> sendUserMessageToAssistant ( $ toolFunctionCallResult -> message . ' ' . $ dataAsJson );
}
}
public function sendAssistantMessageToUser ( string $ message ): void
{
// whatever code is needed to show an AI assistant message to the user
}
public function sendUserMessageToAssistant ( string $ message ): void
{
// whatever code is needed to send a message to the AI assistant
}
}
正如你所看到的,当我们通知人工智能助手有关滚动功能的结果时,我们相当于用户告诉助手这一点。因为从AI助手的角度来看,向AI提供工具的首先是用户!请参阅方法 src/AiToolBridge.php 以了解为什么会出现这种情况。
欢迎贡献!要做出贡献,请熟悉 CONTRIBUTING.md。
保证用户信息安全是首要任务,我们欢迎外部安全研究人员的贡献。如果您认为在此存储库中维护的软件中发现了安全问题,请阅读 SECURITY.md 以获取有关提交漏洞报告的说明。
AI Tool Bridge for PHP 版权所有 © Manuel Kießling,并根据自由软件基金会发布的 GNU 通用公共许可证(GPL-3.0 或更高版本)的条款获得使用许可。
请参阅许可证和通知了解更多信息。