一个 CLI、PHP 库和 Symfony Bundle,帮助从 GPT 中提取结构化数据。

0.1.0 2023-04-07 09:40 UTC

This package is auto-updated.

Last update: 2024-09-11 16:49:13 UTC


README

一个 CLI 和 PHP 库,帮助从 GPT 中提取结构化数据。

给定一个 JSON 模式,GPT 能够输出符合该模式格式的 JSON。这种方法使得 GPT 能够被编程用于非对话场景。

例如,在解析用户上传的 CSV 之前,您可以要求 GPT 将其标题映射到您的代码支持的标题上。

$ bin/portal ./examples/csv_headers.yaml '{
  "supportedHeaders":["firstName","age"], 
  "headers":["Prenom","Nom Famille","Annees"]}'
...

Completion Results:
===================

{
    "mappedHeaders": {
        "Prenom": "firstName",
        "Nom Famille": null,
        "Annees": "age"
    }
}

⚠️ 注意,此库为实验性,API 将会更改。

您可以通过提交问题、想法、PR 等方式贡献。

安装

composer require sourceability/portal

试用

您可以使用 Docker 尝试 YAML 魔法

git clone https://github.com/sourceability/portal.git
cd portal
make php
bin/portal ./examples/csv_headers.yaml

Symfony 支持

该库包括一个 Symfony 包。

将包添加到 config/bundles.php

return [
    // ...
    Sourceability\Portal\Bundle\SourceabilityPortalBundle::class => ['all' => true],
];

然后定义环境变量 OPENAI_API_KEY=sk-XXX,例如在 .env.local 中。

您还可以配置该包

# config/packages/sourceability_portal.yaml
sourceability_portal:
    openai_api_key: '%my_openai_api_key%'

您可以使用 cast 命令通过其 FQCN 调用您的服务魔法(不要忘记引号)

bin/console portal:cast 'App\Portal\MySpell'

您还可以使用 #[AutoconfigureSpell] 属性定义一个短名称

use Sourceability\Portal\Bundle\DependencyInjection\Attribute\AutoconfigureSpell;

#[AutoconfigureSpell('Categorize')]
class CategorizeSpell implements Spell
{

然后使用 bin/console portal:cast Categorize 调用魔法

静态 YAML

您可以使用路径调用 portal,该路径具有以下格式的 .yaml

schema:
    properties:
        barbar:
            type: string
examples:
    - foobar: hello
    - foobar: world
prompt: |
    Do something.
  
    {{ foobar }}
vendor/bin/portal my_spell.yaml

魔法

魔法 接口是与该库交互的主要方式。

您可以将魔法视为创建一个函数的方法,其“实现”是一个 GPT 提示。

$spell = new StaticSpell(
    schema: [
        'type' => 'array',
        'items' => ['type' => 'string']
    ],
    prompt: 'Synonyms of {{ input }}'
);

/** @var callable(string): array<string> $generateSynonyms */
$generateSynonyms = $portal->callableFromSpell($spell);

dump($generateSynonyms('car'));

array:5 [▼
  0 => "automobile"
  1 => "vehicle"
  2 => "motorcar"
  3 => "machine"
  4 => "transport"
]
use Sourceability\Portal\Spell\Spell;

/*
 * @implements Spell<TInput, TOutput>
 */
class MySpell implements Spell

魔法由其输入/输出类型 TInputTOutput 定义。例如,接受一个数字并返回一个字符串数组的魔法将使用 Spell<int, string<string>>

getSchema

使用 getSchema 返回 JSON 模式

/**
 * @return string|array<string, mixed>|JsonSerializable The JSON-Schema of the desired completion output.
 */
public function getSchema(): string|array|JsonSerializable;

确保利用 描述示例 属性为 GPT 提供更多上下文和指令。

public function getSchema()
{
    return [
        'type' => 'object',
        'properties' => [
            'release' => [
                'description' => 'The release reference/key.',
                'examples' => ['v1.0.1', 'rc3', '2022.48.2'],
            ]
        ],
    ];
}

注意,您还可以利用定义 DSL 构建模式的库。

getPrompt

getPrompt 方法用于描述所需的行为

/**
 * @param TInput $input
 */
public function getPrompt($input): string
{
    return sprintf('Do something with ' . $input);
}

transcribe

最后,您可以将解码后的 GPT 输出转换为您的输出类型

/**
 * @param array<mixed> $completionValue
 * @return array<TOutput>
 */
public function transcribe(array $completionValue): array
{
    return array_map(fn ($item) => new Money($item), $completionValue);
}

getExamples

getExamples 方法返回 0 或多个输入示例。这在迭代提示时非常有用。

/**
 * @return array<TInput>
 */
public function getExamples(): array;

铸造

完成所有这些后,您可以尝试您的魔法示例

vendor/bin/portal 'App\Portal\FraudSpell'

或使用 PHP Api 调用您的魔法

$portal = new Portal(...);

$result = $portal->cast(
    new FraudSpell(),
    ['user' => $user->toArray()] // This contains TInput
);

// $result->value contains array<TOutput>
actOnThe($result->value);

$portal->transfer

如果您不需要拼写 getExamplestranscribe,您可以使用 transfer

$transferResult = $portal->transfer(
    ['type' => 'string'], // output schema
    'The prompt'
);
$transferResult->value; // the json decoded value

命令行界面(CLI)

您可以将自己的 JSON 示例传递给门户 CLI

bin/portal spell.yaml '[{"hello":["worlds"]},{"hello":[]}]'

使用 -v-vv-vvv 打印更多信息,例如提示或 OpenAI API 请求/响应。

ApiPlatformSpell

ApiPlatformSpell 使用 API Platform 生成 JSON Schema,同时也用于反序列化 JSON 结果。

您必须实现以下方法

  • getClass
  • getPrompt

以下方法是可选的

  • isCollection 默认为 false,您可以选择返回 true
  • getExamples 默认为空,您可以添加自己的示例
use Sourceability\Portal\Spell\ApiPlatformSpell;

/**
 * @extends ApiPlatformSpell<string, array<Part>>
 */
class PartListSpell extends ApiPlatformSpell
{
    public function getExamples(): array
    {
        return [
            'smartwatch',
            'bookshelf speaker',
        ];
    }

    public function getPrompt($input): string
    {
        return sprintf('A list of parts to build a %s.', $input);
    }
    
    protected function isCollection(): bool
    {
        return true;
    }
    
    protected function getClass(): string
    {
        return Part::class;
    }
}

然后,您可以使用 #[ApiProperty] 属性向您的模式添加上下文

use ApiPlatform\Metadata\ApiProperty;

class Part
{
    #[ApiProperty(
        description: 'Product description',
        schema: ['maxLength' => 100],
    )]
    public string $description;
}

示例

请参阅 ./examples/