AIエージェントプログラミング実践ガイド - LangChain・Function Calling・RAGで作る自律型AI
AIエージェントは、自律的に思考し行動するAIシステムです。LangChain、Function Calling、RAGなどの最新技術を使って、実践的なAIエージェントを構築する方法を詳しく解説します。
GPT-4o、Claude 3、Geminiなど最新のマルチモーダルAIモデルを活用したアプリケーション開発の実践ガイド。実装方法、ベストプラクティス、コスト最適化まで包括的に解説します。
マルチモーダル ai は、テキスト、画像、音声、動画など複数の入力形式を理解し、統合的に処理できる次世代の ai 技術です。2025 年現在、GPT-4o、Claude 3、Google Gemini などの最新モデルにより、従来は不可能だった高度なアプリケーションの開発が可能になりました。本記事では、マルチモーダル ai の実装方法から実践的な活用例まで、包括的に解説します。
マルチモーダル ai は、複数の入力モダリティ(テキスト、画像、音声、動画など)を同時に理解し、統合的に処理できるAIシステムです。人間が五感を使って世界を理解するように、ai も複数の情報源から包括的な理解を構築できるようになりました。
チャートを読み込み中...
特徴 | 説明 | メリット |
---|---|---|
統合的理解 | 複数の情報源を組み合わせた深い理解 | 文脈を考慮した高精度な処理 |
相互補完 | 一つのモダリティの不足を他で補完 | ロバストで信頼性の高い推論 |
自然なインタラクション | 人間的な対話と理解 | 直感的なユーザー体験 |
汎用性 | 様々なタスクに対応可能 | 一つのモデルで多様な用途 |
創造的生成 | マルチモーダルなコンテンツ生成 | リッチなコンテンツ制作 |
2025 年現在、複数の強力なマルチモーダル ai モデルが利用可能です。それぞれの特徴を理解し、用途に応じて選択することが重要です。
モデル | 提供元 | 強み | コスト(1M tokens) | 対応モダリティ |
---|---|---|---|---|
GPT-4o | OpenAI | リアルタイム処理、音声対応 | $5-$15 | テキスト、画像、音声 |
Claude 3 Opus | Anthropic | 高精度な画像理解、大容量コンテキスト | $15-$75 | テキスト、画像 |
Claude 3 Sonnet | Anthropic | バランスの良い性能 | $3-$15 | テキスト、画像 |
Gemini Ultra | 多言語対応、Google連携 | $7-$21 | テキスト、画像、動画 | |
LLaVA 1.6 | OSS | カスタマイズ可能 | 自己ホスティング | テキスト、画像 |
マルチモーダル ai を実装する際の基本的な api の使い方を、主要なプロバイダーごとに解説します。
各プロバイダーの api キーを取得し、環境変数に設定してください:
OPENAI_API_KEY
ANTHROPIC_API_KEY
GOOGLE_API_KEY
# OpenAI GPT-4oの実装例
from openai import OpenAI
import base64
client = OpenAI()
def analyze_image_with_text(image_path, text_prompt):
# 画像をBase64エンコード
with open(image_path, "rb") as image_file:
base64_image = base64.b64encode(image_file.read()).decode('utf-8')
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": text_prompt},
{
"type": "image_url",
"image_url": {
"url": f"data:image/jpeg;base64,{base64_image}"
}
}
]
}
],
max_tokens=1000
)
return response.choices[0].message.content
# 音声とテキストの統合処理
def process_audio_with_context(audio_path, context):
# 音声をテキストに変換
with open(audio_path, "rb") as audio_file:
transcript = client.audio.transcriptions.create(
model="whisper-1",
file=audio_file
)
# テキストと音声内容を統合して処理
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": context},
{"role": "user", "content": transcript.text}
]
)
return response.choices[0].message.content
# Anthropic Claude 3の実装例
import anthropic
import base64
client = anthropic.Anthropic()
def analyze_with_claude(image_path, text_prompt):
# 画像を読み込んでBase64エンコード
with open(image_path, "rb") as image_file:
image_data = base64.b64encode(image_file.read()).decode('utf-8')
message = client.messages.create(
model="claude-3-opus-20240229",
max_tokens=1000,
messages=[
{
"role": "user",
"content": [
{
"type": "text",
"text": text_prompt
},
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/jpeg",
"data": image_data
}
}
]
}
]
)
return message.content[0].text
# 複数画像の比較分析
def compare_images(image_paths, comparison_prompt):
content = [{"type": "text", "text": comparison_prompt}]
for path in image_paths:
with open(path, "rb") as img:
content.append({
"type": "image",
"source": {
"type": "base64",
"media_type": "image/jpeg",
"data": base64.b64encode(img.read()).decode('utf-8')
}
})
message = client.messages.create(
model="claude-3-opus-20240229",
max_tokens=2000,
messages=[{"role": "user", "content": content}]
)
return message.content[0].text
# Google Gemini の実装例
import google.generativeai as genai
from PIL import Image
genai.configure(api_key=os.environ["GOOGLE_API_KEY"])
def analyze_with_gemini(image_path, text_prompt):
# Gemini Proモデルを使用
model = genai.GenerativeModel('gemini-1.5-pro')
# 画像を読み込み
image = Image.open(image_path)
# マルチモーダル入力で生成
response = model.generate_content([text_prompt, image])
return response.text
# 動画分析(Geminiの特徴的機能)
def analyze_video(video_path, analysis_prompt):
model = genai.GenerativeModel('gemini-1.5-pro')
# 動画ファイルをアップロード
video_file = genai.upload_file(path=video_path)
# 動画を分析
response = model.generate_content([
analysis_prompt,
video_file
])
return response.text
# ストリーミング応答
def stream_multimodal_response(image_path, prompt):
model = genai.GenerativeModel('gemini-1.5-pro')
image = Image.open(image_path)
response = model.generate_content(
[prompt, image],
stream=True
)
for chunk in response:
print(chunk.text, end='')
# オープンソースモデル(LLaVA)の実装例
from transformers import LlavaNextProcessor, LlavaNextForConditionalGeneration
import torch
from PIL import Image
# モデルとプロセッサーの読み込み
model_id = "llava-hf/llava-v1.6-mistral-7b-hf"
processor = LlavaNextProcessor.from_pretrained(model_id)
model = LlavaNextForConditionalGeneration.from_pretrained(
model_id,
torch_dtype=torch.float16,
device_map="auto"
)
def analyze_with_llava(image_path, text_prompt):
# 画像の読み込み
image = Image.open(image_path)
# プロンプトの準備
prompt = f"USER: <image>\n{text_prompt}\nASSISTANT:"
# 入力の処理
inputs = processor(
text=prompt,
images=image,
return_tensors="pt"
).to(model.device)
# 推論の実行
with torch.no_grad():
output = model.generate(
**inputs,
max_new_tokens=512,
do_sample=True,
temperature=0.7
)
# 結果のデコード
response = processor.decode(
output[0],
skip_special_tokens=True
).split("ASSISTANT:")[-1].strip()
return response
# バッチ処理で効率化
def batch_process_images(image_paths, prompts):
images = [Image.open(path) for path in image_paths]
# バッチ処理用の入力準備
batch_prompts = [
f"USER: <image>\n{prompt}\nASSISTANT:"
for prompt in prompts
]
inputs = processor(
text=batch_prompts,
images=images,
return_tensors="pt",
padding=True
).to(model.device)
with torch.no_grad():
outputs = model.generate(
**inputs,
max_new_tokens=512,
do_sample=True
)
results = []
for output in outputs:
response = processor.decode(
output,
skip_special_tokens=True
).split("ASSISTANT:")[-1].strip()
results.append(response)
return results
マルチモーダル ai の実践的な活用例を、具体的なコードとともに紹介します。
ユーザーが商品画像と説明文を提供
マルチモーダルAIが画像と文章から特徴を抽出
ベクトルDBで類似商品を高速検索
自然言語で商品説明を生成
# インテリジェント商品検索システムの実装
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
import chromadb
class MultimodalProductSearch:
def __init__(self, model_provider="claude"):
self.model_provider = model_provider
self.chroma_client = chromadb.Client()
self.collection = self.chroma_client.create_collection(
name="products",
metadata={"hnsw:space": "cosine"}
)
def extract_features(self, image_path, text_description):
"""画像とテキストから特徴を抽出"""
if self.model_provider == "claude":
prompt = f"""
画像とテキストから商品の特徴を抽出してください。
テキスト説明: {text_description}
以下の形式でJSON出力してください:
{{
"category": "カテゴリー",
"color": "主要な色",
"style": "スタイル",
"features": ["特徴1", "特徴2", ...],
"embedding_text": "検索用の統合説明文"
}}
"""
result = analyze_with_claude(image_path, prompt)
return json.loads(result)
def add_product(self, product_id, image_path, description):
"""商品をデータベースに追加"""
features = self.extract_features(image_path, description)
# エンベディングの生成(実際はより高度な手法を使用)
embedding = self.generate_embedding(features["embedding_text"])
self.collection.add(
documents=[features["embedding_text"]],
metadatas=[features],
ids=[product_id],
embeddings=[embedding]
)
def search_similar_products(self, query_image, query_text, top_k=5):
"""類似商品を検索"""
# クエリの特徴抽出
query_features = self.extract_features(query_image, query_text)
query_embedding = self.generate_embedding(
query_features["embedding_text"]
)
# 類似検索
results = self.collection.query(
query_embeddings=[query_embedding],
n_results=top_k
)
return self.format_results(results)
def generate_embedding(self, text):
"""テキストからエンベディングを生成(簡略化)"""
# 実際はSentence TransformersやOpenAI Embeddingsを使用
return np.random.randn(768).tolist()
リアルタイム処理では、フレームレートとレイテンシのバランスが重要です。必要に応じてフレームをスキップし、バッチ処理を活用してください。
# リアルタイム動画分析システム
import cv2
import asyncio
from concurrent.futures import ThreadPoolExecutor
import time
class RealtimeVideoAnalyzer:
def __init__(self, model="gpt-4o", fps_target=5):
self.model = model
self.fps_target = fps_target
self.frame_interval = 1.0 / fps_target
self.executor = ThreadPoolExecutor(max_workers=3)
async def analyze_video_stream(self, video_source):
"""ビデオストリームをリアルタイムで分析"""
cap = cv2.VideoCapture(video_source)
last_process_time = 0
try:
while True:
ret, frame = cap.read()
if not ret:
break
current_time = time.time()
# フレームレート制御
if current_time - last_process_time >= self.frame_interval:
# 非同期で分析
asyncio.create_task(
self.process_frame(frame, current_time)
)
last_process_time = current_time
# リアルタイム表示(オプション)
cv2.imshow('Video Stream', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
finally:
cap.release()
cv2.destroyAllWindows()
async def process_frame(self, frame, timestamp):
"""フレームを分析"""
# フレームを一時的に保存
temp_path = f"temp_frame_{timestamp}.jpg"
cv2.imwrite(temp_path, frame)
try:
# マルチモーダルAIで分析
analysis = await self.analyze_frame_async(temp_path)
# 結果を処理
await self.handle_analysis_result(analysis, timestamp)
finally:
# 一時ファイルを削除
os.remove(temp_path)
async def analyze_frame_async(self, image_path):
"""非同期でフレームを分析"""
loop = asyncio.get_event_loop()
# ブロッキング処理を別スレッドで実行
return await loop.run_in_executor(
self.executor,
self.analyze_frame_sync,
image_path
)
def analyze_frame_sync(self, image_path):
"""同期的にフレームを分析"""
prompt = """
この画像から以下を検出してください:
1. 人物の数と位置
2. 主要なオブジェクト
3. 特筆すべき行動やイベント
JSON形式で出力してください。
"""
if self.model == "gpt-4o":
return analyze_image_with_text(image_path, prompt)
# 他のモデルの処理...
マルチモーダル ai の導入により、複雑な金融文書の処理時間が 80%削減され、精度も 95%以上を達成しました。特に、表やグラフを含む文書の理解が大幅に改善されました。
# マルチモーダル文書理解システム
class DocumentUnderstandingSystem:
def __init__(self):
self.claude_client = anthropic.Anthropic()
def analyze_document(self, pdf_path):
"""PDFドキュメントを包括的に分析"""
# PDFを画像に変換
images = self.pdf_to_images(pdf_path)
# 各ページを分析
page_analyses = []
for i, image_path in enumerate(images):
analysis = self.analyze_page(image_path, i + 1)
page_analyses.append(analysis)
# 全体のサマリーを生成
summary = self.generate_document_summary(page_analyses)
return {
"page_analyses": page_analyses,
"summary": summary,
"key_insights": self.extract_key_insights(page_analyses)
}
def analyze_page(self, image_path, page_number):
"""ページを詳細に分析"""
prompt = f"""
このドキュメントのページ{page_number}を分析してください。
以下の要素を特定してください:
1. テキストコンテンツ(段落、見出し)
2. 表やグラフ
3. 図表や画像
4. 重要な数値やデータ
構造化されたJSON形式で出力してください。
"""
message = self.claude_client.messages.create(
model="claude-3-opus-20240229",
max_tokens=2000,
messages=[{
"role": "user",
"content": [
{"type": "text", "text": prompt},
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": self.encode_image(image_path)
}
}
]
}]
)
return json.loads(message.content[0].text)
def extract_tables_and_charts(self, image_path):
"""表とグラフを抽出して構造化データに変換"""
prompt = """
画像内のすべての表とグラフを識別し、
それぞれのデータを構造化形式で抽出してください。
表の場合:ヘッダーと各行のデータ
グラフの場合:軸ラベルとデータポイント
"""
result = self.claude_client.messages.create(
model="claude-3-opus-20240229",
max_tokens=3000,
messages=[{
"role": "user",
"content": [
{"type": "text", "text": prompt},
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": self.encode_image(image_path)
}
}
]
}]
)
return json.loads(result.content[0].text)
マルチモーダル ai を本番環境で使用する際の最適化手法を紹介します。
戦略 | 実装方法 | 削減効果 |
---|---|---|
モデルの使い分け | タスクに応じて軽量モデルを選択 | 最大70%削減 |
キャッシング | 同一入力の結果をキャッシュ | 30-50%削減 |
バッチ処理 | 複数リクエストをまとめて処理 | 20-30%削減 |
プロンプト最適化 | 簡潔で効率的なプロンプト設計 | 10-20%削減 |
画像圧縮 | 品質を保ちつつファイルサイズ削減 | 15-25%削減 |
class CostOptimizedMultimodalAI:
def __init__(self):
self.model_costs = {
"claude-3-haiku": {"input": 0.25, "output": 1.25},
"claude-3-sonnet": {"input": 3, "output": 15},
"claude-3-opus": {"input": 15, "output": 75},
"gpt-4o": {"input": 5, "output": 15},
"gpt-4o-mini": {"input": 0.15, "output": 0.6}
}
self.cache = {}
def select_optimal_model(self, task_complexity, budget_constraint):
"""タスクの複雑さと予算に基づいて最適なモデルを選択"""
if task_complexity == "simple":
return "gpt-4o-mini" if budget_constraint == "strict" else "claude-3-haiku"
elif task_complexity == "medium":
return "claude-3-sonnet"
else:
return "claude-3-opus" if budget_constraint != "strict" else "gpt-4o"
def process_with_caching(self, input_data, task_type):
"""キャッシングを活用した処理"""
# キャッシュキーの生成
cache_key = self.generate_cache_key(input_data, task_type)
# キャッシュチェック
if cache_key in self.cache:
return self.cache[cache_key]
# 処理実行
result = self.execute_task(input_data, task_type)
# キャッシュ保存
self.cache[cache_key] = result
return result
def batch_process_images(self, images, prompts):
"""バッチ処理で効率化"""
# 画像を圧縮
compressed_images = [self.compress_image(img) for img in images]
# タスクの複雑さを評価
complexities = [self.evaluate_complexity(p) for p in prompts]
# モデルごとにグループ化
model_groups = {}
for img, prompt, complexity in zip(compressed_images, prompts, complexities):
model = self.select_optimal_model(complexity, "moderate")
if model not in model_groups:
model_groups[model] = []
model_groups[model].append((img, prompt))
# 各モデルでバッチ処理
results = []
for model, tasks in model_groups.items():
batch_results = self.process_batch_with_model(model, tasks)
results.extend(batch_results)
return results
def compress_image(self, image_path, max_size=1024):
"""画像を圧縮して処理コストを削減"""
from PIL import Image
img = Image.open(image_path)
# アスペクト比を保ちながらリサイズ
img.thumbnail((max_size, max_size), Image.Resampling.LANCZOS)
# 一時ファイルに保存
temp_path = f"temp_compressed_{os.path.basename(image_path)}"
img.save(temp_path, "JPEG", quality=85, optimize=True)
return temp_path
マルチモーダル ai を扱う際の重要なセキュリティ対策を解説します。
# セキュリティを考慮した実装
class SecureMultimodalProcessor:
def __init__(self):
self.pii_patterns = [
r'\b\d{3}-\d{2}-\d{4}\b', # SSN
r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b', # Email
r'\b\d{16}\b', # Credit card
]
def sanitize_text(self, text):
"""テキストからPIIを除去"""
import re
sanitized = text
for pattern in self.pii_patterns:
sanitized = re.sub(pattern, '[REDACTED]', sanitized)
return sanitized
def blur_faces(self, image_path):
"""顔を検出してぼかし処理"""
import cv2
img = cv2.imread(image_path)
face_cascade = cv2.CascadeClassifier(
cv2.data.haarcascades + 'haarcascade_frontalface_default.xml'
)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.1, 4)
for (x, y, w, h) in faces:
roi = img[y:y+h, x:x+w]
blur = cv2.GaussianBlur(roi, (23, 23), 30)
img[y:y+h, x:x+w] = blur
temp_path = "temp_blurred.jpg"
cv2.imwrite(temp_path, img)
return temp_path
def process_secure(self, image_path, text_prompt):
"""セキュアな処理パイプライン"""
# テキストのサニタイズ
sanitized_prompt = self.sanitize_text(text_prompt)
# 画像の匿名化
blurred_image = self.blur_faces(image_path)
try:
# 処理実行
result = self.process_multimodal(blurred_image, sanitized_prompt)
# 結果もサニタイズ
return self.sanitize_text(result)
finally:
# 一時ファイルの削除
if os.path.exists(blurred_image):
os.remove(blurred_image)
マルチモーダル ai の技術は急速に進化しています。今後期待される発展について解説します。
ストリーミング動画のリアルタイム分析が一般化
3Dモデルやポイントクラウドの直接処理
五感すべてを扱うマルチモーダルAI
複雑なタスクを自律的に遂行
マルチモーダル ai は、テキスト、画像、音声を統合的に理解し処理する革新的な技術です。本記事で解説した内容をまとめます:
マルチモーダル ai は、私たちの開発するアプリケーションに新たな可能性をもたらします。本記事で紹介した技術とベストプラクティスを活用し、次世代のインテリジェントなアプリケーションを構築してください。