Skip to main content

LLMの出力をPydanticモデルで型安全に扱うためのPythonライブラリ

Project description

dariko

LLMの出力をPydanticモデルで型安全に扱うためのPythonライブラリ。

特徴

  • LLMの出力をPydanticモデルで型安全に扱える
  • 型アノテーションから自動的に出力モデルを推論
  • バッチ処理に対応
  • 検証失敗時の自己修復リトライ (エラー内容を添えて LLM に再生成を促す)
  • 構造化出力の強制 (OpenAI Structured Outputs / Claude tool-use)
  • 非同期 API (aask / aask_batch) と ストリーミング (ask_stream)
  • 部分オブジェクトのストリーミング (partials()) — 埋まりかけのモデルを逐次取得
  • list[Model] 出力 (output_model=list[Person]) でリスト検証
  • max_tokens / temperature / timeout / max_retries を設定可能
  • シンプルなAPI
  • 環境変数から自動的にAPIキーを読み込み
  • 複数のLLM(GPT, Claude, Gemma等)に対応

インストール

# GPT / Claude (API 経由) のみ — 軽量
pip install dariko

# Gemma (ローカル推論。torch / transformers を含む)
pip install "dariko[gemma]"

使用方法

基本的な使い方

import os
from pydantic import BaseModel
from dariko import ask, set_config

# APIキーの設定(環境変数から取得)
llm_key = os.environ.get("DARIKO_API_KEY")
set_config(model="gpt-4o-mini", llm_key=llm_key)

# 出力モデルの定義
class Person(BaseModel):
    name: str
    age: int
    dummy: bool

# 型アノテーションから自動的にモデルを推論
result: Person = ask("以下の形式のJSONを返してください:\n" + '{"name": "山田太郎", "age": 25, "dummy": false}')
print(result.name)  # "山田太郎"
print(result.age)   # 25
print(result.dummy) # False

明示的にモデルを指定

result = ask("test", output_model=Person)

バッチ処理

from dariko import ask_batch

prompts = [
    "以下の形式のJSONを返してください:\n" + '{"name": "山田太郎", "age": 25, "dummy": false}',
    "以下の形式のJSONを返してください:\n" + '{"name": "佐藤花子", "age": 30, "dummy": true}',
]

results = ask_batch(prompts, output_model=Person)

# 結果の表示
for i, result in enumerate(results, 1):
    print(f"\n人物 {i}:")
    print(f"名前: {result.name}")
    print(f"年齢: {result.age}")
    print(f"ダミー: {result.dummy}")

ローカルモデル(Gemma)の使用例

import os
from pydantic import BaseModel
from dariko import ask, set_config

# Hugging Faceのアクセストークンを設定
llm_key = os.environ.get("DARIKO_API_KEY")
set_config(model="google/gemma-2b", llm_key=llm_key)

class Person(BaseModel):
    name: str
    age: int
    dummy: bool

result: Person = ask("以下の形式のJSONを返してください:\n" + '{"name": "山田太郎", "age": 25, "dummy": false}')
print(result)

Claudeモデルの使用例

import os
from pydantic import BaseModel
from dariko import ask, set_config

# AnthropicのAPIキーを設定
llm_key = os.environ.get("DARIKO_API_KEY")
set_config(model="claude-3-opus-20240229", llm_key=llm_key)

class Person(BaseModel):
    name: str
    age: int
    dummy: bool

result: Person = ask("以下の形式のJSONを返してください:\n" + '{"name": "山田太郎", "age": 25, "dummy": false}')
print(result)

型推論の実践例

関数の戻り値型アノテーションによる推論

def get_person() -> Person:
    return ask('以下の形式のJSONを返してください:\n{"name": "山田太郎", "age": 25, "dummy": false}')

person = get_person()
print(person.name)  # "山田太郎"

変数アノテーションによる推論

result: Person = ask('以下の形式のJSONを返してください:\n{"name": "佐藤花子", "age": 30, "dummy": true}')
print(result.name)  # "佐藤花子"

バッチ処理でも型推論が効く

from typing import List

def get_people() -> List[Person]:
    prompts = [
        '以下の形式のJSONを返してください:\n{"name": "山田太郎", "age": 25, "dummy": false}',
        '以下の形式のJSONを返してください:\n{"name": "佐藤花子", "age": 30, "dummy": true}',
    ]
    return ask_batch(prompts)

people = get_people()
for p in people:
    print(p.name)

注意点

  • 型アノテーションが取得できない場合は output_model を明示的に指定してください。
  • 型推論は「関数の戻り値型」→「変数アノテーション」→「AST解析」の順で行われます。
  • 型アノテーションはPydanticのBaseModelサブクラスである必要があります。

型推論の仕組み

Darikoは以下の優先順位で型を推論します:

  1. 呼び出し元関数のreturn型ヒント
  2. 現フレームのローカル変数アノテーション(1個だけの場合)
  3. AST解析による推定

詳細な実装については、examples/logic.mdを参照してください。

環境変数

以下の環境変数を設定することで、Darikoの動作を制御できます:

  • DARIKO_API_KEY: APIキー(必須)
    • OpenAI APIキー
    • Anthropic APIキー
    • Hugging Faceアクセストークン
  • DARIKO_MODEL: 使用するモデル名(デフォルト: "gpt-4")
    • OpenAIモデル: "gpt-4", "gpt-3.5-turbo" など
    • Claudeモデル: "claude-3-opus-20240229", "claude-3-sonnet-20240229" など
    • Gemmaモデル: "google/gemma-2b" など

開発

セットアップ

git clone https://github.com/yourusername/dariko.git
cd dariko
pip install -e .

テスト

pytest tests/

リリースプロセス

  1. 変更をコミットしてプルリクエストを作成:
./scripts/release.sh
  1. スクリプトの実行手順:

    • コミットタイプを選択(新機能/バグ修正/破壊的変更)
    • 変更内容を入力
    • 破壊的変更の場合は詳細を入力
  2. バージョン管理の仕組み:

    • コミットメッセージに基づいて自動的にバージョンが更新されます
    • feat: → マイナーバージョンアップ(0.1.0 → 0.2.0)
    • fix: → パッチバージョンアップ(0.1.0 → 0.1.1)
    • BREAKING CHANGE: → メジャーバージョンアップ(0.1.0 → 1.0.0)
  3. リリースの流れ:

    • プルリクエストが作成されます
    • レビュー後にマージ
    • マージされると自動的に:
      • バージョンが更新
      • GitHubリリースが作成
      • PyPIにパッケージがアップロード
  4. 注意点:

    • コミットメッセージはAngularのコミットメッセージ規約に従ってください
    • 複数のコミットがある場合、最も大きな変更に基づいてバージョンが更新されます
    • GitHub CLI(gh)のインストールと認証が必要です

高度な設定

set_config で生成パラメータと自己修復リトライ回数を指定できます。

from dariko import set_config

set_config(
    model="gpt-4o-mini",
    llm_key="sk-...",
    max_tokens=2048,    # 生成する最大トークン数
    temperature=0.0,    # 0.0 で決定的
    timeout=60.0,       # HTTP タイムアウト秒
    max_retries=2,      # 検証失敗時に LLM へ再生成を促す回数
)

自己修復リトライ

ask / ask_batch は、LLM 出力が JSON として壊れていたり Pydantic 検証に 失敗した場合、エラー内容を会話に添えて max_retries 回まで再生成を促します。 それでも成功しなければ ValidationError を送出します (fail fast)。

構造化出力の強制

  • GPT: response_format: json_schema (Structured Outputs) でスキーマ準拠を促す
  • Claude: tool-use を強制し、スキーマに従った JSON を確実に取得する

非同期 API

import asyncio
from dariko import aask, aask_batch

async def main():
    # 単発
    person = await aask("...", output_model=Person)

    # 複数プロンプトを並行実行 (concurrency で同時実行数を制限)
    people = await aask_batch(["...", "..."], output_model=Person, concurrency=4)

asyncio.run(main())

ストリーミング

from dariko import ask_stream

stream = ask_stream("...", output_model=Person)
for chunk in stream:        # 生成テキストを逐次受け取る
    print(chunk, end="", flush=True)

person = stream.result()    # 完了後に検証済みオブジェクト

部分オブジェクトのストリーミング

埋まりかけのモデル (全フィールド Optional) を逐次受け取れます。UI のプログレッシブ表示に便利です。

stream = ask_stream("...", output_model=Person)
for partial in stream.partials():
    print(partial)   # name だけ -> name+age -> 全部、と段階的に埋まる

person = stream.result()

ストリーミングでは自己修復リトライは行わず、完了時に1回だけ検証します。

リスト出力

people = ask("3人分の人物を返して", output_model=list[Person])
# -> list[Person] として検証される

ライセンス

MIT License

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dariko-3.2.0.tar.gz (27.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dariko-3.2.0-py3-none-any.whl (23.6 kB view details)

Uploaded Python 3

File details

Details for the file dariko-3.2.0.tar.gz.

File metadata

  • Download URL: dariko-3.2.0.tar.gz
  • Upload date:
  • Size: 27.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for dariko-3.2.0.tar.gz
Algorithm Hash digest
SHA256 2fc83a3b8c88bafcaff1a9e39468b333b4d8e2f0063a899ca9191d766e68e2b2
MD5 0e3e18497f1ac134cedfc049e0083103
BLAKE2b-256 263838a253c8071ac14b33b4982d138205735c85667e4bcf83691f150c2fe6b6

See more details on using hashes here.

File details

Details for the file dariko-3.2.0-py3-none-any.whl.

File metadata

  • Download URL: dariko-3.2.0-py3-none-any.whl
  • Upload date:
  • Size: 23.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for dariko-3.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8e4e7b92855078969e9eee18cdfbbfcd735ab3bea6e38e5e112a66161d756d76
MD5 a311844cbe335e6ba424f71273439dc4
BLAKE2b-256 a483645a4538e700a8554dcff7c8be920e3a9a649b27e311e3bb1a4f81bc4118

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page