ogi / prompt

一个PHP包,将类属性转换为LLM API的XML格式提示。

v0.0.8 2024-09-25 07:46 UTC

This package is auto-updated.

Last update: 2024-09-25 07:52:48 UTC


README

CI

提示

一个将类属性转换为XML格式提示的PHP包,准备用于大型语言模型(LLM) API调用。它递归处理数组、集合、嵌套数组和嵌套的Prompt实例,将它们转换为带有适当标签的XML。

为什么需要结构化提示?

结构化提示在与大型语言模型(LLM)交互时至关重要,以确保一致性、清晰度和最佳性能。XML提供了一种标准化的数据结构化方式,是格式化提示的绝佳选择。

  • 模型间一致性:XML的层次结构允许提示格式的一致性,当与不同的模型或API一起工作时,这可能是有益的。
  • 改进解析:XML是一种广泛接受的格式,可以轻松解析和验证,从而降低了提示解释中出错的可能性。
  • 灵活性:XML表示复杂嵌套数据的灵活性使其适合构建详细和复杂的提示。
  • 可读性:结构化的XML提示更易于阅读和维护,有助于调试和提示优化。

通过使用XML格式化提示,开发人员可以为LLM提供清晰且明确的指令,可能提高模型的理解和响应准确性。

目录

安装

使用Composer安装此包

composer require ogi/prompt

功能

  • 自动XML转换:将公共类属性转换为XML元素。
  • 数组和集合处理:支持数组、集合和嵌套数组,在适当的位置使用<entry><list>标签。
  • 嵌套提示实例:允许属性是Prompt的实例,它们将在<prompt>标签中递归渲染。
  • 自定义对象支持:处理实现toArray()__toString__的对象。
  • 边缘情况处理:管理私有/受保护属性、空值、布尔值、数值、特殊字符和循环引用等特殊情况。
  • 递归处理:递归处理任何深度的嵌套数组和集合。
  • 易于集成:扩展Prompt类并定义您的数据;render()方法将处理其余部分。
  • 模板:扩展GeneralPromptTemplate类并利用其设置器来填充适用于您的数据的通用模板提示。

用法

基本示例

创建一个扩展包中提供的Prompt类的PHP类。使用公共属性定义您的数据。

<?php

require 'vendor/autoload.php';

use Ogi\Prompt\Prompt;

class MyPrompt extends Prompt
{
    public $purpose = 'Who are the leaders of England, France and Russia when World War 2 started';
    public $instructions = [
        'For definition of leader consider titles - king, prime-minister, president',
        'Present the output in a markdown table with columns leader title,name, country'
    ];
}

$prompt = new MyPrompt();
echo $prompt->render();

输出

<prompt>
  <purpose>Who are the leaders of England, France and Russia when World War 2 started</purpose>
  <instructions>
    <entry>For definition of leader consider titles - king, prime-minister, president</entry>
    <entry>Present the output in a markdown table with columns leader title,name, country</entry>
  </instructions>
</prompt>

处理数组

此包自动处理数组并使用<entry><list>标签将其转换为XML。

<?php

class MyPrompt extends Prompt
{
    public $questions = [
        'What is your name?',
        'How old are you?',
        'What is your favorite color?',
    ];
}

$prompt = new MyPrompt();
echo $prompt->render();

输出

<prompt>
  <questions>
    <entry>What is your name?</entry>
    <entry>How old are you?</entry>
    <entry>What is your favorite color?</entry>
  </questions>
</prompt>

使用集合

此包支持任何实现Traversable接口的对象,例如PHP的ArrayObject或来自如Laravel的Illuminate\Support\Collection的集合。

<?php

use Illuminate\Support\Collection;

class MyPrompt extends Prompt
{
    public $items;

    public function __construct()
    {
        $this->items = new Collection([
            'First Item',
            'Second Item',
            new Collection(['Nested Item 1', 'Nested Item 2']),
            'Third Item',
        ]);
    }
}

$prompt = new MyPrompt();
echo $prompt->render();

输出

<prompt>
  <items>
    <entry>First Item</entry>
    <entry>Second Item</entry>
    <list>
      <entry>Nested Item 1</entry>
      <entry>Nested Item 2</entry>
    </list>
    <entry>Third Item</entry>
  </items>
</prompt>

嵌套提示实例

您可以具有实例为Prompt类的属性。这些将在<prompt>标签中递归渲染。

<?php

class SubPrompt extends Prompt
{
    public $message = 'This is a sub-prompt.';
    public $details = [
        'detail1' => 'Detail One',
        'detail2' => 'Detail Two',
    ];
}

class MyPrompt extends Prompt
{
    public $title = 'Main Prompt';
    public $subPrompt;

    public function __construct()
    {
        $this->subPrompt = new SubPrompt();
    }
}

$prompt = new MyPrompt();
echo $prompt->render();

输出

<prompt>
  <title>Main Prompt</title>
  <subPrompt>
    <prompt>
      <message>This is a sub-prompt.</message>
      <details>
        <detail1>Detail One</detail1>
        <detail2>Detail Two</detail2>
      </details>
    </prompt>
  </subPrompt>
</prompt>

使用通用提示模板

GeneralPromptTemplate 是一个抽象类,允许您定义具有上下文、目的、目标和输入输出指令的更结构化的提示。您可以通过扩展此类并设置属性来生成 XML 提示。

<?php

require 'vendor/autoload.php';

use Ogi\Prompt\Templates\GeneralPromptTemplate;

class MyPrompt extends GeneralPromptTemplate
{
    public function setInput($data): void
    {
        $this->input = $data;
    }
}

$prompt = new MyPrompt();
$prompt->addContext('Provide recommendations based on user input.');
$prompt->addPurpose('To give tailored advice for improving coding practices.');
$prompt->addGoal('Ensure the recommendations are practical and concise.');
$prompt->addInputDefinition('A brief description of the code the user wants feedback on.');
$prompt->addOutputDefinition('A list of suggestions to improve the user’s code.');
$prompt->addHowtoSteps([
    'Analyze the provided code.',
    'Identify areas of improvement.',
    'Provide actionable feedback with examples.',
]);

echo $prompt->render();

输出

<prompt>
  <context>Provide recommendations based on user input.</context>
  <purpose>To give tailored advice for improving coding practices.</purpose>
  <goal>Ensure the recommendations are practical and concise.</goal>
  <instructions>
    <input>
      <definition>A brief description of the code the user wants feedback on.</definition>
      <structure></structure>
      <value-meaning></value-meaning>
      <possible-values></possible-values>
      <if-instructions-per-type>
      </if-instructions-per-type>
    </input>
    <output>
      <definition>A list of suggestions to improve the user’s code.</definition>
      <structure></structure>
      <value-meaning></value-meaning>
      <possible-values></possible-values>
      <if-instructions-per-type>
      </if-instructions-per-type>
      <example-valid-output></example-valid-output>
      <example-invalid-output></example-invalid-output>
    </output>
    <howto>
      <definition></definition>
      <steps>
        <entry>Analyze the provided code.</entry>
        <entry>Identify areas of improvement.</entry>
        <entry>Provide actionable feedback with examples.</entry>
      </steps>
      <corner-cases>
      </corner-cases>
    </howto>
  </instructions>
  <considerations>
  </considerations>
  <struggles>
  </struggles>
  <input></input>
</prompt>

具有toArray()__toString__的自定义对象

此包可以处理实现 toArray()__toString() 的自定义对象。

具有 toArray() 的对象

<?php

class CustomObject
{
    public function toArray()
    {
        return [
            'keyA' => 'Value A',
            'keyB' => 'Value B',
        ];
    }
}

class MyPrompt extends Prompt
{
    public $customData;

    public function __construct()
    {
        $this->customData = new CustomObject();
        $this->customArray = [1,2, new CustomObject()];
    }
}

$prompt = new MyPrompt();
echo $prompt->render();

输出

<prompt>
  <customData>
    <keyA>Value A</keyA>
    <keyB>Value B</keyB>
  </customData>
  <customArray>
    <entry>1</entry>
    <entry>2</entry>
    <entry>
      <keyA>Value A</keyA>
      <keyB>Value B</keyB>
    </keyB>
  </customArray>
</prompt>

具有 __toString() 的对象

<?php

class StringableObject
{
    public function __toString()
    {
        return 'I can be converted to a string!';
    }
}

class MyPrompt extends Prompt
{
    public $stringable;

    public function __construct()
    {
        $this->stringable = new StringableObject();
    }
}

$prompt = new MyPrompt();
echo $prompt->render();

输出

<prompt>
  <stringable>I can be converted to a string!</stringable>
</prompt>

处理特殊情况

私有和受保护属性

XML 输出仅包含 public 属性。排除私有和受保护的属性。

<?php

class MyPrompt extends Prompt
{
    public $publicProperty = 'Public Value';
    protected $protectedProperty = 'Protected Value';
    private $privateProperty = 'Private Value';
}

$prompt = new MyPrompt();
echo $prompt->render();

输出

<prompt>
  <publicProperty>Public Value</publicProperty>
</prompt>

空值和空值

处理具有 null 值或空数组的属性。

<?php

class MyPrompt extends Prompt
{
    public $nullProperty = null;
    public $emptyArray = [];
}

$prompt = new MyPrompt();
echo $prompt->render();

输出

<prompt>
  <nullProperty></nullProperty>
  <emptyArray>
  </emptyArray>
</prompt>

布尔值

布尔值转换为以下格式

  • true 变为 1
  • false 变为空字符串
<?php

class MyPrompt extends Prompt
{
    public $trueProperty = true;
    public $falseProperty = false;
}

$prompt = new MyPrompt();
echo $prompt->render();

输出

<prompt>
  <trueProperty>true</trueProperty>
  <falseProperty>false</falseProperty>
</prompt>

数值

数值转换为字符串并包含在输出中。

<?php

class MyPrompt extends Prompt
{
    public $integerProperty = 42;
    public $floatProperty = 3.14;
}

$prompt = new MyPrompt();
echo $prompt->render();

输出

<prompt>
  <integerProperty>42</integerProperty>
  <floatProperty>3.14</floatProperty>
</prompt>

特殊字符

特殊字符被正确转义以生成有效的 XML。

<?php

class MyPrompt extends Prompt
{
    public $specialChars = 'Special < & > " \' Characters';
}

$prompt = new MyPrompt();
echo $prompt->render();

输出

<prompt>
  <specialChars>Special &lt; &amp; &gt; &quot; &apos; Characters</specialChars>
</prompt>

没有toArray()__toString__的对象

无法转换为字符串或数组的对象表示为空标签。

<?php

class NonStringableObject
{
    public $data = 'Some Data';
}

class MyPrompt extends Prompt
{
    public $nonStringableObject;

    public function __construct()
    {
        $this->nonStringableObject = new NonStringableObject();
    }
}

$prompt = new MyPrompt();
echo $prompt->render();

输出

<prompt>
  <nonStringableObject></nonStringableObject>
</prompt>

循环引用

该包可以优雅地处理循环引用,以防止无限递归。

<?php

class MyPrompt extends Prompt
{
    public $me;

    public function __construct()
    {
        $this->me = $this;
    }
}

$prompt = new MyPrompt();
echo $prompt->render();

输出

<prompt>
  <me>
    <self></self>
  </me>
</prompt>

测试

该包包含一个全面的测试套件,使用 PHPUnit 确保可靠性和正确性。测试涵盖

  • 包含公共属性和排除私有/受保护的属性。
  • 处理 null 值、空数组、布尔值、数值和特殊字符。
  • 处理具有或没有 toArray()__toString__ 的对象。
  • 递归渲染嵌套的 Prompt 实例。
  • 边缘情况,如循环引用和混合类型数组。

运行测试

要运行测试,执行

./vendor/bin/phpunit

或者如果您已添加 Composer 脚本

composer test

贡献

欢迎贡献!请遵循以下步骤

  1. 在 GitHub 上派生存储库。
  2. 为您的功能或错误修复创建新分支。
  3. 为您的更改编写测试。
  4. 确保所有测试通过。
  5. 提交带有更改详细描述的拉取请求。

许可证

本项目采用 MIT 许可证

附加说明

  • PHP 版本:确保您的 PHP 版本为 7.4 或更高。
  • 依赖关系:如果您使用来自 Laravel 等框架的集合,请确保包含必要的包(例如,illuminate/support)。
  • 循环引用:检测循环引用以防止渲染时的无限循环。

需要帮助?

如果您有任何问题或需要帮助,请在 GitHub 存储库 上打开一个问题。

祝您编码愉快!