1. セットアップと最初の成功
PythonでAIエージェント(agent)を構築する旅へようこそ!この章を終えるころには、大規模言語モデル(LLM: Large Language Model)への最初の呼び出しを成功させ、裏側で何が起きたのかを正確に理解できるようになります。ここで作る土台が、この先に続くすべての基礎になります。
前提条件
対象読者と前提
本書は、AIエージェント(agent)を作りたいPython開発者向けに書かれていますが、LLMやAIフレームワークの事前経験は不要です。次の内容に慣れていることを前提とします:
- Pythonの基礎: 関数、クラス、import、基本的なデータ構造
- Python 3.10+: システムにPython 3.10以上がインストールされていること
- 仮想環境:
python -m venvでvenvを作成して有効化できること - パッケージ管理:
pipでパッケージをインストールできること - 環境変数: シェルで環境変数を設定し、読み取れること
- APIキー: APIキーが何かを理解し、サービス提供者から取得する方法を知っていること
これらの概念のいずれかが不慣れな場合は、続ける前に別途復習することをおすすめします。Pythonの公式ドキュメントや、仮想環境とpipに関するチュートリアルは優れた出発点です。
前提にしないこと: 機械学習、ニューラルネットワーク、トランスフォーマー(transformer)、AI理論の背景は不要です。LLM固有の概念は遭遇したタイミングで説明し、常に身近なプログラミングパターンに結びつけます。
モデルの取り決め
本書では、例の既定モデルとして GPT-5-mini を使用します。理由は次のとおりです:
- 広く利用可能: OpenAIのAPIは、簡単なサインアップでグローバルに利用できます
- 妥当な速度: 推論努力を最小限にすると、反復開発に十分な速度で応答が返ります
- 費用対効果が高い: 2026年時点で入力100万トークンあたり$0.25、出力100万トークンあたり$2.00と、学習と実験に手頃です
- 十分な能力: 実用的なAIエージェント(agent)タスクの大半をうまく扱えます
明示的にモデル指定がないコード例を見たら、GPT-5-mini を使っていると考えてください。第2章では、利用可能なモデル全体像(Claude、Gemini、その他のGPTバリアント)を探索し、コンテキストウィンドウ(context window)のサイズ、コスト、特化能力といった観点で、状況に応じて代替を選ぶタイミングを議論します。
1.1) LLMとは?
コードを書く前に、私たちが実際に扱うものを整理しましょう。大規模言語モデル(LLM: Large Language Model) は、大量のテキストデータで学習し、系列の次に来るべきテキストを予測するニューラルネットワークです。
これは非常に高度なオートコンプリートシステムのようなものだと考えてください。スマホで文字を入力すると次の単語を提案してくれますが、それがLLMのすることの単純な版です。ただしLLMは、規模と洗練度が桁違いで、次のようなことが可能になります:
- 質問に対して一貫性があり、文脈に合った応答を生成する
- コード、エッセイ、メールなどの構造化されたコンテンツを書く
- 言語間で翻訳する
- 長い文書を要約する
- 非構造テキストから情報を抽出する
- そのほか多数
LLMが従来のソフトウェアと異なる点
従来のソフトウェアは、あなたがプログラムした明示的なルールに従います:
def calculate_discount(price, customer_type):
if customer_type == "premium":
return price * 0.8 # 20% discount
elif customer_type == "regular":
return price * 0.95 # 5% discount
else:
return priceこの関数は、同じ入力には常に同じ出力を返します。ロジックは決定的で透明です。
LLMは異なる働きをします。明示的なルールの代わりに、学習データから得たパターンを使って応答を生成します。あなたは入力テキスト(プロンプト(prompt) と呼ばれます)を与え、モデルは出力テキスト(補完(completion) または 応答(response) と呼ばれます)を生成します。
# 概念例 - すぐに実コードを書きます
response = llm.generate("プレミアム顧客に適した割引率は何ですか?")
# 出力例: "プレミアム顧客は通常15-25%の割引を受けます..."LLMにはハードコードされた割引率はありません。学習中に獲得したパターンに基づいて応答を生成します。つまり:
- 応答は変動し得る: 同じプロンプトでも毎回少し違う応答になることがあります
- 挙動はプログラムではなく学習による: 明示的なロジックを書くのではなく、プロンプトでモデルを誘導します
- 能力はスケールから創発する: 明示的に学習していないタスクも扱える場合があります
重要な用語
頻繁に登場する用語を定義します:
- プロンプト(prompt): モデルに送る入力テキスト。「質問」または「指示」と考えてください
- 補完/応答(completion/response): プロンプトに対してモデルが生成するテキスト
- トークン(token): LLMが扱う基本単位。概ね 1 token ≈ 4文字または単語の¾ 程度です。"Hello world" は約2トークンです
- コンテキストウィンドウ(context window): モデルが一度に処理できる最大テキスト量(トークン単位)。GPT-5-miniのコンテキストウィンドウは400Kトークンです
- 温度(temperature): ランダム性を制御するパラメータ。低い(0.0-0.3) = より焦点が定まり決定的。高い(0.7-1.0) = より創造的で多様
LLMにできること・できないこと
LLMが確実にできること、そしてできるように見えるだけのことを理解するのは、堅牢なAIエージェント(agent)を構築するうえで不可欠です。
LLMが得意なこと:
- 自然言語の理解と生成: 意図を解釈し、一貫した応答を生成し、複雑な言い回しにも対応できます
"返金したい" → 意図を認識: refund_request
"この文書を要約して" → 簡潔な要約を生成- プロンプト内の指示に従うこと: 明確な指示があれば、JSONや整形テキストのような構造化出力を生成できます
"JSONに変換: John Smith, 32, lives in Boston"
→ {"name": "John Smith", "age": 32, "city": "Boston"}-
テキスト内のパターン認識: 感情分析、カテゴリ分類、情報抽出は安定して機能します
-
コードと構造化コンテンツの生成: 適切にプロンプトすれば、妥当なPython、SQL、または他の整形出力を書けます
-
段階的な推論: 「ステップごとに考えて」と明示すると、問題を系統立てて分解します
LLMの制約:
- データベースではない: 事実を検索するのではなく、統計的にもっともらしいテキストを生成します。権威的に聞こえる誤情報を自信満々に述べることがあります。
"Python 4.0はいつリリースされましたか?"
→ "Python 4.0は2023年にリリースされました" を生成するかもしれません(誤りですが、もっともらしい)- 電卓ではない: 計算するのではなく、答えが「どう見えるべきか」を予測します。簡単な算数はうまくいくことが多い一方、複雑な数学は予測不能に失敗します。
"8,247 × 6,839 はいくつ?" → もっともらしく見える誤答になることがあります-
決定的ではない: 同じプロンプトでも毎回異なる出力になり得ます。この変動はtemperatureパラメータで制御します。
-
常に正確とは限らない: 事実の正しさに関係なく、もっともらしい文章を生成します。「ハルシネーション(hallucinations)」—詳細で自信に満ちていますが完全に捏造された情報—が頻繁に起こります。
重要な洞察: エージェント(agent)は、LLM(理解と意思決定のため)と従来のツール(計算、データ取得、事実に基づく操作のため)を組み合わせて構築してください。このパターンは第13章から実装し、LLMが自分で数学をしようとするのではなく、電卓を使うべきタイミングを判断するようにします。
学べること
本書では、LLMがあらかじめ決められたロジックに従うのではなく、目標を達成するためにどの行動を取るべきかを自律的に判断するシステムである AIエージェント(agent) を構築する方法を学びます。このパラダイムは第2章で深く掘り下げます。
1.2) 依存関係のインストール
開発環境をセットアップしましょう。クリーンなプロジェクト構成を作り、AIエージェント(agent)を構築するために使うフレームワークであるLangChainをインストールします。
Pythonインストールの確認
まず、システムにPythonがインストールされていることを確認します。Python 3.10以上を推奨します(2026年時点ではPython 3.13または3.14が良い選択です)。
Pythonのバージョンを確認します:
python --version
# or
python3 --versionPython 3.13.x または Python 3.14.x のような出力が表示されるはずです。
Pythonがインストールされていない場合:
-
macOS:
- python.org からダウンロード
- またはHomebrewを使用:
brew install python@3.14
-
Windows:
- python.org からダウンロード
- インストール時に「Add Python to PATH」にチェックを入れる
-
Linux:
- Ubuntu/Debian:
sudo apt update && sudo apt install python3.14 - Fedora:
sudo dnf install python3.14
- Ubuntu/Debian:
インストール後、python --version で再度確認してください。
注: システムによっては python の代わりに python3 を使う必要があります。本書全体を通して、python が動作しない場合は python3 を試してください。
プロジェクトを作成する
ターミナルを開き、プロジェクト用の新しいディレクトリを作成します:
mkdir agentic-ai-project
cd agentic-ai-project依存関係を分離するために仮想環境を作成します:
python -m venv venv仮想環境を有効化します:
# On macOS/Linux:
source venv/bin/activate
# On Windows:
venv\Scripts\activateターミナルのプロンプトに (venv) が表示され、仮想環境が有効になったことを示すはずです。
LangChainとOpenAIをインストールする
OpenAIのモデルを扱うために必要なものがすべて含まれている、LangChainのOpenAI統合をインストールします:
pip install langchain-openaiこれにより、依存関係と一緒に langchain-openai がインストールされます。依存関係には langchain-core(LangChainのコア抽象化)やOpenAIのPythonクライアントが含まれます。複数パッケージのインストールが確認できる出力が表示されるはずです。
インストールを確認します:
pip show langchain-openaiインストールされたパッケージの詳細(バージョン番号や場所など)が表示されるはずです。これでインストールが成功したことを確認できます。
OpenAI APIキーを取得する
OpenAIのモデルを呼び出すにはAPIキーが必要です:
- platform.openai.com にアクセス
- サインアップまたはログイン
- アカウント設定のAPI Keysへ移動
- 「Create new secret key」をクリック
- キーをコピー(
sk-で始まります)
⚠️ セキュリティ警告: このキーはパスワード同様に扱ってください。バージョン管理にコミットしたり、公開共有したりしないでください。キーを持つ人は誰でも、あなたのアカウントに課金されるAPI呼び出しができます。
APIキーを環境変数として設定する
APIキーを渡す推奨方法は、環境変数を使うことです:
# On macOS/Linux:
export OPENAI_API_KEY='sk-your-actual-key-here'
# On Windows (Command Prompt):
set OPENAI_API_KEY=sk-your-actual-key-here
# On Windows (PowerShell):
$env:OPENAI_API_KEY='sk-your-actual-key-here'注: この設定は一時的で、ターミナルを閉じると失われます。恒久的にするには、次のいずれかを行えます:
- exportコマンドをシェル設定ファイル(
.bashrc、.zshrcなど)に追加する .envファイルを使う(より良いプロジェクト構成のために第3章で設定します)
ひとまず、続けるには一時設定で十分です。
設定できたか確認します:
# On macOS/Linux:
echo $OPENAI_API_KEY
# On Windows (Command Prompt):
echo %OPENAI_API_KEY%
# On Windows (PowerShell):
echo $env:OPENAI_API_KEYAPIキーが表示されるはずです。表示されない場合は、export/setコマンドをやり直し、タイプミスがないか確認してください。
1.3) 最初のLLM呼び出し
いよいよ本番です。最初のLLM呼び出しを行いましょう。first_call.py というファイルを作成します:
# first_call.py
from langchain_openai import ChatOpenAI
# LLMを初期化します
llm = ChatOpenAI(model="gpt-5-mini")
# プロンプトを送信して応答を取得します
response = llm.invoke("LangChainとは何ですか?")
# 応答を表示します
print(response.content)実行します:
python first_call.py次のような出力が表示されるはずです(文言は正確に一致しない場合があります):
LangChainは、大規模言語モデル(LLM)を活用したアプリケーションの開発を簡素化するために設計されたフレームワークです。LLM呼び出しのチェーンを構築するためのツールと抽象化を提供し、外部データソースの統合、プロンプト管理、さまざまなAPIやデータベースと対話できるエージェントの作成を可能にします。LangChainは再利用可能なコンポーネントとパターンを提供することで、複雑なAIアプリケーションをより簡単に構築できます。おめでとうございます! 最初のLLM呼び出しができました。このコードで何が起きたのかを分解して見ていきましょう。
トラブルシューティング: エラーが出た場合:
AuthenticationError: APIキーが無効、または設定されていません →OPENAI_API_KEY環境変数を確認してください(1.2節参照)RateLimitError: リクエストが速すぎる、または使用上限を超えました → 数秒待って再試行するか、platform.openai.com/usage で使用状況を確認してくださいAPIConnectionError: ネットワーク接続の問題 → インターネット接続を確認してください
コードの理解
LLMラッパーをインポートする:
from langchain_openai import ChatOpenAIChatOpenAI は LangChain のOpenAIチャットモデルに対するラッパーです。API認証、リクエストのフォーマット、レスポンスのパースを代わりに処理します。
モデルを初期化する:
llm = ChatOpenAI(model="gpt-5-mini")これにより、GPT-5-miniを使うよう設定されたインスタンスが作成されます。裏側では、LangChainが認証のために OPENAI_API_KEY 環境変数を読み取ります。キーを明示的に渡すこともできます:
llm = ChatOpenAI(model="gpt-5-mini", api_key="sk-your-key")ただし、環境変数を使う方がより安全で柔軟です。
モデルを呼び出す:
response = llm.invoke("LangChainとは何ですか?")invoke() メソッドは、プロンプトをOpenAIのAPIへ送り、完全な応答を待ちます。これは同期(synchronous) 呼び出しで、応答が到着するまでプログラムは停止します。
応答コンテンツにアクセスする:
print(response.content)レスポンスオブジェクトには複数のフィールドがあります。.content フィールドには、モデルが生成した実際のテキストが入っています。次の節で他のフィールドも見ていきます。
別のプロンプトを試す
プロンプトを変更して、入力が違うとモデルがどう応答するか確認してみましょう:
# first_call.py
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-5-mini")
# 別のプロンプトを試します
prompts = [
"Pythonのデコレータを1文で説明してください。",
"15 * 23 はいくつ?",
"Pythonで型ヒントを使う利点を3つ挙げてください。",
]
for prompt in prompts:
response = llm.invoke(prompt)
print(f"Prompt: {prompt}")
print(f"Response: {response.content}\n")モデルは、説明、計算、構造化されたリストなど、異なる種類のリクエストを扱えます。同じプロンプトを複数回実行すると、応答がわずかに変わることに気づくでしょう。これは正常な挙動です—なぜそうなるのか、そしてどう制御するのかは第2章で探ります。
1.4) いま何が起きた?(リクエスト → モデル → 応答の流れ)
llm.invoke() を呼び出したときに何が起きたのかを正確に見ていきましょう。この流れを理解することは、信頼できるAIエージェント(agent)を構築するうえで重要です。
完全なリクエスト-レスポンスのサイクル
各ステップをたどってみましょう:
ステップ1: あなたのコードがinvoke()を呼び出す
response = llm.invoke("LangChainとは何ですか?")invoke() メソッドは、LLMに対する主要なインターフェースです。プロンプト文字列を渡すと、モデルの回答を含むレスポンスオブジェクトが返ります。このシンプルな呼び出しの裏側で、いくつかのステップが自動的に実行されます。
ステップ2: LangChainがリクエストを整形する
LangChainは、あなたの文字列を構造化されたAPIリクエストに変換します。裏側では、次のようなJSONペイロードを作ります:
{
"model": "gpt-5-mini",
"messages": [
{
"role": "user",
"content": "LangChainとは何ですか?"
}
],
"temperature": 1.0
}messages 配列は、チャットモデルが入力を受け取る方法です。各メッセージには role(user、assistant、またはsystem)と content(テキスト)があります。メッセージの役割は第4章で扱います。
ステップ3: OpenAIへのAPI呼び出し
LangChainはOpenAIのAPIエンドポイントにHTTPSのPOSTリクエストを送ります:
POST https://api.openai.com/v1/chat/completions
Authorization: Bearer sk-your-api-key
Content-Type: application/json
{request payload}APIキーによりリクエストが認証されます。OpenAIのサーバーがリクエストを受け取り、指定されたモデルへルーティングします。
ステップ4: モデルがプロンプトを処理する
GPT-5-miniはプロンプトを受け取り、トークン(token)単位で応答を生成します。モデルは:
- テキストをトークン(数値表現)に変換する
- トークンをニューラルネットワークの層で処理する
- 次に来る可能性がもっとも高いトークンを予測する
- 完全な応答を生成するか停止条件に到達するまで繰り返す
これはOpenAIのサーバー上で起きます—あなたのコードは結果を待つだけです。
ステップ5: APIが応答を返す
OpenAIのAPIはJSONレスポンスを返します:
{
"id": "chatcmpl-8x7y9z",
"object": "chat.completion",
"created": 1704067200,
"model": "gpt-5-mini",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "LangChainは、大規模言語モデル(LLM)を活用したアプリケーションの開発を簡素化するために設計されたフレームワークです..."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 12,
"completion_tokens": 58,
"total_tokens": 70
}
}主要フィールド:
- message.content: 生成テキスト
- usage: 課金とモニタリングのためのトークン数
- finish_reason: 生成が止まった理由("stop" = 自然終了、"length" = トークン上限に到達)
ステップ6: LangChainが応答をパースする
LangChainはJSONを、扱いやすいPythonオブジェクトに変換します:
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-5-mini")
response = llm.invoke("What is LangChain?")
# レスポンスオブジェクトを確認します
print(f"Content: {response.content}")
print(f"Type: {type(response)}")
print(f"Response metadata: {response.response_metadata}")出力:
Content: LangChainは、開発を簡素化するために設計されたフレームワークです...
Type: <class 'langchain_core.messages.ai.AIMessage'>
Response metadata: {'token_usage': {'completion_tokens': 58, 'prompt_tokens': 12, 'total_tokens': 70}, 'model_name': 'gpt-5-mini', 'finish_reason': 'stop'}レスポンスは AIMessage オブジェクトで、いくつか便利な属性があります:
- content: 生成テキスト(通常これが欲しいものです)
- response_metadata: トークン使用量、モデル名、finish reason
- id: この応答の一意な識別子
- usage_metadata: トークンの詳細な内訳
トークン使用量の理解
トークン数を見る前に簡単に補足します。トークン(tokens) はLLMが処理する基本単位です。英語では通常、1単語あたり1トークンより少し多い程度(例: "explain quantum computing" = 3単語、4-5トークン)ですが、韓国語や中国語など英語以外の言語では、同じテキストを表現するのに大幅に多くのトークンが必要です。トークンについては第2章で詳しく扱います。
トークン消費をもう少し詳しく見てみましょう:
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-5-mini")
response = llm.invoke("量子コンピューティングを簡単な言葉で説明してください。")
usage = response.response_metadata['token_usage']
print(f"Input tokens: {usage['prompt_tokens']}")
print(f"Output tokens: {usage['completion_tokens']}")
print(f"Total tokens: {usage['total_tokens']}")出力:
Input tokens: 11
Output tokens: 95
Total tokens: 106注: prompt_tokens = 入力トークン(あなたのプロンプト)、completion_tokens = 出力トークン(モデルの応答)、total_tokens = 両者の合計です。
トークン消費は次の要因で変動します:
- プロンプトの長さ: 長いプロンプトほど入力トークンが増えます
- 応答の詳細度: 詳細な応答ほど出力トークンが増えます
- 言語の複雑さ: 技術用語やコードはトークン化が異なる場合があります
たとえば、"What's 2+2?" のような短いプロンプトは入力5-6トークン、出力8-10トークン程度かもしれません。一方で "Write a detailed essay about the history of Python programming language" は入力15-20トークン、出力500+トークンになる可能性があります。
先ほどの例のコスト計算:
GPT-5-miniの価格(入力100万トークンあたり$0.25、出力100万トークンあたり$2.00)では:
- 入力: 11トークン × $0.25 / 1,000,000 = $0.00000275
- 出力: 95トークン × $2.00 / 1,000,000 = $0.00019
- 合計: 約$0.0002(1セントの2/100)
入力トークンと出力トークンの両方に課金されますが、出力トークンの方が高い(この場合は8倍)点に注意してください。
学んだこと
これで、LLM呼び出しの完全なライフサイクルを理解できました:
- あなたのコードがプロンプト文字列を渡す
- LangChainが認証付きのAPIリクエストに整形する
- OpenAIのAPIがリクエストをモデルへルーティングする
- モデルがトークン単位で応答を生成する
- APIが応答とメタデータを含む構造化JSONを返す
- LangChainがそれをPythonオブジェクトにパースする
- あなたのコードが内容とメタデータへアクセスする
さらに学んだこと:
- レスポンスオブジェクトを調べ、メタデータを取り出す方法
- トークン使用量がコストに影響する仕組み
この土台により、第2章で、LLMが内部で実際にどう動くのかを探り、さまざまなモデルを比較し、より良い結果を得るためのプロンプトエンジニアリング(prompt engineering)技法を学ぶ準備が整いました。