llm-agents / prompt-generator
具有拦截器的LLM代理的提示生成器
Requires
- php: ^8.3
- llm-agents/agents: ^1.5
- llm-agents/json-schema-mapper: ^1.0
Requires (Dev)
- illuminate/support: ^11.0
- phpunit/phpunit: ^11.3
- spiral/boot: ^3.13
This package is auto-updated.
Last update: 2024-09-15 21:15:08 UTC
README
本包提供了一个灵活且可扩展的系统,用于生成聊天提示,其中包含了为LLM代理所需的所有系统和用户消息。它使用基于拦截器的方法来扩展生成器的能力。
安装
您可以通过Composer安装此包
composer require llm-agents/prompt-generator
Spiral框架中的设置
要在Spiral框架项目中启动并运行站点状态检查代理,您需要注册其引导程序。
以下是步骤
- 打开您的
app/src/Application/Kernel.php
文件。 - 添加引导程序如下
public function defineBootloaders(): array { return [ // ... other bootloaders ... \LLM\Agents\PromptGenerator\Integration\Spiral\PromptGeneratorBootloader::class, ]; }
- 为提示生成器创建一个引导程序。在您的
app/src/Application/Bootloader
目录中创建一个名为PromptGeneratorBootloader.php
的文件
namespace App\Application\Bootloader; use Spiral\Boot\Bootloader\Bootloader; use LLM\Agents\PromptGenerator\Interceptors\AgentMemoryInjector; use LLM\Agents\PromptGenerator\Interceptors\InstructionGenerator; use LLM\Agents\PromptGenerator\Interceptors\LinkedAgentsInjector; use LLM\Agents\PromptGenerator\Interceptors\UserPromptInjector; use LLM\Agents\PromptGenerator\PromptGeneratorPipeline; class PromptGeneratorBootloader extends Bootloader { public function defineSingletons(): array { return [ PromptGeneratorPipeline::class => static function ( LinkedAgentsInjector $linkedAgentsInjector, ): PromptGeneratorPipeline { $pipeline = new PromptGeneratorPipeline(); return $pipeline->withInterceptor( new InstructionGenerator(), new AgentMemoryInjector(), $linkedAgentsInjector, new UserPromptInjector(), // ... ); }, ]; } }
就这样!您的Spiral应用现在可以开始使用代理了。
用法
以下是一个初始化提示生成器并生成提示的示例
use App\Domain\Chat\PromptGenerator\SessionContextInjector; use LLM\Agents\PromptGenerator\Interceptors\AgentMemoryInjector; use LLM\Agents\PromptGenerator\Interceptors\InstructionGenerator; use LLM\Agents\PromptGenerator\Interceptors\LinkedAgentsInjector; use LLM\Agents\PromptGenerator\Interceptors\UserPromptInjector; use LLM\Agents\PromptGenerator\PromptGeneratorPipeline; $generator = new PromptGeneratorPipeline(); $generator = $generator->withInterceptor( new InstructionGenerator(), new AgentMemoryInjector(), new LinkedAgentsInjector($agents, $schemaMapper), new SessionContextInjector(), new UserPromptInjector() ); $prompt = $generator->generate($agent, $userPrompt, $context, $initialPrompt);
拦截器
该包附带几个内置拦截器
InstructionGenerator
此拦截器将代理的指令添加到提示中。它包括重要的规则,如以Markdown格式响应以及在对用户做出回应之前思考。
AgentMemoryInjector
此拦截器将代理的内存添加到提示中。它包括静态内存(在创建代理时定义)和动态内存(可以在对话期间更新)。
LinkedAgentsInjector
此拦截器将有关链接代理的信息添加到提示中。它提供了有关当前代理可以请求帮助的其他代理的详细信息,包括它们的密钥、描述和输出模式。
UserPromptInjector
此拦截器将用户的输入添加到提示中作为用户消息。
创建自定义拦截器
您可以通过实现 LLM\Agents\PromptGenerator\PromptInterceptorInterface
来创建自定义拦截器
让我们创建一个 ContextAwarePromptInjector
,它根据当前时间和用户偏好添加相关上下文。此示例将演示如何创建一个更复杂的拦截器,该拦截器与外部服务交互并根据提示进行修改。
namespace App\PromptGenerator\Interceptors; use LLM\Agents\LLM\Prompt\Chat\MessagePrompt; use LLM\Agents\LLM\Prompt\Chat\Prompt; use LLM\Agents\LLM\Prompt\Chat\PromptInterface; use LLM\Agents\PromptGenerator\InterceptorHandler; use LLM\Agents\PromptGenerator\PromptGeneratorInput; use LLM\Agents\PromptGenerator\PromptInterceptorInterface; use App\Services\UserPreferenceService; use App\Services\WeatherService; class ContextAwarePromptInjector implements PromptInterceptorInterface { public function __construct( private UserPreferenceService $userPreferenceService, private WeatherService $weatherService, ) {} public function generate(PromptGeneratorInput $input, InterceptorHandler $next): PromptInterface { $userId = $input->context->getUserId(); // Assuming we have this method in our context $userPreferences = $this->userPreferenceService->getPreferences($userId); $currentTime = new \DateTime(); $currentWeather = $this->weatherService->getCurrentWeather($userPreferences->getLocation()); $contextMessage = $this->generateContextMessage($currentTime, $userPreferences, $currentWeather); $modifiedPrompt = $input->prompt; if ($modifiedPrompt instanceof Prompt) { $modifiedPrompt = $modifiedPrompt->withAddedMessage( MessagePrompt::system($contextMessage), ); } return $next($input->withPrompt($modifiedPrompt)); } private function generateContextMessage(\DateTime $currentTime, $userPreferences, $currentWeather): string { $timeOfDay = $this->getTimeOfDay($currentTime); $greeting = $this->getGreeting($timeOfDay); return <<<PROMPT {$greeting} Here's some context for this conversation: - It's currently {$timeOfDay}. - The weather is {$currentWeather->getDescription()} with a temperature of {$currentWeather->getTemperature()}°C. - The user prefers {$userPreferences->getCommunicationStyle()} communication. - The user's interests include: {$this->formatInterests($userPreferences->getInterests())}. Please take this context into account when generating responses. PROMPT; } private function getTimeOfDay(\DateTime $time): string { $hour = (int) $time->format('G'); return match (true) { $hour >= 5 && $hour < 12 => 'morning', $hour >= 12 && $hour < 18 => 'afternoon', $hour >= 18 && $hour < 22 => 'evening', default => 'night', }; } private function getGreeting(string $timeOfDay): string { return match ($timeOfDay) { 'morning' => 'Good morning!', 'afternoon' => 'Good afternoon!', 'evening' => 'Good evening!', 'night' => 'Hello!', }; } private function formatInterests(array $interests): string { return \implode(', ', \array_map(fn($interest) => \strtolower($interest), $interests)); } }
然后,将您的自定义拦截器添加到管道
$generator = $generator->withInterceptor(new ContextAwarePromptInjector(...));
查看此UML序列图,了解提示生成过程如何与拦截器一起工作
实现PromptContextInterface
PromptGeneratorInput
包含一个类型为 PromptContextInterface
的 context
属性。此接口允许您将自定义上下文数据传递给您的拦截器。为了有效地使用它,您需要创建自己的接口实现。
以下是如何实现 PromptContextInterface
的示例
use LLM\Agents\LLM\PromptContextInterface; class ChatContext implements PromptContextInterface { public function __construct( private string $userId, private array $sessionData = [], ) {} public function getUserId(): string { return $this->userId; } public function getSessionData(): array { return $this->sessionData; } // Add any other methods you need for your specific use case }
然后,在生成提示时,您将传递您的自定义上下文实例
$context = new ChatContext($userId, $sessionData); $prompt = $generator->generate($agent, $userPrompt, $context);
在您的自定义拦截器中,您可以访问这些上下文数据
class ContextAwarePromptInjector implements PromptInterceptorInterface { public function generate(PromptGeneratorInput $input, InterceptorHandler $next): PromptInterface { $userId = $input->context->getUserId(); $sessionData = $input->context->getSessionData(); // Use this data to customize your prompt // ... return $next($input); } }
通过实现自己的 PromptContextInterface
,您可以传递从应用程序到拦截器的任何必要数据,从而实现高度定制和上下文感知的提示生成。
想要帮忙吗? 🤝
我们喜欢贡献!如果您有让这个代理变得更酷的想法,以下是您可以如何做出贡献
- 分支存储库
- 进行更改
- 创建一个新的Pull Request
只需确保您的代码整洁、有注释,并遵循PSR-12编码标准。
许可证 📄
本项目使用MIT许可证 - 有关详细信息,请参阅LICENSE 文件。
就这些了,各位!如果您有任何问题或遇到任何问题,请毫不犹豫地提出问题。