adrienbrault/instructrice

PHP 中 LLM 输出的类型化

dev-main 2024-07-23 21:15 UTC

This package is auto-updated.

Last update: 2024-09-23 21:39:35 UTC


README

GitHub Actions Packagist License

LLM 完成输入

一流的 LLM 可以根据您提供的模式输出 JSON,通常是 JSON-Schema。这大大扩展了您在应用程序中利用 LLM 的方式!

将输入视为

  • 上下文,任何可以或可以转换为文本的内容,如电子邮件/PDFs/HTML/xlsx
  • 一个模式,"这里是您需要填写的表单以完成您的任务"
  • 一个可选的提示,提供特定的任务、规则等

输出/结果是与您的用例和领域最佳匹配的结构。

python instructor cookbook 有一些有趣的示例。

简介

Instructrice 是一个 PHP 库,它以类型安全的方式简化了与 LLM 结构化输出的工作。

功能

  • 灵活的模式选项
  • symfony/serializer 集成以反序列化 LLM 输出
  • 以流为主
    • 作为开发者,您可以使用比等待输出完成更快的反馈循环来提高工作效率。这也使得较慢的本地模型更易于使用。
    • 您可以向用户提供更好、更快的用户体验。
    • 解析不完整 JSON 的麻烦由您来解决。
  • 一套预配置的 LLM,具有最佳可用设置。设置您的 API 密钥,在不同提供者和模型之间切换,无需考虑模型名称、JSON 模式、函数调用等。

还提供 Symfony Bundle

安装和使用

$ composer require adrienbrault/instructrice:@dev
use AdrienBrault\Instructrice\InstructriceFactory;
use AdrienBrault\Instructrice\LLM\Provider\Ollama;
use AdrienBrault\Instructrice\LLM\Provider\OpenAi;
use AdrienBrault\Instructrice\LLM\Provider\Anthropic;

$instructrice = InstructriceFactory::create(
    defaultLlm: Ollama::HERMES2THETA_LLAMA3_8B,
    apiKeys: [ // Unless you inject keys here, api keys will be fetched from environment variables
        OpenAi::class => $openAiApiKey,
        Anthropic::class => $anthropicApiKey,
    ],
);

对象列表

use AdrienBrault\Instructrice\Attribute\Prompt;

class Character
{
    // The prompt annotation lets you add instructions specific to a property
    #[Prompt('Just the first name.')]
    public string $name;
    public ?string $rank = null;
}

$characters = $instructrice->getList(
    Character::class,
    'Colonel Jack O\'Neil walks into a bar and meets Major Samanta Carter. They call Teal\'c to join them.',
);

/*
dump($characters);
array:3 [
  0 => Character^ {
    +name: "Jack"
    +rank: "Colonel"
  }
  1 => Character^ {
    +name: "Samanta"
    +rank: "Major"
  }
  2 => Character^ {
    +name: "Teal'c"
    +rank: null
  }
]
*/

对象

$character = $instructrice->get(
    type: Character::class,
    context: 'Colonel Jack O\'Neil.',
);

/*
dump($character);
Character^ {
  +name: "Jack"
  +rank: "Colonel"
}
*/

动态模式

$label = $instructrice->get(
    type: [
        'type' => 'string',
        'enum' => ['positive', 'neutral', 'negative'],
    ],
    context: 'Amazing great cool nice',
    prompt: 'Sentiment analysis',
);

/*
dump($label);
"positive"
*/

您还可以使用第三方 JSON 模式库,如 goldspecdigital/oooas 生成模式

CleanShot.2024-04-18.at.14.11.39.mp4

支持的提供者

支持的提供者是枚举类型,您可以将它们传递给 InstructriceFactory::createllm 参数

use AdrienBrault\Instructrice\InstructriceFactory;
use AdrienBrault\Instructrice\LLM\Provider\OpenAi;

$instructrice->get(
    ...,
    llm: OpenAi::GPT_4T, // API Key will be fetched from the OPENAI_API_KEY environment variable
);

支持的模式

开放式权重

基础

来自 https://artificialanalysis.ai/leaderboards/providers 的吞吐量。

微调

专有

来自 https://artificialanalysis.ai/leaderboards/providers 的吞吐量。

通过抓取 https://artificialanalysis.ai 和 chatboard arena elo 自动更新这些表格?这将是一个很好的库/cli 展示用例?

自定义模型

Ollama

如果您想使用不在枚举中的 Ollama 模型,您可以使用 Ollama::create 静态方法

use AdrienBrault\Instructrice\LLM\LLMConfig;
use AdrienBrault\Instructrice\LLM\Cost;
use AdrienBrault\Instructrice\LLM\OpenAiJsonStrategy;
use AdrienBrault\Instructrice\LLM\Provider\Ollama;

$instructrice->get(
    ...,
    llm: Ollama::create(
        'codestral:22b-v0.1-q5_K_M', // check its license first!
        32000,
    ),
);

OpenAI

您还可以通过传递 LLMConfig 使用任何 OpenAI 兼容的 API

use AdrienBrault\Instructrice\LLM\LLMConfig;
use AdrienBrault\Instructrice\LLM\Cost;
use AdrienBrault\Instructrice\LLM\OpenAiJsonStrategy;

$instructrice->get(
    ...,
    llm: new LLMConfig(
        uri: 'https://api.together.xyz/v1/chat/completions',
        model: 'meta-llama/Llama-3-70b-chat-hf',
        contextWindow: 8000,
        label: 'Llama 3 70B',
        provider: 'Together',
        cost: Cost::create(0.9),
        strategy: OpenAiJsonStrategy::JSON,
        headers: [
            'Authorization' => 'Bearer ' . $apiKey,
        ]
    ),
);

DSN

您可以使用 DSN 配置 LLM

  • 方案是提供者:openaiopenai-httpanthropicgoogle
  • 密码是 API 密钥
  • 主机、端口和路径是 API 端点,不带方案
  • 查询字符串
    • model 是模型名称
    • context 是上下文窗口
    • strategy 是要使用的策略
      • json 用于仅包含提示中模式的 json 模式
      • json_with_schema 用于带有可能完美约束于模式的完成项的 json 模式
      • tool_any
      • tool_auto
      • tool_function

示例

use AdrienBrault\Instructrice\InstructriceFactory;

$instructrice = InstructriceFactory::create(
    defaultLlm: 'openai://:api_key@api.openai.com/v1/chat/completions?model=gpt-3.5-turbo&strategy=tool_auto&context=16000'
);

$instructrice->get(
    ...,
    llm: 'openai-http://localhost:11434?model=adrienbrault/nous-hermes2theta-llama3-8b&strategy=json&context=8000'
);

$instructrice->get(
    ...,
    llm: 'openai://:api_key@api.fireworks.ai/inference/v1/chat/completions?model=accounts/fireworks/models/llama-v3-70b-instruct&context=8000&strategy=json_with_schema'
);

$instructrice->get(
    ...,
    llm: 'google://:api_key@generativelanguage.googleapis.com/v1beta/models?model=gemini-1.5-flash&context=1000000'
);

$instructrice->get(
    ...,
    llm: 'anthropic://:api_key@api.anthropic.com?model=claude-3-haiku-20240307&context=200000'
);

LLMInterface

您也可以实现 LLMInterface

致谢

显然受到了 instructor-phpinstructor 的启发。

它与 instructor php 有何不同?

这两个库基本上做的是同一件事

  • 从类自动生成模式
  • 多个 LLM/提供商抽象/支持
  • 许多提取数据的方法:函数调用、json 模式等
  • 自动反序列化/填充
  • 也许这个库以后会有验证/重试的功能。

然而,instructice 与之不同

  • 以流为主。
  • 预配置提供商+llms,无需担心
    • json 模式、函数调用等
    • 要使用的最佳提示格式
    • 您在本地模型上的选项
    • 流是否工作。例如,groq 只能在没有 json-mode/函数调用的情况下进行流。
  • PSR-3 日志记录
  • Guzzle+symfony/http-client 支持
  • 没有消息。您只需传递上下文、提示。
    • 我希望这个选择能够支持以后的一些酷功能,比如支持 few-shots 示例、evals 等
  • 更灵活的模式选项
  • 高级抽象。您无法提供消息列表,而 instructor-php 可以。

备注/想法

需要考虑的事情

DSPy 非常有趣。有许多值得借鉴的伟大想法。

理想情况下,这个库适合进行原型设计,但可以支持具有 few shot 示例、某种评估系统、生成样本/输出等更高级的提取工作流程。

有一个 CLI 会很酷,它接受一个 FQCN 和一个上下文。

instructrice get "App\Entity\Customer" "$(cat some_email_body.md)" 

将所有输入/模式/输出自动保存到 sqlite 数据库中。像 llm 一样?利用它来测试示例、添加 few shots、evals?