LangChainは大規模言語モデルでアプリケーションを構築するためのフレームワークです。Amazon Bedrockと組み合わせることで、高度なAIアプリケーションを作成する強力なツールキットを提供します。
セットアップ
pip install langchain langchain-aws boto3
from langchain_aws import ChatBedrock, BedrockEmbeddings
import boto3
チャットモデル
基本的な使い方
from langchain_aws import ChatBedrock
from langchain_core.messages import HumanMessage, SystemMessage
llm = ChatBedrock(
model_id="anthropic.claude-3-sonnet-20240229-v1:0",
model_kwargs={"temperature": 0.7, "max_tokens": 1024}
)
messages = [
SystemMessage(content="あなたは親切なアシスタントです。"),
HumanMessage(content="クラウドコンピューティングとは何ですか?")
]
response = llm.invoke(messages)
print(response.content)
ストリーミング
for chunk in llm.stream(messages):
print(chunk.content, end="", flush=True)
プロンプトテンプレート
from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_messages([
("system", "あなたは{role}です。{language}で回答してください。"),
("human", "{question}")
])
chain = prompt | llm
response = chain.invoke({
"role": "技術エキスパート",
"language": "日本語",
"question": "REST APIを説明してください"
})
チェーン
シンプルなチェーン
from langchain_core.output_parsers import StrOutputParser
chain = prompt | llm | StrOutputParser()
result = chain.invoke({"role": "教師", "language": "日本語", "question": "Pythonとは?"})
シーケンシャルチェーン
from langchain_core.prompts import PromptTemplate
# ステップ1: アウトラインを生成
outline_prompt = PromptTemplate.from_template(
"{topic}についての記事のアウトラインを作成してください"
)
# ステップ2: アウトラインから記事を書く
article_prompt = PromptTemplate.from_template(
"このアウトラインに基づいて短い記事を書いてください:\n{outline}"
)
outline_chain = outline_prompt | llm | StrOutputParser()
article_chain = article_prompt | llm | StrOutputParser()
# 結合チェーン
full_chain = outline_chain | (lambda x: {"outline": x}) | article_chain
result = full_chain.invoke({"topic": "機械学習"})
メモリ
会話バッファ
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationChain
memory = ConversationBufferMemory()
conversation = ConversationChain(llm=llm, memory=memory)
print(conversation.predict(input="こんにちは、私は田中です"))
print(conversation.predict(input="私の名前は?")) # 「田中」を覚えている
サマリーメモリ
from langchain.memory import ConversationSummaryMemory
memory = ConversationSummaryMemory(llm=llm)
conversation = ConversationChain(llm=llm, memory=memory)
埋め込みとベクトルストア
from langchain_aws import BedrockEmbeddings
from langchain_community.vectorstores import FAISS
from langchain.text_splitter import RecursiveCharacterTextSplitter
# 埋め込みを作成
embeddings = BedrockEmbeddings(
model_id="amazon.titan-embed-text-v1"
)
# ドキュメントを分割
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50
)
documents = text_splitter.create_documents([
"ドキュメントの内容...",
"さらにドキュメントの内容..."
])
# ベクトルストアを作成
vectorstore = FAISS.from_documents(documents, embeddings)
# 検索
results = vectorstore.similarity_search("クエリ", k=3)
LangChainでRAG
from langchain.chains import RetrievalQA
# リトリーバーを作成
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
# RAGチェーン
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=retriever,
return_source_documents=True
)
result = qa_chain.invoke({"query": "ドキュメントには何が書いてありますか?"})
print(result["result"])
print(result["source_documents"])
エージェント
from langchain.agents import create_react_agent, AgentExecutor
from langchain.tools import Tool
from langchain import hub
# ツールを定義
def search_database(query: str) -> str:
return f"検索結果: {query}"
tools = [
Tool(
name="DatabaseSearch",
func=search_database,
description="データベースから情報を検索"
)
]
# エージェントを作成
prompt = hub.pull("hwchase17/react")
agent = create_react_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
result = agent_executor.invoke({"input": "ユーザーデータを検索して"})
完全なアプリケーション
from langchain_aws import ChatBedrock, BedrockEmbeddings
from langchain_community.vectorstores import FAISS
from langchain.chains import ConversationalRetrievalChain
from langchain.memory import ConversationBufferMemory
class RAGChatbot:
def __init__(self, documents: list):
self.llm = ChatBedrock(
model_id="anthropic.claude-3-sonnet-20240229-v1:0"
)
self.embeddings = BedrockEmbeddings(
model_id="amazon.titan-embed-text-v1"
)
self.vectorstore = FAISS.from_texts(documents, self.embeddings)
self.memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True
)
self.chain = ConversationalRetrievalChain.from_llm(
llm=self.llm,
retriever=self.vectorstore.as_retriever(),
memory=self.memory
)
def chat(self, question: str) -> str:
result = self.chain.invoke({"question": question})
return result["answer"]
# 使用例
docs = ["会社ポリシードキュメント...", "製品情報..."]
chatbot = RAGChatbot(docs)
print(chatbot.chat("会社のポリシーは何ですか?"))
print(chatbot.chat("それについてもっと教えて"))
ベストプラクティス
| プラクティス | 推奨事項 |
|---|---|
| モデル選択 | 会話にはChatBedrockを使用 |
| チャンキング | オーバーラップ付き500-1000トークン |
| メモリ | コンテキストニーズに応じて選択 |
| エラーハンドリング | try-exceptで呼び出しをラップ |
重要なポイント
- LangChainは簡素化 - Bedrock統合を抽象化
- チェーンで構成 - 複雑なワークフローを構築
- メモリでコンテキスト - マルチターン会話
- RAGは簡単 - ベクトルストア + リトリーバー
- エージェントで拡張 - カスタムツールを追加