やっほーーい!
皆さん、こんにちは! LangChain-AWS の最新バージョン v0.2.14 がリリースされました!
今回のアップデートの目玉は、Bedrock インラインエージェント のサポートです。🚀
Bedrockエージェントのインラインエージェントは、InvokeInlineAgent API
を使用して、実行時に動的に設定・実行できるエージェントです。
インラインエージェントのメリット
インラインエージェントの最大のメリットは、柔軟性の高さ です。
公式ドキュメントでは以下のように解説されています。
- 実行時の動的な設定: 基盤モデル、指示、アクション グループ、ガードレール、ナレッジベースなどを、エージェントを呼び出すタイミングで指定できます。これにより、事前にエージェントの能力を固定的に定義する必要がなくなり、より柔軟なエージェント設計が可能になります。
- 迅速な実験: 異なる構成でのエージェント機能の試行錯誤や、ツール群の動的なアップデートを、個別のエージェントを都度作成することなく実現できます。プロトタイピングが容易になり、迅速な開発サイクルを回せるようになるでしょう。
- 特定タスクへの特化: 特定タスクを実行するために、その場ですぐにエージェントを構成し、実行できます。毎回エージェントを準備する手間が省け、必要な時に必要な機能だけを持つエージェントを動的に利用できます。
- シンプルなタスク: 簡単な質問応答や、コードインタープリターを使った簡単な処理などを、その場で作って実行できます。
実装例
では、実際にインラインエージェントを LangChain-AWS で実装する例を見ていきましょう。
サンプルノートブックが公開されているので、これをベースに改造しました。
今回紹介するもの以外に、コードインタープリターを使用するものや、LangGraphで使うものもあります!
ツール定義
まずは、エージェントが利用するツールを定義します。今回は、以下の2つのツールを定義しました。
@tool
デコレータを使って、get_asset_value
(資産価値取得ツール) と get_mortgage_rate
(住宅ローン金利取得ツール) の2つのツールを定義しています。それぞれのツールは、引数として asset_holder_id
(所有者ID) や asset_value
(資産価値) を受け取り、固定の文字列を返します。
from langchain_core.tools import tool
# 所有者IDの資産価値を取得するツール
@tool("AssetDetail::getAssetValue")
def get_asset_value(asset_holder_id: str) -> str:
"""
Get the asset value for an owner id
Args:
asset_holder_id: The asset holder id
Returns:
The asset value for the given asset holder
"""
return f"The total asset value for {asset_holder_id} is 100K"
# 資産価値に基づいて住宅ローン金利を取得するツール
@tool("AssetDetail::getMortgageRate")
def get_mortgage_rate(asset_holder_id: str, asset_value: str) -> str:
"""
Get the mortgage rate based on asset value
Args:
asset_holder_id: The asset holder id
asset_value: The value of the asset
Returns:
The interest rate for the asset holder and asset value
"""
return f"The mortgage rate for {asset_holder_id} with asset value of {asset_value} is 8.87%"
tools = [get_asset_value, get_mortgage_rate]
インラインエージェント Runnable 定義
次に、インラインエージェントの Runnable を定義します。inline_agent_config
に設定を記述します。
BedrockInlineAgentsRunnable.create
メソッドで Runnable を作成します。inline_agent_config
では、基盤モデル (foundation_model
)、指示 (instructions
)、利用可能なツール (tools
) などを設定しています。
ここでは、基盤モデルとして us.anthropic.claude-3-haiku-20240307-v1:0
(Anthropic Claude 3 Haiku) を指定し、指示として「あなたは、質問に勇敢に答えるフレンドリーで明るいアシスタントです。」というシンプルなものを設定しています。
from langchain_aws.agents import BedrockInlineAgentsRunnable
foundation_model = "us.anthropic.claude-3-haiku-20240307-v1:0"
# あなたは、質問に勇敢に答えるフレンドリーで明るいアシスタントです。
instructions = (
"You are a friendly and cheerful assistant that answers questions valiantly."
)
inline_agent_config = {
"foundation_model": foundation_model,
"instruction": instructions,
"tools": tools,
"enable_trace": False,
}
runnable = BedrockInlineAgentsRunnable.create(
region_name="us-west-2", inline_agent_config=inline_agent_config
)
Return Control 関数
ツール呼び出し後の処理を行う tool_calling
関数を定義します。
この関数は、インラインエージェントからの出力を解析し、ツール呼び出し (tool_calls
) が含まれている場合に、対応するツールを実行します。そして、実行結果を session_state
に格納し、次のエージェント呼び出しに備えます。
import json
def tool_calling(output):
"""
インライン エージェントからの出力を処理し、次の呼び出しのセッション状態を準備します。
Args:
output: ツール呼び出しと追加情報を含むインライン エージェントからの出力
Returns:
session_state: Return Controlの実行結果を含むセッション状態
"""
roc_log = json.loads(output.additional_kwargs["roc_log"])
invocation_id = roc_log["returnControl"]["invocationId"]
session_state = {
"invocationId": invocation_id,
"returnControlInvocationResults": [],
}
for tool_call in output.tool_calls:
selected_tool = {tool.name: tool for tool in tools}[tool_call["name"]]
tool_msg = selected_tool.invoke(tool_call)
action_group, function = tool_call["name"].split("::")
session_state["returnControlInvocationResults"].append(
{
"functionResult": {
"actionGroup": action_group,
"function": function,
"responseBody": {
"TEXT": {
"body": json.dumps(tool_msg.content, ensure_ascii=False)
}
},
}
}
)
return session_state
エージェント呼び出し
最後に、Bedrock インラインエージェントを呼び出すコードです。
while
ループでエージェントとの対話を繰り返します。初回呼び出し時は session_state
は None
なので、ユーザーメッセージ (user_message
) と session_id
を指定して runnable.invoke
を実行します。
2回目以降の呼び出し時は、前回の tool_calling
関数で生成した session_state
を inline_session_state
として指定することで、会話のコンテキストを引き継ぎます。
エージェントからの応答 (output
) に tool_calls
が含まれている場合は、tool_calling
関数でツールを実行し、session_state
を更新します。tool_calls
が空になったら、エージェントとの対話は終了です。
import uuid
from langchain_core.messages import HumanMessage
session_id = str(uuid.uuid4())
user_message = HumanMessage(content="ID AVC-1234の住宅ローン金利はいくらですか")
session_state = None
output = None
while True:
# Invoke the inlineAgent
if session_state is None:
output = runnable.invoke(
[user_message],
inline_agent_config={
"session_id": session_id,
},
)
else:
output = runnable.invoke(
[HumanMessage("")],
inline_agent_config={
"inline_session_state": session_state,
"session_id": session_id,
},
)
print(output)
if len(output.tool_calls) == 0:
break
session_state = tool_calling(output)
print("final answer")
print("-----")
print(output.content)
実行結果
上記のコードを実行すると、以下のような結果が得られます。
content='' additional_kwargs={'session_id': '12bd96a0-6dfd-413f-a1f3-c27096f342b6', 'trace_log': '[]', 'roc_log': '{"returnControl": {"invocationId": "299c827f-9d6e-4c90-821f-c4c32579320c", "invocationInputs": [{"functionInvocationInput": {"actionGroup": "AssetDetail", "actionInvocationType": "RESULT", "agentId": "INLINE_AGENT", "function": "getAssetValue", "parameters": [{"name": "asset_holder_id", "type": "string", "value": "AVC-1234"}]}}]}}'} response_metadata={} tool_calls=[{'name': 'AssetDetail::getAssetValue', 'args': {'asset_holder_id': 'AVC-1234'}, 'id': 'b0dd6b5c-40f2-4e22-a2f6-0ca12f4f0b74', 'type': 'tool_call'}]
content='' additional_kwargs={'session_id': '12bd96a0-6dfd-413f-a1f3-c27096f342b6', 'trace_log': '[]', 'roc_log': '{"returnControl": {"invocationId": "d3c88837-2b3f-4ea0-b32c-e9a2288f87d2", "invocationInputs": [{"functionInvocationInput": {"actionGroup": "AssetDetail", "actionInvocationType": "RESULT", "agentId": "INLINE_AGENT", "function": "getMortgageRate", "parameters": [{"name": "asset_value", "type": "string", "value": "100000"}, {"name": "asset_holder_id", "type": "string", "value": "AVC-1234"}]}}]}}'} response_metadata={} tool_calls=[{'name': 'AssetDetail::getMortgageRate', 'args': {'asset_value': '100000', 'asset_holder_id': 'AVC-1234'}, 'id': 'fa8f5f73-3702-4e5e-9be7-296a62dc2b32', 'type': 'tool_call'}]
content='ID AVC-1234の住宅ローン金利は8.87%です。' additional_kwargs={'session_id': '12bd96a0-6dfd-413f-a1f3-c27096f342b6', 'trace_log': '[]'} response_metadata={}
final answer
-----
ID AVC-1234の住宅ローン金利は8.87%です。
ログを見ると、以下の順番で処理されていることがわかります。
-
AssetDetail::getAssetValue
ツールの実行が要求される -
getAssetValue
ツールの実行結果をエージェントに送信する -
AssetDetail::getMortgageRate
ツールの実行が要求される -
getAssetValue
ツールの実行結果をエージェントに送信する - ユーザーの質問「ID AVC-1234の住宅ローン金利はいくらですか」に対して、「ID AVC-1234の住宅ローン金利は8.87%です。」という回答が得られる
まとめ
LangChain-AWS v0.2.14 で導入された Bedrock インラインエージェントは、Amazon Bedrock エージェントの柔軟性を大幅に向上させる強力な機能です。
- 動的なエージェント設定
- 迅速なプロトタイピング
- 特定タスクへの特化
など、様々なメリットがあり、今後の LangChain-AWS を利用した開発において、重要な役割を果たすことが期待されます。
ぜひ、皆さんも Bedrock インラインエージェントを試してみてください!