忙しい人向けのまとめ
LLM の出力を確実に JSON にしたい!! → Outlines が使えるぞ!
はじめに
LLM を使ったアプリケーションを開発していると、出力を JSON や Pydantic などの決まった形式で受け取りたい場面がよくあります。しかし、LLMが勝手に説明文を付け加えたり、形式を微妙に変えたりして、パースエラーや予期しない出力に悩まされることも多いのではないでしょうか。
従来はこうした問題に対して正規表現での整形やリトライ処理など、本来のロジックとは関係ない処理を書く必要がありました。
Outlines
は、これらの問題を解決し、LLM の出力をシンプルなコードで確実に構造化出力を成功させることのできる便利なライブラリです。Outlines は OpenAI の API や transformers, Ollama, vLLM といった様々なバックエンドで利用可能です。
インストール
以下のコマンドでインストールできます。
pip install outlines
uv add outlines
使用例
基本的な使い方
outlines
を使って構造化出力を得る際に、パース処理や正規表現を使ったコードを書く必要はなく、基本的に以下のようなシンプルなコードで実現可能です。
model("Prompt", output_type)
モデルをインスタンス化する際は、Outlines の from_*
関数でラップする必要があります。
様々な Outlines の from_* 関数
Pydantic を使った構造化出力
Outlines のドキュメント に従って、OpenAI API を使って構造化出力を試してみます。
from outlines import from_openai
import openai
from pydantic import BaseModel
class ClubActivity(BaseModel):
name: str
category: str
established_year: int
model = from_openai(
openai.OpenAI(),
"gpt-4o"
)
prompt = "架空の部活「ちくわ部」について教えて"
output = model.generate(prompt, ClubActivity)
print(output)
print(type(output))
以下の出力を得ました。
{"name":"ちくわ部","category":"食文化研究会","established_year":2020}
様々なデータ型での出力
Outlines では output_type
(第二引数) を指定することで、int
などの Python 標準な型や、Pydantic のクラス、選択肢からのトークン選択など様々な出力制限が可能です。
model("How many minutes are there in one hour", int)
model("Pizza or burger", Literal["pizza", "burger"])
model("Create a character", Character, max_new_tokens=100)
正規表現での出力制限
正規表現のような自由な出力形式も指定可能です。
from outlines.types import Regex
regex = r"[0-9]{3}"
output_type = Regex(regex)
マルチモーダル・チャット入力
画像、音声などのマルチモーダルな入力形式やチャット形式の入力なども可能です。
import io
import requests
import PIL
import outlines
import openai
from outlines.inputs import Image
model = outlines.from_openai(
openai.OpenAI(),
"gpt-4o"
)
def get_image(url):
r = requests.get(url)
return PIL.Image.open(io.BytesIO(r.content))
prompt = [
"Describe the image",
Image(get_image("https://picsum.photos/id/237/400/300"))
]
response = model(prompt, max_tokens=50)
print(response)
チャット形式の入力も可能です。
from outlines.inputs import Chat, Image
prompt = Chat([
{"role": "system", "content": "You are a helpful assistant."},
{
"role": "user",
"content": ["Describe the image", Image(get_image("https://picsum.photos/id/237/400/300"))]
},
])
print(prompt)
まとめ
このように、Outlines を使うと構造化出力にまつわる複雑なコーディングやモデル側の生成/パース失敗を気にする必要がなくなり、かなり便利です。OpenAI API の場合はネイティブの Structured Output を使っても使用感は変わらないかもしれません。
余談ですが、Outlines は DeNA さんの DeNA × AI Talks #1 – AIスペシャリストが語る、最新技術 –で知りました。面白い勉強会をありがとうございます。
参考文献
Views: 0