LangChainでReAct Agentを構築する
Web検索Tool、計算Tool、ドキュメント検索Toolを備えた完全なReAct AgentをLangChainのAgentExecutorで組み立て、その推論手順を追跡します。
「LangChainでReAct Agentを構築する」はCoddyKit上の無料AI Engineering Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAI Engineering Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 AI Engineering Academyコースには全4レッスンが含まれています。
LangChainのエージェントエコシステム
LangChainは、エージェントを構築するための完全なスタックを提供します。ツールはエージェントにできることを定義し、プロンプトは指示と推論形式を与え、LLMが思考を行い、AgentExecutorがツール呼び出しを実行して観測結果をフィードバックするループを管理します。各要素を個別に設定できるため、すべてを書き直さずにコンポーネントを交換できます。
ReActエージェントの組み立て
LangChainでReActエージェントを構築する最も簡単な方法は、create_react_agentを使うことです。LLM、ツールのリスト、プロンプトテンプレートを渡すと、Thought/Action/Observationのステップを自動的に生成する実行可能オブジェクトが返されます。これをAgentExecutorでラップしてループを管理します。
from langchain import hub
from langchain.agents import create_react_agent, AgentExecutor
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
# 1. Define tools
@tool
def search(query: str) -> str:
'''Search the web for current information. Input: a search query string.'''
return f'Search results for "{query}": [mock result]'
@tool
def calculator(expression: str) -> str:
'''Evaluate a math expression. Input: a valid Python math expression.'''
try:
return str(eval(expression))
except Exception as e:
return str(e)
tools = [search, calculator]
# 2. Load a ReAct prompt template
prompt = hub.pull('hwchase17/react')
# 3. Create the agent
llm = ChatOpenAI(model='gpt-4o', temperature=0)
agent = create_react_agent(llm, tools, prompt)AgentExecutorでの実行
AgentExecutorはThought/Action/Observationのループを管理します。開発中にverbose=Trueを渡すと、すべてのステップがコンソールに出力されます。このトレースはデバッグに非常に役立ちます。max_iterationsパラメーターは、無限ループを防ぐための安全弁です。
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
verbose=True, # Print each step
max_iterations=10, # Safety limit
handle_parsing_errors=True # Don't crash on format errors
)
# Invoke with a user question
result = agent_executor.invoke({
'input': 'What is the square root of 144 multiplied by the number of days in a leap year?'
})
print('Final answer:', result['output'])詳細トレースの読み方
詳細トレースには、エージェントがどのように推論したかが正確に表示されます。各反復では、モデルのThought、選択したAction、ツールからのObservationが出力されます。これにより、間違ったツールを選んだのか、間違った引数を渡したのか、観測結果を誤って解釈したのかなど、エージェントがどこで失敗したかを正確に確認できます。
# Example verbose output from AgentExecutor:
#
# > Entering new AgentExecutor chain...
# Thought: I need to find the square root of 144 first, then multiply by days in a leap year.
# Action: calculator
# Action Input: 144 ** 0.5
# Observation: 12.0
# Thought: 12.0 times 366 days in a leap year.
# Action: calculator
# Action Input: 12.0 * 366
# Observation: 4392.0
# Thought: I have the final answer.
# Final Answer: 4392.0
# > Finished chain.組み込みLangChainツールの使用
LangChainには、一般的なタスク向けのすぐに使えるツールが多数用意されています。コードを書かなくても、langchain_community.toolsからWeb検索ツールを追加できます。これらのツールが、API認証とレスポンスの解析を代わりに処理してくれます。
from langchain_community.tools import DuckDuckGoSearchRun
from langchain_community.tools import WikipediaQueryRun
from langchain_community.utilities import WikipediaAPIWrapper
# Web search tool
search_tool = DuckDuckGoSearchRun()
# Wikipedia lookup tool
wiki_tool = WikipediaQueryRun(
api_wrapper=WikipediaAPIWrapper(top_k_results=2)
)
# Add to your agent
tools_with_search = [search_tool, wiki_tool, calculator]
agent_executor.tools = tools_with_searchRAGツールとしてのドキュメント検索
最も強力なパターンの1つは、RAGパイプラインをエージェントツールとして公開することです。エージェントは、ナレッジベースから検索するか、他のツールを使うか、学習済みの知識に頼るかを判断します。これによりRAGシステムが動的になり、関連する場合にだけエージェントが呼び出します。
from langchain_core.tools import tool
@tool
def lookup_knowledge_base(query: str) -> str:
'''Search the company knowledge base for internal policies, procedures, and documentation.
Use when the user asks about company-specific information not available publicly.
Input: a natural language question or keyword query.
'''
# Your RAG pipeline here
retrieved_chunks = vector_store.similarity_search(query, k=3)
context = '\n'.join([doc.page_content for doc in retrieved_chunks])
return context if context else 'No relevant documents found.'エージェント出力のストリーミング
ユーザー体験を向上させるため、完全なレスポンスを待つのではなく、エージェントの最終回答をトークン単位でストリーミングします。agent_executor.astream_eventsを使うと、中間ステップや最終出力のストリームなど、発生したイベントを受け取れます。
import asyncio
async def stream_agent(user_input: str):
async for event in agent_executor.astream_events(
{'input': user_input},
version='v1'
):
kind = event['event']
if kind == 'on_chat_model_stream':
chunk = event['data']['chunk']
if chunk.content:
print(chunk.content, end='', flush=True)
elif kind == 'on_tool_start':
print(f'\n[Calling tool: {event["name"]}]')
elif kind == 'on_tool_end':
print(f'[Tool result: {str(event["data"]["output"])[:100]}]')
asyncio.run(stream_agent('What is the latest news about AI?'))エージェントへのメモリの受け渡し
エージェントの推論と会話メモリを組み合わせることで、エージェントに過去のやり取りを記憶させられます。RunnableWithMessageHistoryでエージェントエグゼキューターをラップし、チャット履歴のストアを提供してください。これによりエージェントは、過去のターンの記憶とツールを呼び出す能力の両方を持てます。
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_community.chat_message_histories import ChatMessageHistory
session_store = {}
def get_session_history(session_id: str):
if session_id not in session_store:
session_store[session_id] = ChatMessageHistory()
return session_store[session_id]
agent_with_memory = RunnableWithMessageHistory(
agent_executor,
get_session_history,
input_messages_key='input',
history_messages_key='chat_history'
)ReActプロンプトのカスタマイズ
デフォルトのHubプロンプトは適切に機能しますが、特定のドメイン向けにカスタムシステムプロンプトが必要になることもよくあります。カスタムプロンプトを使うと、ツールの説明の前に、ペルソナの指示、出力形式のルール、ドメイン固有のガイダンスを追加できます。必要なReActプレースホルダーを含むChatPromptTemplateを使用してください。
from langchain_core.prompts import ChatPromptTemplate
custom_prompt = ChatPromptTemplate.from_messages([
('system', '''You are a helpful customer support agent for TechCorp.
Always be polite and professional. When you do not know something, use your tools.
You have access to these tools:
{tools}
Tool names: {tool_names}
Use this format:
Thought: ...
Action: tool_name
Action Input: input_value
Observation: result
Final Answer: your response to the customer
'''),
('human', '{input}'),
('assistant', '{agent_scratchpad}')
])
agent = create_react_agent(llm, tools, custom_prompt)エージェントの推論ステップの確認
return_intermediate_steps=Trueを設定すると、AgentExecutorは最終出力とともに中間ステップを返します。各ステップは、エージェントのアクションとツールの観測結果からなるタプルです。これは、エージェントの推論プロセスをユーザーに表示するUIの構築に役立ちます。
agent_executor = AgentExecutor(
agent=agent,
tools=tools,
return_intermediate_steps=True
)
result = agent_executor.invoke({'input': 'What is 2 to the power of 10?'})
print('Final answer:', result['output'])
print('Reasoning steps:')
for step in result['intermediate_steps']:
action, observation = step
print(f' Tool: {action.tool}, Input: {action.tool_input}')
print(f' Observation: {observation}')エージェントの徹底的なテスト
代表的な質問からなるテストスイートでエージェントをテストしてください。対象には、単一ツールのタスク、複数回のツール呼び出しが必要なマルチホップタスク、ツールが不要でモデルが学習データから回答するタスク、そしてツール選択を混乱させるように設計された質問などの敵対的な入力を含めます。合格率と失敗パターンを追跡し、ツールの説明とプロンプトを改善してください。
クイックチェック
LangChainでReActエージェントを構築する方法についての理解度を確認しましょう。
レッスンのまとめ
このレッスンでは、create_react_agentによってLLM、ツール、プロンプトをReActエージェントに組み立てられること、AgentExecutorが設定可能な安全上限付きでThought/Action/Observationのループを管理すること、そしてverbose=Trueとreturn_intermediate_steps=Trueによってエージェントの推論を完全に確認できることを学びました。次は、エージェントの失敗を処理し、無限ループを防ぐ方法を学びます。
よくある質問
「LangChainでReAct Agentを構築する」レッスンは無料ですか?
はい。「LangChainでReAct Agentを構築する」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、AI Engineering Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 AI Engineering Academyコースには全4レッスンが含まれています。
「LangChainでReAct Agentを構築する」で何を学びますか?
Web検索Tool、計算Tool、ドキュメント検索Toolを備えた完全なReAct AgentをLangChainのAgentExecutorで組み立て、その推論手順を追跡します。 ブラウザで直接実行するハンズオンコードでAI Engineering Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
AI Engineering Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのAI Engineering Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「LangChainでReAct Agentを構築する」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このAI Engineering Academyレッスンでコードを書いて実行できますか?
はい。すべてのAI Engineering Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- ReActフレームワーク:Think、Act、Observe
- Agent用Toolの定義
- LangChainでReAct Agentを構築する
- エージェントの失敗とループへの対処