sourceability / portal
一个 CLI、PHP 库和 Symfony Bundle,帮助从 GPT 中提取结构化数据。
Requires
- composer-runtime-api: *
- ext-json: *
- guzzlehttp/promises: ^1.5
- nyholm/psr7: ^1.5
- php-http/cache-plugin: ^1.0
- php-http/logger-plugin: ^1.0
- sourceability/openai-client: ^0.3.4
- symfony/cache: ^6.0
- symfony/console: ^6.0
- symfony/http-client: ^6.0
Requires (Dev)
- api-platform/core: ^3.0
- ergebnis/composer-normalize: ^2.30
- php-http/vcr-plugin: ^1.2
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^10.0
- rector/rector: ^0.15.21
- symfony/config: ^6.0
- symfony/dependency-injection: ^6.0
- symfony/framework-bundle: ^6.0
- symfony/http-kernel: ^6.0
- symplify/easy-coding-standard: ^11.2
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
魔法由其输入/输出类型 TInput
和 TOutput
定义。例如,接受一个数字并返回一个字符串数组的魔法将使用 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 构建模式的库。
- goldspecdigital/oooas - see examples/goldspecdigital-oooas
- swaggest/json-schema - see examples/swaggest
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
如果您不需要拼写 getExamples
和 transcribe
,您可以使用 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,您可以选择返回 truegetExamples
默认为空,您可以添加自己的示例
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/。