モデル / データセット
jackmpcollins/magentic avatar
jackmpcollins/magentic

magentic: Python の関数シグネチャに LLM を埋め込む @prompt デコレータ

Seamlessly integrate LLMs as Python functions

スター 2,425フォーク 127PythonMIT

ひと目でわかる

これは何?
magentic は @prompt と @chatprompt で LLM 呼び出しを通常の Python 関数として扱えるようにする MIT ライセンスのライブラリだ。型注釈と pydantic モデルがそのまま出力スキーマになり、FunctionCall と @prompt_chain でツール呼び出しを組み立てられる。向いているのは既存の Python コードベースに LLM を差し込みたいチームで、独自のエージェントランタイムを丸ごと採用したい場合には向かない。
誰に向いている?
採用を検討すべきなのは、すでに Python と pydantic で書かれたコードベースがあり、LLM の出力を既存の型に合わせて受け取りたいチームだ。逆に、グラフ構造のワークフローや永続的な状態管理をフレームワーク側に求める場合は、magentic のデコレータ中心の設計は物足りない。
商用利用できる?
できます。MIT は寛容なライセンスで、著作権表示とライセンス表示を残せば、使用・改変・販売が可能です。
今もメンテナンスされている?
活動が鈍っています。最後のコミットは 6 か月前です。
何の言語で書かれている?
主に Python です(GitHub の言語統計による)。

回答はプロジェクトの GitHub データ(最終同期:2026年9月15日)と当サイトの分析に基づくもので、法的助言ではありません。

オープンソース詳細解説

LLM 呼び出しを「関数」として扱うという発想

magentic が解こうとしているのは、LLM の出力を既存の Python コードに戻すときの型の断絶だ。通常はプロンプト文字列を組み立て、レスポンスの JSON をパースし、失敗したらリトライし、型を検証するという配管を毎回書くことになる。magentic はこの配管をデコレータに押し込む。README の例では、関数本体を書かずに `...` だけを置いた `def dudeify(phrase: str) -> str: ...` がそのまま LLM 呼び出しになる。呼び出し側のコードは普通の Python 関数呼び出しと区別がつかない。対象読者は、チャット UI を作りたい人ではなく、業務ロジックの途中に LLM の判断を差し込みたい人だ。たとえば問い合わせ文の分類、自由記述からの構造化データ抽出、検索クエリの生成など、入出力が型で決まっている処理に向く。

戻り値の型注釈がそのまま出力スキーマになる仕組み

`@prompt` は装飾した関数の戻り値アノテーションを読み取り、それを出力スキーマとして使う。README は pydantic が対応する任意の型を使えると説明しており、例では `Superhero` という `BaseModel` を返す関数が `name`、`age`、`power`、`enemies` を持つインスタンスを返している。つまりプロンプト本文には「JSON で返してください」といった指示を書かなくてよい。スキーマは Python の型から導出される。`@chatprompt` はこれに加えてメッセージ列をテンプレートとして渡せる。`SystemMessage`、`UserMessage`、`AssistantMessage` を並べ、`{movie}` のような波括弧のフィールドが全メッセージに展開される。README の注記では `FunctionResultMessage` だけは例外とされている。few-shot の例をそのままテンプレートに埋め込めるので、出力の癖をプロンプトではなくサンプルで誘導したい場合に都合がよい。

FunctionCall と @prompt_chain の役割分担

ツール呼び出しは2段階で設計されている。`@prompt` に `functions=[...]` を渡すと、LLM は関数を実行せずに `FunctionCall` オブジェクトを返す。README の例では `perform_search` が `FunctionCall(<function search_twitter at 0x10c367d00>, 'LLMs', 'latest')` を返し、利用者が `output()` を呼んで初めて実際の関数が走る。実行のタイミングと引数を人間側が検査できる。一方 `@prompt_chain` はこの `FunctionCall` を自動で解決し、結果を LLM に戻して最終回答まで進める。`describe_weather` の例では `get_current_weather` が呼ばれ、その戻り値を使って天気の説明文が生成される。この2つを使い分ける基準は明確で、ツールの引数を検証したいなら `@prompt`、多段の推論を一気に走らせたいなら `@prompt_chain` になる。デコレータ付きの関数を別のデコレータの `functions` に渡せる点も README に明記されており、部品ごとにテストを分けられる。

導入: pip と環境変数、そして設定の所在

インストールは `pip install magentic`、uv を使う場合は `uv add magentic` の2通りが README に示されている。OpenAI を使う場合は `OPENAI_API_KEY` 環境変数を設定する。README はこれ以外のプロバイダについて Configuration のページを参照するよう案内しており、本文中には具体的な設定キーは書かれていない。OpenAI、Anthropic、Ollama が対応先として機能一覧に挙がっているが、それぞれの設定方法はこの README からは確認できない。設定キーの詳細を知るには https://magentic.dev/configuration を読む必要がある。観測性については OpenTelemetry と Pydantic Logfire の統合が挙げられており、こちらも専用ページへのリンクのみだ。導入時に読むべきページが README 本体ではなく外部ドキュメントに分散している点は、オフライン環境や閉域網で作業する場合に手間になる。

ストリーミングと非同期は同じ関数のまま使えるか

`StreamedStr` と `AsyncStreamedStr` を使うと、生成途中のテキストを逐次処理できる。README の機能一覧には構造化出力のストリーミングと関数呼び出しのストリーミングの両方が挙がっており、単なる文字列だけでなく構造化された値を生成しながら扱えると読める。ただし README の本文で示されているのは `StreamedStr` の宣言までで、構造化出力をストリーミングしたときに部分的な pydantic モデルがどう振る舞うかは記載がない。Asyncio 対応も機能一覧にあるが、同期版と非同期版で再試行や FunctionCall の解決が同じ挙動をするかは README からは判断できない。ストリーミングを前提に UI を作るなら、部分的なスキーマの扱いを Streaming のページで先に確認しておきたい。ここは設計上の要検討点であって、README だけでは埋まらない。

向かない場面: 状態を持つエージェントランタイムを求める場合

magentic はデコレータの集合であって、実行エンジンではない。会話の履歴を永続化する仕組み、複数エージェントの役割分担、グラフで分岐するワークフロー、中断と再開といった機能は、README の機能一覧にも Usage の例にも出てこない。`@prompt_chain` が自動で解決するのは関数呼び出しの連鎖であって、条件分岐やループを宣言的に組む仕組みではない。したがって、チェックポイント付きの長時間タスクや、人間の承認を挟むフローを求めている場合、magentic の上に自分で状態管理を書くことになる。これは欠陥ではなく設計の重心の違いだが、フレームワークに状態管理を期待して導入すると、デコレータだけでは足りない部分をすべて自作する羽目になる。判断の分かれ目は、会話や実行履歴をどこに持つかを自分で決めたいかどうかだ。

代替としての LangChain: 抽象化の層が違う

比較対象として分かりやすいのは LangChain だ。magentic が関数の型注釈を出力スキーマとして使うのに対し、LangChain はプロンプトテンプレート、出力パーサー、チェーン、エージェント、メモリといった部品を個別のオブジェクトとして組み合わせる。抽象化の単位が関数ではなくコンポーネントなので、既存の LangChain コンポーネントを差し替えたり、コミュニティのインテグレーションを多数のプロバイダやベクターストアに対して使いたい場合には LangChain のほうが選択肢が多い。逆に、LLM の出力を既存の pydantic モデルに合わせるだけの用途では、LangChain のチェーン定義は記述量が増える。magentic の README が繰り返し述べているのは、LLM 呼び出しを普通の Python 関数と同じように扱うという一点であり、この粒度の細かさが両者の実質的な違いだ。どちらが優れているかではなく、抽象化をどの層に置きたいかで選ぶ。

メンテナンス費用とライセンスの確認点

ライセンスは MIT で、商用利用や改変、再配布に関する制限はこの表記からは読み取れない。ただし MIT の条文そのものをここで解釈するのは避ける。注意すべきは依存の側で、pydantic のバージョンに追従する必要がある。magentic は戻り値の型注釈を pydantic 経由で解釈するため、pydantic のメジャー更新はこのライブラリの互換性に直結する。リリース履歴を見ると v0.40.0 が 2025-06-22、v0.41.0 が 2025-10-14、v0.41.1 が 2026-03-11 で、0.x 系のままマイナー番号が進んでいる。0.x の間はマイナー更新で破壊的変更が入り得るので、`pip install magentic` ではなくバージョンを固定して導入し、更新時はリリースノートを確認する運用が現実的だ。LLM-Assisted Retries は複雑なスキーマへの適合率を上げる機能だが、再試行のたびに API 呼び出しが発生するため、コストとレイテンシの見積もりには再試行回数を含めておく必要がある。

編集部の結論

採用を検討すべきなのは、すでに Python と pydantic で書かれたコードベースがあり、LLM の出力を既存の型に合わせて受け取りたいチームだ。逆に、グラフ構造のワークフローや永続的な状態管理をフレームワーク側に求める場合は、magentic のデコレータ中心の設計は物足りない。導入前に確認すべきは、README が示す OpenAI 以外のプロバイダ設定のページで自分のモデルが対応しているか、そして LLM-Assisted Retries のページで再試行が何回・どの条件で走るのかを読むことだ。この2点はコードを書く前に決めておかないと、複雑な pydantic スキーマを組んだ後に手戻りになる。

公式情報源

  1. jackmpcollins/magentic on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
コミュニティノート

コミュニティノート