LLM アプリ開発 #1 はじめての API 呼び出しと開発環境のセットアップ
このシリーズは、LLM をはじめてコードで扱う方のための入門シリーズです。REST API やデータベースを扱った経験があれば、より楽に進められます。最後まで進めば、単純な呼び出しから始めて RAG やエージェントまで、実際に動く LLM アプリを自分で作れるようになります。
全13回で構成します。
- #1 はじめての API 呼び出しと開発環境のセットアップ ← この記事
- #2 メッセージとパラメータを理解する
- #3 ストリーミングで応答をリアルタイム出力
- #4 プロンプトエンジニアリングの実務
- #5 構造化された出力を受け取る
- #6 ツール呼び出しで外部機能を連携
- #7 埋め込みとベクトル検索
- #8 RAG パイプラインの構築
- #9 会話メモリとコンテキスト管理
- #10 AI エージェントを作る
- #11 MCP でツールを接続する
- #12 コスト・評価・観測
- #13 実践プロジェクト
コード例は Python で書き、モデルは Anthropic の Claude を使います。概念のほとんどは、ほかのプロバイダにもそのまま当てはまります。
LLM アプリは一般的なバックエンドと何が違うか #
コードから LLM を呼び出すことは、外部 API を呼び出すことと構造が似ています。HTTP リクエストを送り、応答を受け取ります。ところが中をのぞくと、慣れ親しんだバックエンド開発とは異なる性質がいくつかあります。この違いを先に押さえておくと、以降の回がなぜそうした方法を取るのかが理解できます。
第一に、出力が毎回異なります。 同じ入力を送っても、応答が同じには返りません。通常の関数は同じ引数に同じ結果を返しますが、LLM はそうではありません。そのため「正確にこの文字列が返る」を前提にコードを書くと壊れます。応答の形を強制し検証することが重要になりますが、これは #5 で扱います。
第二に、入力と出力が自然言語です。 何をさせるかを、関数シグネチャではなく文章で記述します。この文章をどう書くかで、結果の品質が大きく変わります。そのためプロンプトの作成が独立した技術になり、#4 で別途扱います。
第三に、コストがトークン単位です。 リクエストごとの固定料金ではなく、やり取りした文字量(正確にはトークン)に比例して課金されます。入力が長いほど、出力が長いほどコストが上がります。そのため、どれだけコンテキストを送るか、どうキャッシュするかが、実運用で重要なテーマになります。#12 で扱います。
第四に、応答が遅く、長くなり得ます。 LLM は答えを一度に出さず、トークンを一つずつ生成します。長い回答は数秒かかることもあります。そのため、生成されるそばから画面に流し込むストリーミングが基本の手法になり、#3 で扱います。
いまはこの四つを「そういう性質があるのだな」という程度に覚えておけば十分です。各回で一つずつ実際に扱っていきます。
準備するもの #
はじめての呼び出しには、三つが必要です。
- Anthropic アカウントと API キー
- Python 3.8 以上の環境
- 少しの利用クレジット(はじめての呼び出しの費用はごくわずかです)
API キーは Anthropic Console にログインしたあと、API Keys メニューから発行します。発行されたキーは一度しか全体が表示されないので、その場でコピーしておきます。
SDK のインストールとキーの設定 #
Anthropic は Python 用の公式 SDK を提供しています。仮想環境を作ったあとにインストールします。
python -m venv venv
source venv/bin/activate
pip install anthropic発行したキーは環境変数 ANTHROPIC_API_KEY に入れます。SDK はこの名前の環境変数を自動で読み込みます。
export ANTHROPIC_API_KEY="sk-ant-ここに発行したキー"こうしておけば、コードのどこにもキーの文字列が現れません。キーをコードに埋め込まない習慣は、最初から身につけておくのがよいです。
はじめての呼び出し #
では、Claude に一文を送り、応答を受け取ってみます。
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[
{"role": "user", "content": "一文で自己紹介をしてください。"}
],
)
for block in response.content:
if block.type == "text":
print(block.text)実行すると、Claude が生成した自己紹介の一文が出力されます。短いですが、このコードに LLM 呼び出しの基本的な骨格がすべて入っています。一つずつ分解していきます。
anthropic.Anthropic()— クライアントを作ります。引数を空にしておくと、環境変数ANTHROPIC_API_KEYからキーを読み込みます。model— どのモデルで答えるかを指定します。モデル選択はすぐ下で扱います。max_tokens— 応答が最大何トークンまで生成されるかの上限を決めます。この値を超えると応答が途中で切れます。messages— 会話の内容です。いまはユーザー(user)一人が一度だけ発言した形です。役割の構造は #2 で詳しく扱います。response.content— 応答は一つの文字列ではなく、ブロックのリストです。各ブロックのtypeを確認し、textブロックの内容を取り出します。
最後の部分は、はじめは面倒に感じるかもしれません。「テキストだけ返せばいいのに、なぜリストなのか」と思うところですが、あとでツール呼び出しや推論に関わるブロックが一緒に返り始めると、この構造が必要になります。そのため、最初から type を確認して取り出す習慣をつけておくのがよいです。
三つのモデルから選ぶ #
model に入れられる Claude モデルは、性能とコストによって大きく三つの等級に分かれます。
| 等級 | モデル ID | 性格 | 向いている用途 |
|---|---|---|---|
| 最も強力 | claude-opus-4-8 | 最も賢く高価 | 複雑な推論、長い作業、エージェント |
| バランス | claude-sonnet-4-6 | 速度と知能のバランス | ほとんどの実務作業 |
| 最も高速 | claude-haiku-4-5 | 速くて安い | 分類や要約のような単純な作業 |
学習段階では、バランス等級の claude-sonnet-4-6 が無難です。コスト負担が少なく、それでいてほとんどの例を十分にこなせます。単純な分類や短い変換のような軽い作業なら、より安価な Haiku で十分で、難しい推論が必要なら Opus を使います。このシリーズでは、回ごとに作業の性格に合ったモデルを選んで使います。
よくつまずくところ #
はじめての呼び出しの段階でよく出会う問題を、いくつか先に整理しておきます。
AuthenticationErrorが出る — 環境変数が設定されていないか、キーが間違っている場合です。echo $ANTHROPIC_API_KEYで値がきちんと入っているか確認します。新しいターミナルを開いたなら、exportをやり直す必要があるかもしれません。- 応答が途中で切れる —
max_tokensが小さすぎる場合です。応答のstop_reasonがmax_tokensで返れば上限に達しているので、値を増やします。 block.textでエラーになる — すべてのブロックがテキストとは限りません。上の例のように、block.type == "text"を先に確認してから取り出すと安全です。
この三つを知っておくだけでも、最初の30分のつまずきはほとんど避けられます。
まとめ #
今回は、LLM アプリが一般的なバックエンドとどう違うかを押さえ、API キーの発行から最初の応答までを実際に行いました。まとめると次のとおりです。
- LLM アプリは出力が毎回異なり、入出力が自然言語で、トークン単位で課金され、応答が遅くなり得ます。
- API キーは環境変数で扱い、コードに埋め込みません。
- 応答はブロックのリストなので、
typeを確認して取り出します。 - モデルは作業の性格に合わせて Opus、Sonnet、Haiku から選びます。
次回の「LLM アプリ開発 #2 メッセージとパラメータを理解する」では、いま軽く飛ばした messages の役割の構造と、temperature のようなパラメータをしっかり見ていきます。これを知ることで、Claude に文脈と指示を正確に伝えられるようになります。