💡

ChatGPT時代のAI Agent設計: LLMチャットUI vs OpenAI API vs フレームワーク5種の選定基準

に公開

1.はじめに

朝起きると、新しいAI Agentフレームワークが生まれている。 そんな「カンブリア爆発」のような現代に、私たちは今生きています。

LangGraph, AutoGen, CrewAI, CrewAI, smolagents, LlamaIndex Workflows...。様々なAI Agentで溢れています。

正直、こう思いませんか?

「種類が多すぎて何を選べばいいか分からない」 「そもそもそれって本当に必要なの?」

LLMチャットUIやRaw APIという強力なライバル: Agentフレームワークを導入する前に強力な2つの既存の選択肢が浮かび上がります。

「ChatGPTでよくない?」説: 今の gpt-5.1 や claude opus 4.5 は非常に賢いです。ブラウジングもコード実行も標準機能でこなせます。「わざわざPythonで環境構築してAgentを作るくらいなら、Web画面にプロンプトを投げた方が早いし精度も高い」という現実があります。

「素のAPI (import openai) でよくない?」説: ライブラリの変更に振り回されるのは嫌だ、という硬派な意見です。 「結局やっていることはAPIを叩いているだけ。なら import openai して for ループと if 文を書けばいい。」という主張です。

なぜ、あえて比較するのか。
それでもなお、世界中でフレームワークが開発され続けているのには理由があるはずです。

そこで本記事では、「LLMチャットUI」 と 「素のAPI (Raw Python)」 をあえて比較のベースラインに置きます。その上で、現在注目を集める 5つの主要フレームワーク に全く同じタスクを投げ、以下の点を評価していきたいと思います。

LLMチャットUIでは越えられないラインはどこか?
素のAPIだとコードが破綻するラインはどこか?
各フレームワークは「何」を楽にするために設計されているのか?

「流行っているから使う」のではなく、「必要だから使う」ための選定基準を、実際のコードと挙動をもとに調べていきたいと思います。

なお、本記事は2025年12月1日時点の想定で執筆しています。

2.比較対象となるAI Agentと基準

本記事では、設計思想の異なる代表的なフレームワークを選択しました。

また、それらを評価するためのベースラインとして、LLMチャットUIと素のAPIも比較対象にします。

【基準点】比較のベースライン

まず、これらに勝てなければフレームワークを導入する意味はありません。

  • 0-1. LLMチャットUI (ChatGPT / Claude/ Gemini)
    特徴: セットアップ不要。プロンプトを投げれば、裏側で高度なRAGやCode Interpreterが走り、高品質の答えを返す。
    弱点: 「自動化」と「連携」ができない。人間が画面の前に張り付いてコピペする必要がある。API経由の自律動作は不可。

  • 0-2. Raw API
    特徴: import openai だけで書く、究極のホワイトボックス。
    弱点: 「複雑性」への耐性がない。会話履歴の管理、ツール実行結果のパース、エラー時のリトライ処理などを全て手書きすると、コードがスパゲッティ化する。

【比較対象】Agentフレームワーク 5選

数あるツールの中から、開発が活発であり、かつアプローチが異なる5つを選出しました。

1. LangGraph

特徴: グラフ指向。LangChainの「一直線のChain」では限界だったループ処理や条件分岐を、ノードとエッジで定義する。状態管理が非常に強力。

2. CrewAI

特徴: ロールプレイ指向。「リサーチャー」「ライター」のような役割とタスクを定義し、チームとして協調させる。LangChainベースだが、抽象度が高く書きやすい。

3. smolagents

特徴: Code Agent指向。従来の「JSONを出力してツールを呼ぶ」形式ではなく、LLMに「Pythonコードを書かせて実行する」スタイル。非常に軽量。

4. PydanticAI

特徴: 実務・型安全指向。LangChain独自のDSLを排除し、純粋なPythonとPydanticの型定義だけでAgentを構築する。

5. AutoGen

特徴: 会話指向。エージェント同士がチャットツールのように会話を重ねることでタスクを解決する。マルチエージェントの代名詞として参戦。

なぜこの5つなのか?

今回の選定理由は以下の通りです。

  • 「更新頻度」の鮮度: 2023年のAgentブーム(AutoGPT等)で登場したツールの多くは、開発が停滞気味です。今回は2025年現在もコミットが活発で、現場で使えるレベルに進化し続けているものを優先しました。
  • 「アーキテクチャ」の多様性: 似たようなツールを比べても面白くありません。
  • グラフ型 (LangGraph)
  • ロールプレイ型 (CrewAI)
  • コード生成型 (smolagents)
  • 型安全型 (PydanticAI)
  • 会話型 (AutoGen)
    と、設計思想が異なるものをバラけさせました。これにより、「自分の好み・要件に合うのはどれか」が見えやすくなります。

3.検証タスクの設定:3つのTask

各フレームワークの実力を公平に測るため、共通のレギュレーションと、難易度別の3つのタスクを用意しました。
🏁 共通レギュレーション

  • LLMモデル: gpt-4o (OpenAI) で統一。
  • 検索ツール: Tavily Search API
  • 実行環境: ローカルのPython環境、バージョンは3.11

Task1: 外部ツール連携の壁

  • Task: Web検索と要約
  • 指令: 「『2025年のAI Agentフレームワークの最新トレンド』についてWeb検索し、その要点を日本語で300文字以内にまとめてください。」
  • 狙い:最も基本的な「Tool Calling (Function Calling)」のテスト

LLMチャットUIなら簡単にできることですが、コードで実装しようとするとツール定義の煩雑さが露見します。

観戦ポイント:

  • Raw API: ツールのJSONスキーマを手書きする苦行
  • Framework: ツール定義がどれだけシンプルになるか

Task2: ローカル操作と論理の壁

  • Task: コード実行による計算とファイル操作
  • 指令: 「フィボナッチ数列の第50項を計算し、その結果をローカルのテキストファイル fib_result.txt に保存してください。注意: LLMの知識で回答せず、必ずPythonコードを実行して計算すること。」
  • 狙い:ハルシネーションの回避とサンドボックスからの脱出をテスト
    巨大な桁の計算はLLMの苦手分野です。正しく「計算機(Python)」を使えるかが鍵です。
    また、LLMチャットUI(ChatGPT)はクラウド上で完結するため、ユーザーのPCのフォルダに勝手にファイルを生成することはできません。
    観戦ポイント:
  • smolagents: "Code as Action" の真骨頂。Pythonコードを生成して実行する流れが最も自然なはずです。
  • LLMチャットUI: 「計算はできたが、ファイル保存は手動ダウンロード」という限界点。

Task3: 自律ループと修正の壁

  • Task: 複合プランニングと自己修正

  • 指令: 「東京から京都へ1泊2日の旅行プランを立ててください。

    • 条件:
      • 予算は交通費・宿泊費込みで 5万円以内。
      • 観光スポットを3つ以上回る。
      • もし予算オーバーしたら、プランを自動で見直して再提案すること。」
  • 狙い:「思考のループ (Loop)」 のテスト
    一発で正解を出すのは難しく、「プラン作成 → 計算 → 予算判定 → 修正」という試行錯誤のフローが必要になります。
    観戦ポイント:

  • Raw API: 条件分岐と再実行を while ループで書くと、コードがいかに汚くなるか。

  • LangGraph: グラフ構造(ステートマシン)でループをどう綺麗に制御できるか。

  • CrewAI / AutoGen: 複数のエージェントが、会話だけで解決できるか、あるいは無限に会話して終わらないか。

4.コードの比較

出力結果を見る前に、まずは「実装コード」を比較します。 同じタスクを実装するのに、フレームワークによって記述量とアプローチが驚くほど異なりました。コード全体は8.実行コードの方に掲載しています。

1.ツール定義

比較対象: Raw API vs PydanticAI/smolagents
ここが最も「フレームワークを使ってよかった」と感じる瞬間です。

Raw API

これを手書き・メンテするのは大変です

tools = [
    {
        "type": "function",
        "function": {
            "name": "web_search",
            "description": "Searches the web...",
            "parameters": {
                "type": "object",
                "properties": {
                    "query": {"type": "string"} # 型も手動指定
                },
                "required": ["query"]
            }
        }
    }
]

Pros: 依存ライブラリなし。ブラックボックスなし。
Cons: パラメータが1つ増えるたびにJSON構造を修正する必要があり、ミスが頻発する。可読性が最悪。

PydanticAI / smolagents

Pythonの型ヒントを書くだけでOK

@agent.tool
def web_search(ctx: RunContext[str], query: str) -> str:
    """Web検索を行い、結果を返します。"""
    # ... (中身の実装)

Pros: str, int などの型ヒントとdocstringから、ツール定義を自動生成してくれる。IDEの補完も効く。
Cons: PydanticAIはバージョンアップが激しく、RunContext の指定方法などが頻繁に変わる(今回の検証でも苦労した点)。

2.エージェント定義の構造

比較対象: CrewAI vs LangGraph
「エージェントをどう定義するか」に思想の違いが色濃く出ます。

CrewAI

researcher = Agent(
    role='Senior Web Researcher',
    goal='Web情報を正確に調査し要約する',
    backstory='あなたは技術のトレンドに詳しい専門家です。',
    verbose=True
)

Pros: 自然言語で「役割」を書くだけ。プログラミングというよりマネジメントに近い感覚で直感的に書ける。
Cons: 裏側でどんなプロンプトが流れているか隠蔽されており、微調整が難しい。トークン消費量が多くなりがち。

LangGraph

ノードとエッジを明示的に配線する

workflow = StateGraph(AgentState)
workflow.add_node("agent", agent_node)
workflow.add_node("tools", ToolNode(tools))

workflow.add_edge(START, "agent")
workflow.add_conditional_edges("agent", should_continue)

Pros: 処理の流れがコード上で完全に可視化されている。「なぜそこでループしたのか」が論理的に追える。
Cons: 記述量が多い。状態の設計など、学習コストが高い。

3.実行ロジック

比較対象: 一般的なAgent vs smolagents
計算タスク(Task2)の実装で、決定的な違いが現れました。

一般的なAgent (LangGraph/CrewAI等)

「計算機ツール」を用意し、それをLLMに使わせるスタイルです。
ツールを用意して渡す必要がある

@tool
def python_interpreter(code: str):
    # ... exec(code) ...

Pros: 既存の資産をツールとして渡しやすい。
Cons: 「ツールを呼ぶためのJSON」をLLMに生成させる工程で、構文エラーが起きやすい。

smolagents

エージェント自体がPython実行環境を内包しています。

# ツール定義なしで、いきなり計算できる
agent = CodeAgent(tools=[], model=model)
# LLMがいきなり "def fib(n): ..." と書き始める

Pros: 論理的なタスクにおいて、記述量・実行速度・精度のすべてで他を上回る。
Cons: まだ新しいライブラリであり、複雑なマルチエージェント連携などのドキュメントは少なめ。

4.対話制御

AutoGen

# 終了条件をlambdaで書く必要がある
is_termination_msg=lambda x: (x.get("content") or "").rstrip().endswith("TERMINATE"),

Pros: 複数のエージェントが勝手に会話して問題を解決する。
Cons: 明確に TERMINATE と言わせるようプロンプト制御しないと、「ありがとうございます!」「他に何かありますか?」という無限ループで課金され続けるリスクがある。

結局のところ、構造でガチガチに管理したい(LangGraph)コードで直感的に書きたい(smolagents/PydanticAI) か、自分の開発スタイルに合うものを選ぶのが正解です。

5.全フレームワークのアウトプット

コードの書き心地(第4章)と同様に、実際に走らせてみた 挙動と最終アウトプット にも、フレームワークごとの個性が強烈に現れました。

Task 1: 2025年のAIトレンド検索と要約

検索ツール(Tavily)から得ている情報は全員同じです。しかし、出力されたテキストの「視点」はバラバラでした。

LLMチャットUI

まず、Web画面で聞いた結果です。

2025年のAI Agentフレームワークは、
* LangGraph と OpenAI Agents SDK/Responses API が「本命」候補(状態管理・制御性・OpenAIネイティブ統合)
* LlamaIndex・Semantic Kernel はデータ/RAG・Microsoftスタック向けに定着
* CrewAI・AG2(AutoGen)・smolagents・PydanticAI などのマルチエージェント/型安全/ミニマル指向フレームワークがニッチを分担
共通トレンドは「プロトタイプから本番へ」:
* 再実行性・ログ/監視・評価・ワークフロー制御を備えたオーケストレーション重視が主流になっている。

ブラウザ上ではgpt-5.1しか使用できないため仕方がないですが、圧倒的です。単に情報を要約するだけでなく、市場のポジショニング(構造化)まで行っています。「相談相手」としては素晴らしいです。

LangGraph (システム設計者)

2025年のAIエージェントフレームワークのトレンドとして、以下の点が挙げられます。Langflowのようなローコードフレームワークが注目されており、視覚的にAIエージェントやワークフローを構築・展開できることが特徴です。また、AIエージェントを用いたシミュレーション技術が進化し、複雑な社会的相互作用や予期せぬ状況への対応が可能になっています。これにより、教育、経済、都市計画、ヘルスケアなど多岐にわたる分野での応用が期待されています。特に政策立案や戦略策定において、様々な選択肢の影響を事前に評価するツールとしての活用が進んでいます。(269文字)

個別のツール名よりも、システム全体のあり方(アーキテクチャ)を説いています。非常に堅実で教科書的で、失敗できないシステムを設計するアーキテクトのような振る舞いです。また、検索結果を一度で咀嚼し、スッと回答を出していました。そのため速度も非常に速かったです。システム全体を設計するアーキテクト視点での情報収集に最適だと思います。

CrewAI (ビジネスコンサルタント)

2025年のAIエージェントフレームワークのトレンドとして、以下が挙げられます。まず、MicrosoftのSemanticKernelやFlowiseなど、特定のプラットフォームに特化したSDKが注目されています。また、LangChainやLangGraph、AutoGenといったフレームワークが人気を集めています。これらのフレームワークは、Pythonや.NETなどのプログラミング言語をサポートし、OpenAIやAzure、Googleなどの主要なAIプラットフォームと連携可能です。さらに、生成AIのROIを定量化することが求められており、AI戦略の差別化が競争優位性を高めるとされています。(300文字)

「ROI」や「競争力」といったビジネス用語を盛り込んできました。"Senior Web Researcher"という役割を与えた瞬間、彼は上司への報告書モードに入ったようです。ビジネスサイドには響きますが、技術だけ知りたいエンジニアには前置きが長いと感じるかもしれません。適切なロールの指定が重要です

smolagents

2025年のAIエージェントフレームワークのトレンドとして、マルチエージェントのオーケストレーションが注目されています。企業は単一エージェントから複数のエージェントシステムへと拡大しています。LangChain、LangGraph、AutoGenなどのフレームワークが人気です。エージェントは新奇性から必要性へと進化し、実際の運用課題を解決しています。(176文字)

最も短く、簡潔にまとまっています。また、LangGraphと同様に、検索結果を一度で理解し回答を出しています。核心的なキーワードだけを抽出しており、チャットボットや、Slackへの速報通知など、「読む時間を取らせたくない」場面ではこれがベストプラクティスです。

PydanticAI

2025年のAIエージェントフレームワークのトレンドは、生成AIの進化と共に、組織の運用を再形成する重要な局面を迎えています。主なトレンドとして、ROIの定量化、LLM(大規模言語モデル)の管理、AIガバナンスの強化、労働力のスキルアップが挙げられます。特に、生成AIのROIを明確に示すための指標やフレームワークの必要性が高まっており、AIエージェントの潜在能力を最大限に引き出すための戦略が求められています。また、エンタープライズ向けのAIエージェントSDKやローコードフレームワークの普及も進んでおり、これらの技術を活用することで、競争力を高めることが可能です。(284文字)

「労働力のスキルアップ」「LLM管理」など、組織運用の観点が強いです。

AutoGen

2025年のAIエージェントフレームワークのトレンドとして、Agnoが注目されています。Agnoは、スピード、プライバシー、スケールを重視したPythonベースのオープンソース・マルチエージェントフレームワークで、開発から運用、セキュリティまでを包括的にサポートする統合ソリューションです。特に、パフォーマンスの高さが際立ち、他のフレームワークと比較しても優れた効率性を持っています。Agnoは、スタートアップから大企業、AI研究者まで幅広いユーザーに対応し、迅速なプロトタイピングやデータプライバシーを重視した運用が可能です。また、AIエージェント市場は急成長しており、2024年には54億ドル規模に達し、2030年までに年平均成長率45.8%で拡大が見込まれています。これにより、AIエージェントの実用化が進み、企業の運用に大きな変革をもたらすと期待されています。TERMINATE(393文字)

丁寧にまとまっていますが、300文字を大きく超えてしまいました。会話を複数回行うにつれて、元の制限が弱くなっているような気がします。また、最後にTERMINATEが入るのも特徴です。

Task2: フィボナッチ数列の計算

比較の視点:どうやって計算したか?(ツール vs コード vs サンドボックス)
ここでは「計算結果(数字)」は全員正解でした。違いが出たのは、そこに至る**「プロセス」**です。

従来型 (CrewAI / LangGraph / Raw API)

これらは「Python実行ツール」という**"外部の関数"**に、コードを文字列として渡しています。

# CrewAIのログ(ツール呼び出し)
Action: python_interpreter
Action Input: { "code": "def fibonacci(n): ..." }

いわば「電卓アプリに数式を打ち込んでいる」状態です。今回は成功しましたが、複雑なコードになるとパースエラーのリスクが高まります。

smolagents (Code as Action)

# smolagentsのログ(思考=コード)
Step 1:
def fibonacci(n):
    # ... (中略) ...
    return a

fib_50 = fibonacci(50)
save_to_file("fib_result_smol.txt", str(fib_50))

思考ログ自体が、すでに実行可能なPythonコードになっています。「ツールを呼ぶ」のではなく「コードを書いて自己完結する」。ログの中で一瞬エラーが出ても即座に自己修復しており、論理タスクにおけるスピードと安定感は他を圧倒していました。

LLMチャットUI

出力結果: 「計算しました。ファイルを作成しました。 [ダウンロード]」
計算能力は完璧です。しかし、「ダウンロードボタン」が表示されるだけです。 ユーザーがクリックしないと、手元のPCにファイルは来ません。smolagentsが「勝手にPCのフォルダに保存してくれる」のに対し、LLMチャットUIはあくまでブラウザの中に閉じています。これが「自動化」における最大の壁です。

Task3: 旅行プラン作成

出力結果に関しては、皆似たようなものを出力していました。
しかし、複雑なフローにおいて、制御の難しさが露呈しました。

AutoGen

会話型エージェントの弱点が出ました。「正確な平均交通費」を求めて検索を繰り返し始めました。

# AutoGenのログ(無限ループ)
Assistant: ...交通費の平均を調べます。
(検索実行)
Assistant: ...もう一度交通費を確認します。
(検索実行)
...
TERMINATING RUN: Maximum number of consecutive auto-replies reached

「納得するまで止まらない」 という自律性が仇となり、予算チェックに辿り着く前に死にました。仕事で使うには、かなり強烈なプロンプト制御が必要です。

LangGraph

対照的だったのが LangGraph です。

ログの一部

[Node: agent]
🛠 Tool Calls: [{'name': 'tavily_search_results_json', 'args': {'query': '東京 京都 新幹線 料金 往復'}, 'id': 'call_zW00QvjUzLoBvLC281RrvC6q', 'type': 'tool_call'}, {'name': 'tavily_search_results_json', 'args': {'query': '京都 ホテル 1泊 料金'}, 'id': 'call_RhMVg3bZinN2KrA36vz7waIq', 'type': 'tool_call'}, {'name': 'tavily_search_results_json', 'args': {'query': '京都 観光スポット おすすめ'}, 'id': 'call_GDPaNAaxmXMTUXMzK59zgR4S', 'type': 'tool_call'}]

[Node: tools]
🤖 Content: [{"title": "京都おすすめ観光スポットはここ!名所・穴場30選", "url": "https://travel.jr-central.co.jp/plan/area/kyoto/kankospot/", "content": "1. HOME\n2. 京都旅行・ツアー・観光情報\n3. 京都おすすめ観光スポットはここ!名所・穴場30選\n\n# 京都おすすめ観光スポットはここ!名所・穴場30選\n\n京都旅行に行きたいと考えていても、京都の町は実に広く、観光スポットも多いため、どこを見てまわるか決めるのは、それぞれのスポットを知らないと難しいかもしれません。 \nここでは有名な観光スポットから穴場の観光スポットまでエリアごとにご紹介!ぜひ行ってみたい場所を探していただき、京都旅行の観光スポットめぐりにお役立てください。\n\n京都旅行 特集ページをみる\n\n 京都は魅力的な観光スポットがいっぱい\n 京都観光スポット【祇園・四条・清水エリア】\n 京都観光スポット【銀閣寺・南禅寺エリア】\n 京都観光スポット【京都駅エリア】\n 京都観光スポット【嵐山・仁和寺・金閣寺エリア】\n 京都観光スポット【下鴨・詩仙堂エリア】\n 京都観光スポット【大原・貴船エリア】\n 京都観光スポット【伏見・宇治エリア】\n 京都観光スポット【京都郊外エリア】\n 京都旅行はJR東海ツアーズのおすすめプランで\n まとめ\n\n## 京都は魅力的な観光スポットがいっぱい [...] 日本の観光地の中でも不動の人気を誇る京都は、お寺・神社や平安時代を思わせる街並みや山里といった、日本古来の美しさが集約された街です。 \n市街地と山里の距離もさほど遠くなく、古都京都から少し足を伸ばすだけで豊かな自然も楽しめるのが特徴で、人気の秘訣ともいえます。\n\n### 歴史的建造物がたくさんある\n\n### 山・川・庭園など自然も感じられる\n\n五山送り火に代表されるような催しもある京都は、市街地にいながら山をのぞむ立地で、市内を流れる河川も街の風景の一部になっていて、都市的観光地でありながら自然を身近に感じることができます。 \n桂川や鴨川などの自然のほか、人工的な自然として美を取り入れた庭園も点在します。\n\n### 狭いエリアに見所が集まっている\n\n京都旅行 特集ページをみる\n\n## 京都観光スポット【祇園・四条・清水エリア】\n\n### 1. 京都の定番スポット 「清水寺」\n\n京都で定番の観光スポットといえば清水寺を思い浮かべる方も少なくないでしょう。 \n音羽山の山麓一帯が境内になっている清水寺は、春の桜や秋の紅葉など、四季折々の表情を見せてくれます。\n\n#### 施設情報 [...] | | |\n --- |\n| 所在地 | 〒601-1325 京都府京都市伏見区醍醐東大路町22 |\n| 電話番号 | 075-571-0002 |\n| アクセス | 地下鉄東西線「醍醐駅」下車、徒歩約13分 |\n| 公式HP | |\n\n※詳細は公式ホームページなどでチェックしてください。\n\n日帰りで京都へ!渋滞知らずの新幹線ならたっぷり観光できる♪\n\n京都 日帰り旅行 特集ページをみる\n\n▲「もくじ」に戻る\n\n## 京都観光スポット【京都郊外エリア】\n\n### 29. 海の京都を望む日本三景 「天橋立」\n\n#### 施設情報(天橋立ビューランド)\n\n| | |\n --- |\n| 所在地 | 〒626-0001 京都府宮津市字文珠 |\n| 電話番号 | 0772-22-1000 |\n| アクセス | 京都丹後鉄道「天橋立駅」下車、徒歩約5分 |\n| 公式HP | |\n\n※詳細は公式ホームページなどでチェックしてください。\n\n冬の京都観光で堪能する美しい雪景色とあったかグルメ\n\n### 30. 海と共に暮らす町の魅力 「伊根の舟屋」\n\n#### 施設情報", "score": 0.90771407}, {"title": "京都のおすすめ観光スポット71!世界遺産の社寺から穴場まで網羅 ...", "url": "https://travel.rakuten.co.jp/mytrip/ranking/spot-kyoto", "content": "1.祇園・東山 \n 2.四条・烏丸御池 \n 3.銀閣寺・岡崎 \n 4.上賀茂神社~西陣~京都御所 \n 5.金閣寺周辺 \n 6.嵐山・嵯峨野 \n 7.京都駅周辺 \n 8.伏見・宇治 \n 9.八幡・大山崎 \n 10.大原・鞍馬・貴船 \n 11.京都府北部・丹後半島 \n 【MAP】京都の観光スポットMAP・京都へのアクセス情報\n\n## 【1】祇園・東山\n\nその清水の舞台から望む京都市街の絶景は必見! それだけでなく、春の桜、初夏の新緑、秋の紅葉と、1年を通して多くの観光客を魅了する美しい風景が広がります。\n\n時間\n: 6:00~18:00 ※時期により異なる \n 年中無休\n\n料金\n: 大人400円、小中学生200円\n\nアクセス\n: 京都駅から市バス「五条坂」下車、徒歩約10分\n\n住所\n: 京都市東山区清水1-294\n\nHP\n: 「音羽山 清水寺」公式サイト\n\n清水寺 周辺のホテル・旅館を探す\n\n### 地主神社 【※社殿修復工事のため閉門中】\n\n住所\n: 京都市東山区清水1-317(清水寺敷地内) [...] かつては貴族の別荘地として栄えたエリア。京都屈指の景勝地として、多くの観光客で賑わいます。\n\n### 渡月橋\n\n大堰川(おおいがわ)に架かる嵐山のシンボル的な橋「渡月橋(とげつきょう)」。嵐山を背景に、春は桜、秋は紅葉と、季節ごとの見事な景色を楽しめます。夏には伝統的な鵜飼を見ることも。屋形船に乗って、美景をゆったりと眺める遊覧もおすすめです。\n\nアクセス\n: 嵐電「嵐山」駅より徒歩約3分 \n 阪急「嵐山」駅より徒歩約5分\n\n住所\n: 京都市右京区嵐山\n\n渡月橋 周辺のホテル・旅館を探す\n\n### 竹林の小径\n\n野宮神社から大河内山荘まで続く、両側に竹が生い茂る小道で、嵐山を代表する観光スポットです。風にそよぐ葉音が心地よく、すがすがしい青緑と木漏れ日が織り成す空間はまるで別世界のように幻想的。\n\nアクセス\n: 嵐電「嵐山」駅より徒歩約10分 \n JR「嵯峨嵐山」駅より徒歩約13分\n\n住所\n: 京都市右京区嵯峨天龍寺芒ノ馬場町\n\n竹林の小径 周辺のホテル・旅館を探す\n\n### 野宮神社 [...] 京都府南丹市美山町は、かやぶき屋根の古民家が残る美しい里山。そんな美山をサイクリング!観光名所「かやぶきの里」を巡り、美山産のそばを味わい、パワースポットで開運祈願。見どころ満載のモデルコースを紹介します。\n\n## 京都の観光スポットMAP\n\n## その他の京都観光おすすめ情報\n\nお菓子に雑貨、コスメまで地元民おすすめ!京都駅で買えるお土産\n\n関西\n\n京都\n\n京都駅で買えるおすすめのお土産を「楽天トラベル」現地スタッフが厳選。知る人ぞ知るお菓子からばらまき土産、京都限定品、お菓子以外の漬物やお酒、コスメに雑貨まで。定番・八ツ橋だけじゃない、ツウな京都のお土産を紹介します。\n\n【京都の桜の名所 2025】夜桜ライトアップや無料花見スポットと見頃情報!満開は4月5日の予想\n\n京都\n\n2025年の京都の桜の名所、人気のお花見スポットを、見頃情報とともにご紹介。清水寺や二条城などのライトアップされた夜桜、円山公園のしだれ桜、歴史ある社寺の桜など、京都ならではの風景と桜のコラボレーションは見ものです。\n\n【2025年 京都の紅葉】ライトアップ情報から名所・穴場・見頃情報まで網羅\n\n京都", "score": 0.90432173}, {"title": "【京都観光】おすすめスポット55選+定番名所「効率の良い ...", "url": "https://www.tabikobo.com/tabi-pocket/japan/kyoto/article48049.html", "content": "1. HOME\n2. 国内\n3. 京都\n4. 【京都観光】おすすめスポット55選+定番名所「効率の良い」モデルコース~観光のコツ・交通手段まで~\n\n旅Pocket 編集部\n\n #モデルコース\n #神社\n #京都観光\n #定番スポット\n #移動手段\n\n# 【京都観光】おすすめスポット55選+定番名所「効率の良い」モデルコース~観光のコツ・交通手段まで~\n\n1. 祇園・清水寺エリア\n2. 伏見・宇治エリア\n3. 金閣寺・太泰・御室エリア\n4. 嵐山・嵯峨・高雄エリア\n5. 市内中心部(三条・四条)エリア\n6. 哲学の道・岡崎エリア\n7. 京都御所・下鴨・二条城エリア\n8. 京都駅周辺エリア\n9. 大原・鞍馬・貴船周辺エリア\n10. 京都市郊外エリア\n11. 「効率の良い」1日モデルコース~ド定番スポットをまわる~\n12. 京都の観光スポットを1日でまわるコツ・交通手段\n\n※営業時間が変更になっている可能性があります。 \n お出かけの際は各スポットにご確認ください。\n\n本ページはアフィリエイトプログラムによる収益を得ています。\n\n## 清水寺 [...] アクセス《車》京都市内から約2時間または、与謝天橋立ICから約30分 \n《電車+バス》JR「京都駅」から特急はしだてで約2時間、「天橋立駅」から丹後海陸交通路線バスで約1時間、バス停「伊根」からすぐ\n\n料金施設によって異なる\n\n電話番号0772-32-0277(伊根町観光協会)\n\n営業時間施設によって異なる\n\nURL\n\n## 「効率の良い」1日モデルコース~ド定番スポットをまわる~\n\n10:00 ①JR嵯峨嵐山駅から観光スタート\n\n↓  徒歩約11分\n\n10:15 ②「渡月橋」に到着!川べりから眺めたり橋を渡ったりして景色を堪能。写真撮影も忘れずに。\n\n↓  徒歩約2分\n\n10:55 ③嵐電嵐山駅に到着。路面電車とバスで金閣寺へ\n\n↓  電車(嵐電)約20分+市バス約5分\n\n11:25 ④まばゆい輝きを放つ「金閣寺」を見学\n\n↓  市バス約35分\n\n13:00 ⑤京都駅に到着。駅周辺でランチをしてひと休み\n\n↓  市バス約20分+徒歩約10分\n\n14:30 ⑥「清水寺」へ。清水の舞台で記念撮影!\n\n↓  徒歩すぐ [...] 2023年01月23日 \n140,033view\n\n## 南禅寺\n\n観光時間(目安):約1時間~\n\n「南禅寺」は、1291年に亀山法皇によって開創された臨済宗南禅寺派の大本山です。境内には格式の高さを感じさせる空気が満ち、重要文化財の「三門」や枯山水の庭園のほか、明治に建てられたレンガづくりの「水路閣」など見どころが多数。生い茂る木々は季節ごとに違った表情を見せ、歴史とともに日本の美を堪能できます。\n\nアクセス《電車》地下鉄東西線「蹴上駅」から徒歩10分 \n 《バス》JR「京都駅」から市バスで約40分、バス停「南禅寺・永観堂道」から徒歩10分\n\n料金方丈庭園 大人:600円、高校生:500円、小・中学生:400円|三門 大人:600円、高校生:500円、小・中学生:400円|南禅院 大人:400円、高校生:350円、小・中学生:250円\n\n電話番号075-771-0365\n\n拝観時間3月~11月:08:40~17:00、12月~2月:08:40~16:30(拝観受付:拝観時間終了の20分前まで)、休み:12月28日~31日(一般拝観不可)\n\nURL", "score": 0.8846886}]

[Node: agent]
🛠 Tool Calls: [{'name': 'python_interpreter', 'args': {'code': "# 交通費、宿泊費、観光費用の合計を計算し、予算内か確認する\ntransportation_cost = 28340\naccommodation_cost = 15000\nsightseeing_cost = 2000\n\ntotal_cost = transportation_cost + accommodation_cost + sightseeing_cost\nbudget = 50000\n\n# 結果を出力\n{'total_cost': total_cost, 'within_budget': total_cost <= budget}"}, 'id': 'call_GrT7uGLReQ1qe6Tbw7hmt8gL', 'type': 'tool_call'}]

[Node: tools]
🤖 Content: Executed:

ログを見ると、「交通費・ホテル・観光地」の3つを並列で検索し、サクッと計算を終えていました。 評価: 感情やこだわりを持たず、定義されたグラフ(手順)通りに処理を進める。面白みはありませんが、「業務システムとして安心して寝られる」 のは間違いなくこっちです。

LLMチャットUI

1. web_searchで調べた京都の観光スポット(3つ)
    伏見稲荷大社:無数の朱色の鳥居が続く参道で有名な稲荷信仰の総本宮。
    清水寺:舞台から京都市内を一望できる世界遺産の古刹。四季折々の景色と音羽の滝が見所。
    嵐山竹林:約500m続く竹林の小径で、異世界のような雰囲気を味わえる人気スポット。
2. 予算計算(Python実行結果)
    交通費:28,000円(新幹線往復想定)
    宿泊費:12,000円(ビジネスホテル1泊と仮定)
    観光費:6,000円(拝観料+市内交通などと仮定)
    Pythonで計算した結果:
        合計予算: 46,000円
        5万円以内か? True
3. 1泊2日モデルプラン(東京→京都)
    1日目(朝〜夜)
    朝:東京発 → 新幹線で京都へ(約2.5時間)
    午前:京都駅→伏見稲荷大社。千本鳥居を散策。
    昼:伏見エリアでランチ(きつねうどんなど)。
    午後:清水寺周辺(清水寺〜二年坂・三年坂)を散策。
    夜:四条河原町または京都駅周辺のホテルにチェックイン。夕食&自由時間。
2日目(朝〜夕方)
朝:ホテル発→嵐山へ移動。
午前:嵐山竹林〜渡月橋周辺を散策。
昼:嵐山で湯豆腐や和食ランチ。
午後:土産購入後、京都駅へ戻り東京へ帰京。
上記の仮定ベースでは合計約46,000円で5万円以内に収まる想定の1泊2日プランです(飲食やお土産を多めにすると+数千円程度の余裕を見ておくと安心です)。

こちらも同様に、gpt-5.1を使用しているため対照実験とはなっていませんが、Pythonで予算計算をしつつ、プランも比較的詳細に書かれています。 ただし、Task2同様、これをSlackに通知したりカレンダーに登録したりはできません。「決めるまで」はLLMチャットUIが最強ですが、「決まった後の処理」はAgentに軍配が上がります。

6. 総合評価

全5フレームワーク + Raw API を、5段階評価(S:最高 〜 D:辛い) で完全に主観的に採点しました。

評価項目 LangGraph CrewAI smolagents PydanticAI AutoGen Raw API LLMチャットUI
実装の手軽さ C S S A B C D
制御性・安定性 S C A S C A C
処理速度 A C S A C S S
論理・計算能力 B B S A A B B
複雑なフロー S B B A A D D
学習コスト D A B C C A S

各フレームワークのコメント

  1. LangGraph
    コード量は増えますが、Task3のような 「条件分岐とリトライ」を含むフローの制御 においては右に出るものがいません。Raw APIで while ループを書く地獄に比べれば、グラフ定義は天国です。
    推奨: 業務システム、長期運用するSaaSのバックエンド。

  2. CrewAI
    「リサーチャー」「エンジニア」といった役割を与えるだけで動くのはやはり楽です。ただ、ログを見ると「無駄な会話(思考)」が多く、トークン消費量と実行時間が肥大化する傾向がありました。
    推奨: ハッカソン、PoC(概念実証)、非エンジニアへのデモ。

  3. smolagents
    「LLMにPythonコードを書かせる」アプローチを取ったことで、Task2の安定感と速度が段違いでした。
    推奨: データ分析、計算、単発のタスク解決。

  4. PydanticAI
    セットアップでバージョンの壁に苦しみましたが、一度動いてしまえばコードの綺麗さはNo.1です。Pythonエンジニアにとって最も無理がない書き心地です。
    推奨: FastAPIなどを使ったWebアプリへの組み込み。

  5. AutoGen
    「コードを書いて」「実行しました」というチャットのラリーは見ている分には面白いですが、Task 2のような単純な計算でさえ会話が発生するため、実務での制御は難しい印象です。
    推奨: シミュレーション、人間が会話に介入するツール。

  6. Raw API (基準点: 素のOpenAI SDK)
    Task1のような単純なワークフローなら組めますが、Task3のように複雑なループ処理が入ると、コードが指数関数的に汚くなります。単純なチャットボット以外では、メンテナンス不能なスパゲッティコードになる未来が見えました。
    推奨: 学習目的、非常にシンプルな単発タスク、ライブラリ依存を極限まで減らしたい場合。

  7. LLMチャットUI (番外編: ChatGPT/Claude)
    当たり前の話ですが、コードに組み込むことができません。「ファイルを保存して」と頼んでも、ダウンロードボタンが出るだけで、自動的にローカルフォルダに保存されたり、Slackに通知が飛んだりはしません。「知能」は最強ですが、「手足(自動化能力)」を持たないため、アプリやシステムを作成する用途には向きません。
    推奨: 企画・アイデア出し、プロンプトの挙動確認

7. まとめ:「あなた」はどれを選ぶべきか?

ここまで、LLMチャットUIから素のAPI、そして最新のフレームワーク5種を比較してきました。 正直、検証コードを書いている私自身も「これ、全部使い分けるの無理なのでは?」と思う瞬間がありました。
しかし、それぞれの設計思想を理解すると、選ぶべきツールは自ずと決まります。結論としてのフローチャートを提案します。もちろんこれが完全に正しいわけではないので、最終的には各々が使用したいツールを決めてください。

ケース別・推奨フレームワーク
Case 1: 「コード生成」「データ分析」をさせたいなら
→ smolagents
理由: 従来の「JSONを出力して関数を呼ぶ」方式よりも、「Pythonコードを書いて実行する」方式の方が、LLMの推論能力を最大限に引き出せます。 計算、ファイル操作、データの加工において、smolagentsは頭一つ抜けています。
こんな人へ: データサイエンティスト、Hugging Faceのエコシステムが好きな人。

Case 2: 「Webアプリ」の本番環境に組み込みたいなら
→ PydanticAI
理由: Web開発者にとって馴染み深い Pydantic モデルで入出力を定義できるため、FastAPIなどのフレームワークと相性が抜群です。DI(依存性の注入)や型安全性が考慮されており、テストも書きやすい。「動けばいい」ではなく「保守できる」コードになります。
こんな人へ: バックエンドエンジニア、型安全性にこだわりたい人。

Case 3: 複雑怪奇な「業務フロー」を完全に制御したいなら
→ LangGraph
理由: 業務には「AがダメならB、それでもダメなら上長(人間)に承認を求める」といった複雑な分岐が存在します。これをグラフ構造で可視化・制御できるのはLangGraphだけです。「Human-in-the-loop」 機能が必要ならこれ一択です。
こんな人へ: 大規模システムのアーキテクト、LangChainに慣れている人。

Case 4: とにかく爆速で「マルチエージェント」を動かしたいなら
→ CrewAI
理由: 「リサーチャー」と「ライター」を定義して戦わせる、といったデモを最も短いコード量で実現できます。
こんな人へ: PM、ハッカソンで急いで動くものを作りたい人。

Case 5: エージェントと「対話」しながら進めたいなら
AutoGen
理由: エージェント同士の会話でタスクが進みますが、最大の特徴は**「UserProxy(人間の代理)」** の存在です。「ここだけ人間が確認する」「コード実行だけ人間が許可する」といった、Human-in-the-loop(人間参加型) のワークフローを組むのに最適です。
こんな人へ: 研究者、シミュレーションを行いたい人、半自動化ツールを作りたい人。

Case 6: そもそもフレームワークが不要な場合
→ [LLMチャットUI] or [Raw API]
LLMチャットUI: アイデア出し、学習、単発のデバッグ。ここに勝るUXはありません。
Raw API: 「天気予報APIを叩いて返すだけのチャットボット」など、ループや自律判断が不要なタスク。

8.最後に

今は、適材適所でツールを選ぶ 「Agentのモジュール化」 が進んでいます。

  • 脳みそだけ借りたいなら LLMチャットUI
  • 手足として単純作業させたいなら Raw API
  • 論理的な思考が必要なら smolagents
  • 社会的な協調が必要なら CrewAI
  • 対話的な実験がしたいなら AutoGen
  • システムの一部として堅実に動かすなら PydanticAI / LangGraph

この記事が、あなたの「相棒」探しの助けになれば幸いです。
最後まで読んでいただき、ありがとうございました!

付録.実行コード

  • LangChain
全文を見る
pip install langgraph langchain-openai langchain-community tavily-python langchain-experimental
import os
os.environ.get("OPENAI_API_KEY")
os.environ.get("TAVILY_API_KEY")
import operator
from typing import Annotated, TypedDict, Union, List
import time

from langchain_openai import ChatOpenAI
from langchain_tavily import TavilySearch
from langchain_core.messages import BaseMessage, HumanMessage, SystemMessage
from langchain_core.tools import tool
from langchain_experimental.utilities import PythonREPL

from langgraph.graph import StateGraph, END, START
from langgraph.prebuilt import ToolNode

search_tool = TavilySearch(max_results=3)

@tool
def save_to_file(filename: str, content: str) -> str:
    """指定されたファイル名に内容を保存します。"""
    try:
        with open(filename, "w", encoding="utf-8") as f:
            f.write(content)
        return f"Successfully saved to {filename}"
    except Exception as e:
        return f"Error saving file: {e}"

repl = PythonREPL()

@tool
def python_interpreter(code: str) -> str:
    """Pythonコードを実行し、標準出力を返します。計算やデータ処理に使用します。"""
    try:
        result = repl.run(code)
        return f"Executed:\n{result}"
    except Exception as e:
        return f"Error: {e}"

tools = [search_tool, save_to_file, python_interpreter]

class AgentState(TypedDict):
    messages: Annotated[List[BaseMessage], operator.add]


llm = ChatOpenAI(model="gpt-4o", temperature=0)
llm_with_tools = llm.bind_tools(tools)

def agent_node(state: AgentState):
    """LLMを呼び出し、応答を生成するノード"""
    messages = state["messages"]
    response = llm_with_tools.invoke(messages)
    return {"messages": [response]}

def should_continue(state: AgentState):
    """次に行くべきか終了すべきかを判断する条件付きエッジ"""
    last_message = state["messages"][-1]
    if last_message.tool_calls:
        return "tools"
    return END

# グラフ構築
workflow = StateGraph(AgentState)

workflow.add_node("agent", agent_node)
workflow.add_node("tools", ToolNode(tools))

workflow.add_edge(START, "agent")
workflow.add_conditional_edges("agent", should_continue, ["tools", END])
workflow.add_edge("tools", "agent")

app = workflow.compile()

def run_task(task_id: str, prompt: str):
    initial_state = {
        "messages": [
            SystemMessage(content="あなたは優秀なAIアシスタントです。与えられたツールを適切に使用してタスクを解決してください。"),
            HumanMessage(content=prompt)
        ]
    }

    config = {"recursion_limit": 50}
    try:
        for event in app.stream(initial_state, config=config):
            for key, value in event.items():
                print(f"\n[Node: {key}]")
                if "messages" in value:
                    last_msg = value["messages"][-1]
                    if hasattr(last_msg, "tool_calls") and last_msg.tool_calls:
                        print(f"Tool Calls: {last_msg.tool_calls}")
                    elif hasattr(last_msg, "content"):
                        print(f"Content: {last_msg.content}")
    except Exception as e:
        print(f"Error occurred: {e}")

if __name__ == "__main__":
    
    # Task 1: Web検索と要約
    task1_prompt = "「2025年のAI Agentフレームワークの最新トレンド」についてWeb検索し、その要点を日本語で300文字以内にまとめてください。"
    run_task("1", task1_prompt)
    time.sleep(30)

    # Task 2: コード実行とファイル保存 (Prompt修正)
    task2_prompt = """
    フィボナッチ数列の第50項をPythonコードを実行して計算し、その結果をローカルのテキストファイル `fib_result.txt` に保存してください。
    【重要】
    1. 計算結果は必ず `print()` で出力して確認してください(出力がないと結果を認識できません)。
    2. 第50項は計算量が多いため、再帰関数ではなくループ処理で計算してください。
    """
    run_task("2", task2_prompt)
    time.sleep(30)

    # Task 3: 複合プランニング
    task3_prompt = """
    東京から京都へ1泊2日の旅行プランを立ててください。
    条件:
    1. 予算は交通費・宿泊費込みで **5万円以内**。
    2. 観光スポットを3つ以上回る。
    3. Pythonで概算見積もりを行い、もし予算オーバーしたら、プランを自動で見直して再提案すること。
    """
    run_task("3", task3_prompt)
  • CrewAI
全文を見る
pip install crewai crewai-tools langchain-openai tavily-python 
import os
import time
from crewai import Agent, Task, Crew, Process
from crewai_tools import TavilySearchTool
from langchain_experimental.utilities import PythonREPL
from crewai.tools import tool
from langchain_openai import ChatOpenAI

os.environ.get("OPENAI_API_KEY")
os.environ.get("TAVILY_API_KEY")

llm = ChatOpenAI(model="gpt-4o", temperature=0)
tavily_tool = TavilySearchTool()

@tool("Save to File")
def save_to_file(filename: str, content: str) -> str:
    """Useful to save content to a file. Input should be a filename and the content string."""
    try:
        with open(filename, "w", encoding="utf-8") as f:
            f.write(content)
        return f"Successfully saved to {filename}"
    except Exception as e:
        return f"Error saving file: {e}"

# Python実行ツール
python_repl = PythonREPL()

@tool("Python Interpreter")
def python_interpreter(code: str) -> str:
    """Useful to execute Python code. Input is valid Python code.
    IMPORTANT: You must print the result using `print()` to see the output.
    """
    try:
        result = python_repl.run(code)
        return f"Executed result:\n{result}"
    except Exception as e:
        return f"Error executing code: {e}"

researcher = Agent(
    role='Web Researcher',
    goal='Web情報を正確に調査し要約する',
    backstory='技術のトレンドに詳しい',
    tools=[tavily_tool],
    verbose=True,
    llm=llm,
    max_iter=10
)

engineer = Agent(
    role='Python Engineer',
    goal='Pythonコードを書いて実行し、正確な計算を行う',
    backstory='数学とPythonのプロ。暗算はせず必ずコードで検証する。',
    tools=[python_interpreter, save_to_file],
    verbose=True,
    llm=llm,
    max_iter=10
)

planner = Agent(
    role='Travel Planner',
    goal='予算と条件に合わせて最適な旅行プランを作成する',
    backstory='予算管理に厳しい旅行代理店のエージェント。',
    tools=[python_interpreter, tavily_tool],
    verbose=True,
    llm=llm,
    max_iter=15
)

def run_task_1():
    task1 = Task(
        description='「2025年のAI Agentフレームワークの最新トレンド」についてWeb検索し、その要点を日本語で300文字以内にまとめてください。',
        expected_output='要約された日本語テキスト',
        agent=researcher
    )
    crew = Crew(agents=[researcher], tasks=[task1], verbose=True)
    result = crew.kickoff()
    print(f"\nResult 1:\n{result}")

def run_task_2():
    task2 = Task(
        description="""
        フィボナッチ数列の第50項をPythonコードを実行して計算し、その結果をローカルのテキストファイル `fib_result_crew.txt` に保存してください。
        
        【重要】
        1. 必ずPythonツールを使用すること。暗算禁止。
        2. コード内では計算結果を `print()` して確認すること。
        3. 再帰関数(recursion)は遅いので禁止。ループ処理を使うこと。
        """,
        expected_output='ファイル保存完了のメッセージ',
        agent=engineer
    )
    crew = Crew(agents=[engineer], tasks=[task2], verbose=True)
    result = crew.kickoff()
    print(f"\nResult 2:\n{result}")

def run_task_3():
    research_task = Task(
        description='京都の観光スポットを3つ、価格(入場料など)とともに調査してください。',
        expected_output='観光スポットリストと価格',
        agent=researcher
    )

    plan_task = Task(
        description="""
        東京から京都へ1泊2日の旅行プランを立ててください。
        条件:
        1. 予算は交通費・宿泊費込みで **5万円以内**。
        2. リサーチャーが調査したスポットを回る。
        3. Pythonツールを使って概算見積もりを出し、予算オーバーならプランを修正すること。
        """,
        expected_output='5万円以内に収まる旅行プラン',
        agent=planner,
        context=[research_task]
    )

    crew = Crew(
        agents=[researcher, planner],
        tasks=[research_task, plan_task],
        process=Process.sequential,
        verbose=True
    )
    result = crew.kickoff()
    print(f"\nResult 3:\n{result}")

if __name__ == "__main__":
    try:
        # Task 1
        run_task_1()
        time.sleep(30)

        # Task 2
        run_task_2()
        time.sleep(30)

        # Task 3
        run_task_3()

    except Exception as e:
        print(f"❌ Error: {e}")
  • smolagents
全文を見る
pip install smolagents tavily-python 
import os
import time
from smolagents import CodeAgent, OpenAIServerModel, tool
from tavily import TavilyClient

os.environ.get("OPENAI_API_KEY")
os.environ.get("TAVILY_API_KEY")

model = OpenAIServerModel(
    model_id="gpt-4o",
    api_key=os.environ["OPENAI_API_KEY"],
    temperature=0
)

@tool
def web_search(query: str) -> str:
    """
    Search the web for a given query using Tavily API.
    Args:
        query: The search query string.
    Returns:
        A string containing the search results.
    """
    try:
        tavily = TavilyClient(api_key=os.environ["TAVILY_API_KEY"])
        response = tavily.search(query=query, max_results=3)
        results = [f"- {res['content']} (URL: {res['url']})" for res in response['results']]
        return "\n".join(results)
    except Exception as e:
        return f"Error searching web: {e}"

@tool
def save_to_file(filename: str, content: str) -> str:
    """
    Save content to a local text file.
    Args:
        filename: The name of the file to save (e.g., 'output.txt').
        content: The text content to write into the file.
    """
    try:
        with open(filename, "w", encoding="utf-8") as f:
            f.write(content)
        return f"File saved successfully to {filename}"
    except Exception as e:
        return f"Error saving file: {e}"

agent = CodeAgent(
    tools=[web_search, save_to_file], 
    model=model,
    add_base_tools=False,
    verbosity_level=2
)

def run_task_1():
    prompt = "「2025年のAI Agentフレームワークの最新トレンド」についてweb_searchし、その要点を日本語で300文字以内にまとめてください。"
    result = agent.run(prompt)
    print(f"\nResult 1:\n{result}")

def run_task_2():
    prompt = """
    フィボナッチ数列の第50項をPythonコードで計算し、その結果を `save_to_file` ツールを使って `fib_result_smol.txt` に保存してください。
    注意:
    1. あなたはPythonコードを実行できるので、ループ処理で計算するコードを書いてください。
    2. 再帰(recursion)は遅いので使わないでください。
    """

    result = agent.run(prompt)
    print(f"\nResult 2:\n{result}")

def run_task_3():
    prompt = """
    東京から京都へ1泊2日の旅行プランを日本語で立ててください。
    
    手順:
    1. `web_search` で京都の観光スポットを3つ調査する。
    2. 予算は5万円以内。Pythonコードで交通費(約28000円と仮定)と宿泊費・観光費を足し算して見積もりを出すこと。
    3. 予算内であればプランを提示し、予算オーバーなら修正案を考えるコードを書くこと。
    """
    
    result = agent.run(prompt)
    print(f"\nResult 3:\n{result}")

if __name__ == "__main__":
    try:
        # Task 1
        run_task_1()
        time.sleep(30)

        # Task 2
        run_task_2()
        time.sleep(30)

        # Task 3
        run_task_3()

    except Exception as e:
        print(f"❌ Error: {e}")
  • pydanticAI
全文を見る
pip install pydantic-ai langchain-experimental tavily-python nest_asyncio
import os
import asyncio
from pydantic_ai.models.openai import OpenAIChatModel as ModelClass

from pydantic_ai import Agent, RunContext
from tavily import TavilyClient
from langchain_experimental.utilities import PythonREPL

os.environ.get("OPENAI_API_KEY")
os.environ.get("TAVILY_API_KEY")

model = ModelClass('gpt-4o')

agent = Agent(
    model,
    system_prompt='あなたは優秀なAIアシスタントです。与えられたツールを適切に使ってタスクを完了させてください。',
    deps_type=str,
    model_settings={'temperature': 0},
)

@agent.tool
def web_search(ctx: RunContext[str], query: str) -> str:
    """Web検索を行い、結果を返します。"""
    try:
        tavily = TavilyClient(api_key=os.environ["TAVILY_API_KEY"])
        response = tavily.search(query=query, max_results=3)
        results = [f"- {res['content']} (URL: {res['url']})" for res in response['results']]
        return "\n".join(results)
    except Exception as e:
        return f"Error searching web: {e}"

@agent.tool
def save_to_file(ctx: RunContext[str], filename: str, content: str) -> str:
    """指定されたファイル名にテキスト内容を保存します。"""
    try:
        with open(filename, "w", encoding="utf-8") as f:
            f.write(content)
        return f"Successfully saved to {filename}"
    except Exception as e:
        return f"Error saving file: {e}"

repl = PythonREPL()

@agent.tool
def python_interpreter(ctx: RunContext[str], code: str) -> str:
    """
    Pythonコードを実行し、標準出力を返します。
    注意: 必ず `print()` を使って結果を出力してください。
    """
    try:
        result = repl.run(code)
        return f"Executed:\n{result}"
    except Exception as e:
        return f"Error executing code: {e}"

def print_result(result, task_name):
    """
    結果オブジェクトの構造を気にせず、あるものを表示するヘルパー関数
    エラーが出ても止まらないように try-except で囲みます。
    """
    print(f"\nResult {task_name}:")
    msgs = result.new_messages()
    last_msg = msgs[-1]
    print(last_msg.parts[0].content)

async def run_tasks():
    deps_data = "dummy_context"

    # Task 1
    prompt1 = "「2025年のAI Agentフレームワークの最新トレンド」についてweb_searchし、その要点を日本語で300文字以内にまとめてください。"
    result1 = await agent.run(prompt1, deps=deps_data)
    print_result(result1, "1")
    await asyncio.sleep(30)

    # Task 2
    prompt2 = """
    フィボナッチ数列の第50項をPythonコード(`python_interpreter`)を実行して計算し、その結果をローカルのテキストファイル `fib_result_pydantic.txt` に保存してください。
    【重要】計算結果は必ず `print()` で出力すること。再帰禁止。
    """
    result2 = await agent.run(prompt2, deps=deps_data)
    print_result(result2, "2")
    await asyncio.sleep(30)

    # Task 3
    prompt3 = """
    東京から京都へ1泊2日の旅行プランを立ててください。
    条件:
    1. 予算は交通費・宿泊費込みで **5万円以内**。
    2. 観光スポットを3つ以上回る。
    3. Pythonツールで概算見積もりを行い、もし予算オーバーしたら、プランを自動で見直して再提案すること。
    """
    result3 = await agent.run(prompt3, deps=deps_data)
    print_result(result3, "3")

if __name__ == "__main__":
    asyncio.run(run_tasks())
  • AutoGen
全文を見る
pip install autogen
import os
import time
import autogen
from typing import Annotated
from tavily import TavilyClient

import logging
logging.getLogger("autogen").setLevel(logging.ERROR)

os.environ.get("OPENAI_API_KEY")
os.environ.get("TAVILY_API_KEY")

config_list = [
    {
        "model": "gpt-4o",
        "api_key": os.environ.get("OPENAI_API_KEY"),
    }
]

llm_config = {
    "config_list": config_list,
    "temperature": 0,
    "functions": [
        {
            "name": "web_search",
            "description": "Searches the web for a query and returns the results.",
            "parameters": {
                "type": "object",
                "properties": {
                    "query": {
                        "type": "string",
                        "description": "The search query string",
                    }
                },
                "required": ["query"],
            },
        }
    ],
}

assistant = autogen.AssistantAgent(
    name="Assistant",
    llm_config=llm_config,
    system_message="""
    あなたは優秀なAIアシスタントです。
    タスクを完了するために必要なステップを考え、コードの作成や Web検索を行ってください。

    【重要ルール】
    1. 計算やファイル保存が必要な場合は、必ずPythonコードブロック (```python ... ```) を書いてください。
    2. コードの実行結果を見て、最終的な回答が得られたら、最後に必ず「TERMINATE」とだけ出力して会話を終了してください。
    """
)

user_proxy = autogen.UserProxyAgent(
    name="User_Proxy",
    human_input_mode="NEVER",
    max_consecutive_auto_reply=10,
    is_termination_msg=lambda x: (x.get("content") or "").rstrip().endswith("TERMINATE"),
    code_execution_config={
        "work_dir": "coding",
        "use_docker": False,
    },
    function_map={
        "web_search": lambda query: web_search_tool(query)
    }
)

def web_search_tool(query: str) -> str:
    """Tavilyを使って検索する実関数"""
    print(f"\n[Tool] Searching for: {query}")
    try:
        tavily = TavilyClient(api_key=os.environ["TAVILY_API_KEY"])
        response = tavily.search(query=query, max_results=3)
        results = [f"- {res['content']} (URL: {res['url']})" for res in response['results']]
        return "\n".join(results)
    except Exception as e:
        return f"Error: {e}"

def run_task_1():
    chat_result = user_proxy.initiate_chat(
        assistant,
        message="「2025年のAI Agentフレームワークの最新トレンド」についてweb_searchし、その要点を日本語で300文字以内にまとめてください。",
        silent=True
    )
    for msg in reversed(chat_result.chat_history):
        if msg.get("name") == "Assistant":
            content = msg.get("content", "")
            if content:
                print("\n【回答】")
                print(content)
                break

def run_task_2():
    prompt = """
    フィボナッチ数列の第50項をPythonコードを実行して計算し、その結果を `fib_result_autogen.txt` というファイルに保存してください。
    
    条件:
    1. 再帰関数は禁止。ループ処理を使うこと。
    2. 計算結果をprintして表示すること。
    3. 完了したらTERMINATEしてください。
    """
    user_proxy.initiate_chat(assistant, message=prompt)

def run_task_3():
    prompt = """
    東京から京都へ1泊2日の旅行プランを立ててください。

    手順:
    1. web_searchを使って京都の観光スポットを3つ調べる。
    2. Pythonコードを書いて、交通費(約28000円と仮定) + 宿泊費 + 観光費の合計予算を計算する。
    3. 予算が5万円以内かチェックし、プランを提案する。
    4. 完了したらTERMINATEしてください。
    """
    user_proxy.initiate_chat(assistant, message=prompt)

if __name__ == "__main__":
    if not os.path.exists("coding"):
        os.makedirs("coding")

    try:
        run_task_1()
        time.sleep(30)

        run_task_2()
        time.sleep(30)

        run_task_3()

    except Exception as e:
        print(f"Error: {e}")
EpicAI Tech Blog

Discussion