最初の自律型エージェントを構築してデプロイする7つのステップ
この記事では、LangGraphフレームワークとClaudeモデルを使用して、自律型リサーチエージェントを構築しデプロイするためのステップバイステップガイドを提供します。エージェントの目的の定義、ツールの選択、プロジェクトのセットアップ、コアループの構築、メモリとツールの追加、API公開、コンテナ化までの全プロセスを網羅しています。本番運用における境界設定、エラーハンドリング、コンテナ化の重要性を強調しています。
この記事では、最初の自律型リサーチエージェントを構築してデプロイするための完全なステップバイステップガイドを提供します。このガイドはLangGraphフレームワークとClaudeモデルに基づいており、コンセプトからプロダクションまでの全プロセスをカバーしています。
はじめに
ほとんどの人の最初のAIエージェントは、ノートパソコンから離れることはありません。ターミナルで一度実行され、適切な答えを出力し、その後は誰もスクリプトを他の人やシステムが実際に呼び出せるサービスに変えるための15行のグルーコードを書かなかったために、そこに放置されます。「実行時に機能した」から「本番稼働して誰かが使っている」までのギャップが、ほとんどのエージェントプロジェクトが静かに消滅する場所です。
データはこれを裏付けています。Gartner、McKinsey、IDCのデータをまとめた2026年の統計によると、企業の約79%が何らかの形でAIエージェントを採用していると回答していますが、本番稼働しているのは約11%に過ぎません。このギャップは小さな問題ではありません。デモと製品の違いであり、その原因はほとんどの場合、モデルが弱すぎるからではなく、誰もジョブの範囲を適切に定義しなかったり、障害に対処しなかったり、プログラムをコンテナ化してURLのある場所に配置する手間を惜しんだりすることにあります。
この記事では、特定のプロジェクトについてこのギャップを埋めます。この記事を読み終える頃には、研究エージェントを構築してデプロイできるようになります。トピックを与えると、ウェブを検索し、ソースを取得し、リンク付きの短い書面によるブリーフを返します。実際のツール使用、メモリ、ガードレールが必要なほど複雑ですが、一度の作業で全体を構築できるほど小規模です。以下の各コードブロックは完全でコメント付きであり、各ブロックの後にはその機能と理由の平易な説明があります。
ステップ1: エージェントが実際に何をする必要があるか(そして何をすべきでないか)を決定する
エディタを開く前に、次の3つのことを書き留めてください:エージェントが行う唯一の仕事、成功した出力の見た目、そして人間が最初に確認することなく決して行ってはならないこと。
私たちの研究エージェントの場合、次のようになります:
- 仕事:トピックを入力として受け取り、ウェブ検索を実行し、結果を読み、要約とソースリストを含む書面によるブリーフを作成する。
- 成功の見た目:500語未満の首尾一貫した事実に基づくブリーフで、各主張がソースURLによって追跡可能であること。
- 厳格な境界:検索と読み取りは自由に行えるが、人の承認なしに何も投稿、送信、または自身のワークスペース外のファイルに書き込んではならない。
3番目のポイントは見かけ以上に重要です。このステップをスキップすることは、Gartnerが2027年末までにエージェンティックAIプロジェクトの40%以上がキャンセルされると予想する大きな理由の1つであり、通常は誰も早期に境界を定義しなかったため、プロジェクトが役に立たないほど少ないか、信頼できないほど多くを行ってしまうことになります。
ステップ2: モデルとフレームワークの選択
ここでは2つの決定が必要です:推論を行うモデルと、思考、行動、結果の確認のループを管理するフレームワークです。
モデルについては、確かなツール使用能力を持つ現在の最先端モデルであればどれでも適しています:Claude、GPT、Geminiのいずれも動作します。以下のコードではClaudeを使用します。そのツール呼び出しがマルチステップタスクで一貫して信頼性が高いためですが、他のプロバイダに切り替えるには1行を変更するだけです。
フレームワークについては、2026年後半の状況は次のとおりです:
- LangGraph:エージェントをグラフのノードとエッジとしてモデル化し、組み込みのチェックポイント機能により、クラッシュした実行を再開できます。月間PyPIダウンロード数は3800万を超え、Klarna、Uber、LinkedInなどの企業が本番環境で使用しています。トレードオフは学習曲線が急で、通常1〜2週間かかることです。
- CrewAI:エージェントを役割と目標を持つ「クルー」としてモデル化し、20行未満のコードで動作させることができます。アイデアを検証する最速の方法であり、GitHubで44,000以上のスターを獲得していますが、ワークフローが複雑になると制御が難しくなり、チームはLangGraphに移行することが一般的です。
- AutoGen:かつてマルチエージェント会話パターンのデフォルトの選択肢でしたが、Microsoftはメンテナンスモードに移行し、統一されたMicrosoft Agent Frameworkに開発を移したため、2026年に新しいプロジェクトを構築する場所ではありません。
- ベンダーSDK:OpenAI Agents SDKやAnthropicのClaude Agent SDKなど、1つのベンダーに完全にコミットしていて、最小限のフレームワークオーバーヘッドを望む場合に検討に値しますが、そのベンダーのモデルにロックインされます。
この構築ではLangGraphを使用します。研究エージェントはチェックポイント(タイムアウトした検索で最初からやり直す必要がない)の恩恵を受け、またこのスキルが実際の本番ジョブに最も直接的に移行できるバージョンだからです。
ステップ3: プロジェクトのセットアップ
フォルダ、仮想環境を作成し、必要なものをインストールします。
mkdir research-agent && cd research-agent
python3 -m venv venv
source venv/bin/activate
pip install langgraph langchain-anthropic langchain-community python-dotenv tavily-python beautifulsoup4仮想環境により、このプロジェクトのパッケージをマシン上の他のプロジェクトから分離し、依存関係の更新が他のプロジェクトを壊すのを防ぎます。インストールするパッケージは、オーケストレーション(langgraph)、モデル接続(langchain-anthropic)、すぐに使えるウェブ検索ツールとページローダー(langchain-community、tavily-python、beautifulsoup4)、安全なキー管理(python-dotenv)をカバーします。
次に、プロジェクトルートに.envファイルを作成してキーを保存します。Anthropic ConsoleからのAnthropic APIキーと、Tavilyからの検索APIキーが必要です。Tavilyはこのチュートリアルに十分な無料ティアを提供しています。
# .envファイル、バージョン管理にコミットしないでください
ANTHROPIC_API_KEY=your-anthropic-key-here
TAVILY_API_KEY=your-tavily-key-here最後に、フォルダ構造を設定します:
research-agent/
├── venv/
├── .env
├── .gitignore
├── agent.py
├── app.py
├── requirements.txt
└── Dockerfileagent.py(エージェントロジック)をapp.py(エージェントを公開するウェブサーバー)から分離することで、コードを読みやすくし、APIにラップする前に直接エージェントをテストできます。.envとvenv/を.gitignoreに追加して、キーがリポジトリに漏れないようにします。
ステップ4: コアエージェントループの構築
これがプロジェクトの核心です:エージェントがタスクを読み、ツールが必要かどうかを判断し、ツールを呼び出し、結果を読み、次に何をするかを決定するループです。agent.pyを開き、少しずつ構築します。
# agent.py
from dotenv import load_dotenv
from langchain_anthropic import ChatAnthropic
from langchain_community.tools.tavily_search import TavilySearchResults
from langgraph.prebuilt import create_react_agent
load_dotenv()
model = ChatAnthropic(model="claude-sonnet-4-6", temperature=0.2, max_tokens=1500)
search_tool = TavilySearchResults(max_results=5)
agent = create_react_agent(model, tools=[search_tool])
def run_research(topic: str) -> str:
result = agent.invoke({
"messages": [
("system", "You are a research assistant. When given a topic, search for current, credible information and write a brief under 500 words. Every factual claim must be followed by the source URL in parentheses. If sources disagree, say so."),
("user", topic),
]
})
return result["messages"][-1].content
if __name__ == "__main__":
topic = input("What should I research? ")
print(run_research(topic))行ごとの説明:load_dotenv()は.envファイルからキーを読み込みます。ChatAnthropicはモデルへの接続を設定します。低い温度は、創造性よりも正確性を重視する場合に重要です。TavilySearchResultsはエージェントにライブインターネットへのアクセスを提供します。create_react_agentは、LangGraphが提供する古典的な推論ループ(ReAct、推論と行動)を構築するショートカットです。システムメッセージは、ソースを引用し、意見の相違を指摘するよう強制します。
ターミナルからpython agent.pyを実行し、トピックを入力すると、リンク付きの短いブリーフが返されるはずです。ハングアップしたりエラーが発生した場合は、.envファイルのキーが正しいことと、アクティブな仮想環境にいることを確認してください。
ステップ5: メモリと2番目のツールの追加
現在、エージェントは完了するとすべてを忘れます。これは単一の質問には問題ありませんが、「今度はそれをXと比較して」のようなフォローアップが来ると機能しません。会話メモリを追加し、検索スニペットだけでは詳細が不十分な場合にエージェントがページ全体のコンテンツを取得できるように、2番目のツールを追加します。
# agent.py (updated)
from dotenv import load_dotenv
from langchain_anthropic import ChatAnthropic
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_community.document_loaders import WebBaseLoader
from langchain_core.tools import tool
from langgraph.prebuilt import create_react_agent
from langgraph.checkpoint.memory import MemorySaver
load_dotenv()
model = ChatAnthropic(model="claude-sonnet-4-6", temperature=0.2, max_tokens=1500)
search_tool = TavilySearchResults(max_results=5)
@tool
def read_page(url: str) -> str:
"""Fetches the readable text of a single web page."""
try:
loader = WebBaseLoader(url)
docs = loader.load()
return docs[0].page_content[:3000]
except Exception as e:
return f"Could not load that page: {e}"
SYSTEM_PROMPT = (
"You are a research assistant with memory. Use the search and read_page tools "
"to gather information. Keep track of the conversation history. Always cite sources."
)
memory = MemorySaver()
agent = create_react_agent(model, tools=[search_tool, read_page], checkpointer=memory)
config = {"configurable": {"thread_id": "research thread"}}
def run_research(topic: str) -> str:
result = agent.invoke({"messages": [("user", topic)]}, config=config)
return result["messages"][-1].content
if __name__ == "__main__":
topic = input("What should I research? ")
print(run_research(topic))主要な変更点:@toolデコレータでread_page関数を定義。MemorySaverでチェックポイントが追加され、会話履歴を保存。システムプロンプトを定数として定義。configのthread_idでセッションを識別し、後続の呼び出しを同じ会話に関連付けます。
ステップ6: FastAPIを使用してエージェントをAPIとして公開
これでエージェントはターミナルでうまく動作しますが、Web APIを介して呼び出し可能にする必要があります。FastAPIを使用してエンドポイントを作成し、長時間実行されるタスクによるサーバーのブロックを防ぐために非同期処理を行います。
# app.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from agent import run_research
app = FastAPI()
class ResearchRequest(BaseModel):
topic: str
@app.post("/research")
async def research(request: ResearchRequest):
if not request.topic:
raise HTTPException(status_code=400, detail="Topic cannot be empty")
result = run_research(request.topic)
return {"result": result}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)ステップ7: Dockerによるコンテナ化デプロイ
最後に、エージェントをコンテナ化して、Dockerをサポートする任意の環境(クラウドサーバーやKubernetesなど)で一貫して実行できるようにします。
# Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]イメージをビルドして実行:
docker build -t research-agent .
docker run -d -p 8000:8000 --env-file .env research-agentこれで、エージェントはhttp://localhost:8000/researchで呼び出し可能になり、会話メモリ、ツール使用、永続化状態を備えています。コンテナをAWS ECS、Google Cloud Run、Azure Container Instancesなどの任意のクラウドサービスにデプロイするには、1回のプッシュで済みます。
結論
この記事では、ゼロからプロダクションまで、自律型リサーチエージェントを構築しました。重要なポイントは、タスクの境界を正確に定義すること、適切なツールフレームワークを選択すること、メモリとツールを備えたコアループを構築すること、APIを介して公開すること、そしてコンテナ化してデプロイすることです。これらのスキルは、より複雑なプロダクショングレードのエージェントプロジェクトに直接適用できます。