概要
Outlines は、大規模言語モデルが指定された構造(JSON、正規表現、Pydantic モデルなど)に準拠した出力を生成することを保証する Python ライブラリです。複数のモデルバックエンドをサポートし、既存のワークフローとシームレスに統合します。
README プレビュー
\n\n\n\n\n\n 🗒️ *Structured outputs for LLMs* 🗒️\n\nMade with ❤👷️ by the team at [.txt](https://dottxt.co)\nTrusted by NVIDIA, Cohere, HuggingFace, vLLM, etc.\n\n\n[![PyPI Version][pypi-version-badge]][pypi]\n[![Downloads][downloads-badge]][pypistats]\n[![Stars][stars-badge]][stars]\n\n\n[![Discord][discord-badge]][discord]\n[![Blog][dottxt-blog-badge]][dottxt-blog]\n[![Twitter][twitter-badge]][twitter]\n\nThe .txt API is currently in early access. **[Request access here →](https://h1xbpbfsf0w.typeform.com/to/fwQNWmS8?utm_source=github&utm_medium=organic&utm_campaign=outlines)**\n\n\n\n\n## 🚀 Building the future of structured generation\n\nWe're working with select partners to develop new interfaces to structured generation.\n\nNeed XML, FHIR, custom schemas or grammars? Let's talk.\n\nAudit your schema: share one schema, we show you what breaks under generation, the constraints that fix it, and compliance rates before and after. Sign up [here](https://h1xbpbfsf0w.typeform.com/to/rtFUraA2?typeform).\n\n## Table of Contents\n\n- [Why Outlines?](#why-outlines)\n- [Quickstart](#quickstart)\n- [Real-World Examples](#real-world-examples)\n - [🙋♂️ Customer Support Triage](#customer-support-triage)\n - [📦 E-commerce Product Categorization](#e-commerce-product-categorization)\n - [📊 Parse Event Details with Incomplete Data](#parse-event-details-with-incomplete-data)\n - [🗂️ Categorize Documents into Predefined Types](#categorize-documents-into-predefined-types)\n - [📅 Schedule a Meeting with Function Calling](#schedule-a-meeting-with-function-calling)\n - [📝 Dynamically Generate Prompts with Re-usable Templates](#dynamically-generate-prompts-with-re-usable-templates)\n- [They Use Outlines](#they-use-outlines)\n- [Model Integrations](#model-integrations)\n- [Core Features](#core-features)\n- [Other Features](#other-features)\n- [About .txt](#about-txt)\n- [Community](#community)\n\n\n\n## Why Outlines?\n\nLLMs are powerful but their outputs are unpredictable
FAQ (5)
トラブル対応OutlinesでJsonSchemaのwhitespace_patternを変更した際に、古いキャッシュヒットや誤ったregex出力が発生する問題を修正するにはどうすればよいですか?
JsonSchema.__eq__ はパース済みのスキーマ JSON のみを比較し、whitespace_pattern を考慮していないため、パターンの異なるスキーマが同一として扱われ、キャッシュや重複排除で誤った logits プロセッサが再利用される可能性があります。等価性の判定でパターンも比較するように修正してください:
def __eq__(self, other):
if not isinstance(other, JsonSchema):
return False
try:
self_dict = json.loads(self.schema)
other_dict = json.loads(other.schema)
return (
self_dict == other_dict
and self.whitespace_pattern == other.whitespace_pattern
)
except json.JSONDecodeError:
return (
self.schema == other.schema
and self.whitespace_pattern == other.whitespace_pattern
)
パッチが適用されるまでは、JsonSchema のみをキーとしてプロセッサをキャッシュするのは避けてください。(schema.schema, schema.whitespace_pattern) のようなキャッシュキーを使用するか、パターンが変更された際に該当するキャッシュをクリアしてください。
トラブル対応MkDocsでPythonパッケージをsrcレイアウトに移行した後、API Referenceが空になるのはなぜですか?
scripts/gen_ref_pages.py を更新し、mkdocs-gen-files が新しいパッケージの場所をスキャンするようにします。古いパス root / "outlines" を root / "src" / "outlines" に置き換えてください。変更後、MkDocs でドキュメントを再ビルドし、site/api_reference/models/index.html などのページが生成されていることを確認します。この問題は、srcレイアウトへの移行によってパッケージが outlines/ から src/outlines/ に移動し、古い glob が空になったことが原因で発生します。
トラブル対応Outlines の json_schema_dict_to_dataclass がオプションフィールドに対して `age: int = None` を生成するのはなぜですか?また、どうすれば修正できますか?
src/outlines/types/json_schema_utils.py では、json_schema_dict_to_dataclass が必須ではないフィールドのデフォルト値として None を割り当てますが、それらの型を Optional でラップしていません。必須ではないプロパティが Optional[typ] を使用するように、コンバーターを更新してください:
from typing import Optional
for property, details in properties.items():
typ = schema_type_to_python(details, "dataclass")
if property not in required:
typ = Optional[typ]
defaults[property] = None
annotations[property] = typ
これにより、オプションの JSON Schema の整数は age: Optional[int] = None を生成するようになり、Pydantic コンバーターと一致し、構造化生成において null を使用できるようになります。修正が適用されるまでの一時的な回避策として、必須ではない dataclass フィールドを手動で Optional[T] = None として宣言するか、convert_to(schema, "pydantic") を使用してください。
トラブル対応Outlines の `Literal[1.5]` が `"1x5"` のような文字列に誤ってマッチしてしまう問題を修正するには?
数値はエスケープされずに正規表現に変換されるため、1.5 内の . は正規表現のワイルドカードとして機能します。src/outlines/types/dsl.py で、数値項の構築を Regex(str(value)) から Regex(re.escape(str(value))) に変更し、re がインポートされていることを確認してください:
import re
# Inside python_types_to_terms handling for int/float:
term = Regex(re.escape(str(value)))
これにより 1\.5 が生成されるため、Literal[1.5] は "1.5" のみにマッチし、"1x5" を拒否します。修正がリリースされるまでは、float リテラル制約の代わりに、Regex(r"1\.5") のような明示的にエスケープされた正規表現を使用してください。
トラブル対応outlines.types.ipv6 が先頭にゼロを含む無効な IPv4-mapped IPv6 アドレスを受け入れてしまう問題を修正するにはどうすればよいですか?
ipv6 の正規表現は古い IPv4 オクテットパターンを再利用しているため、::ffff:01.1.1.1 や ::ffff:00.0.0.0 のようなサフィックスが誤ってマッチしてしまいます。
src/outlines/types/__init__.py 内の ipv6 定義に含まれる古いオクテットパターンの両方の出現箇所を置き換えて修正してください:
古いパターン:25[0-5]|2[0-4][0-9]|1?[0-9]{1,2}
新しいパターン:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]
これは IPv4-mapped の両方の分岐で更新する必要があります:
- ::ffff:a.b.c.d
- x:x:x:x::a.b.c.d
新しいパターンは 0、1、42、192 のような正規のオクテットを受け入れますが、00、01、007 のような先頭にゼロが付く形式は拒否します。
パッチを適用するまでの一時的な回避策として、Python の標準ライブラリを使って生成されたアドレスを検証してください:
import ipaddress
def is_valid_ip(value: str) -> bool:
try:
ipaddress.ip_address(value)
return True
except ValueError:
return False
正規表現の修正を適用した後も、::ffff:192.168.1.1 と 1:2:3:4::5.6.7.8 は引き続きマッチし、::ffff:01.1.1.1、::ffff:00.0.0.0、1:2:3:4::5.6.007.8 は拒否されます。