LangChainにてカスタムエージェントを作ってみた。
Function CallingとLangChainの組み合わせにより、Re-Actプロンプトの実現ができるが、LangChainの用意したツール(PythonREPLTool等)にて簡易に簡易に実現できるユースケースばかりではなく、要件に応じてアクションをカスタマイズしたいといったケースのサンプル。参考サイトのコピペですがAzure OpenAIのリソースで動作&日本語応答だけカスタマイズしています。
- Langchain Agentを使う場合に、実行機能を任意に作成したい場合に使う。
- langchainのBaseToolを継承したクラスとして定義。_runメソッドを実装することで、Agentのアクションで実行される。
Azure OpenAIのリソース定義
AOAIリソースのエンドポイントURL、APIキー、デプロイ名を設定する。(OS環境変数に設定したものを取得するようにするのが良い)
BASE_URL = ""
API_KEY = ""
DEPLOYMENT_NAME = ""
カスタムリソースの定義部
サンプル例では円の半径(r)から円周(2πr)を計算するためのツール(CircumferenceTool)を作成する。BaseToolを継承して作成する。
from langchain.tools import BaseTool
from math import pi
from typing import Union
class CircumferenceTool(BaseTool):
name = "Circumference calculator"
description = "use this tool when you need to calculate a circumference using the radius of a circle"
def _run(self, radius: Union[int, float]):
return float(radius)*2.0*pi
def _arun(self, radius: int):
raise NotImplementedError("This tool does not support async")
Azure OpenAIのChatModel定義
Langchain のLLM Chat modelを定義する。AOAIを使うため、AzureChatOpenAIモデルを使用。api_versionはFunctionCallingを使うのであれば2023-07-01-previewを使用。(ここらは利用機能と公式APIリファレンスの状況によって変えるところ) Chatの会話履歴を保持するためのMemoryも用意する。
from langchain.chat_models import AzureChatOpenAI
from langchain import LLMChain, PromptTemplate
from langchain.chains.conversation.memory import ConversationBufferWindowMemory
llm = AzureChatOpenAI(
openai_api_base=BASE_URL,
openai_api_version="2023-07-01-preview",
deployment_name=DEPLOYMENT_NAME,
openai_api_key=API_KEY,
openai_api_type="azure",
)
conversational_memory = ConversationBufferWindowMemory(
memory_key='chat_history',
k=5,
return_messages=True
)
カスタムツールを使用するエージェントの定義
Toolの定義にて先ほどのカスタムツールを設定。agentをイニシャライズして、LLM、toolを指定して完了。
from langchain.agents import initialize_agent
tools = [CircumferenceTool()]
# initialize agent with tools
agent = initialize_agent(
agent='chat-conversational-react-description',
tools=tools,
llm=llm,
verbose=True,
max_iterations=3,
early_stopping_method='generate',
memory=conversational_memory
)
実行
実際に実行してみる。
agent("半径5mの円周は?日本語で回答して。")
実行結果
実行結果としてLLMがToolを使用すると判断し、そのインプット(半径)を指定。Toolの実行結果を持って最終結果を算出し、回答文をLLMが作成する。
> Entering new AgentExecutor chain...
```json
{
"action": "Circumference calculator",
"action_input": "5"
}
```
Observation: 31.41592653589793
Thought:```json
{
"action": "Final Answer",
"action_input": "半径5mの円の円周は約31.42mです。"
}
```
> Finished chain.
{'input': '半径5mの円周は?日本語で回答して。',
'chat_history': [],
'output': '半径5mの円の円周は約31.42mです。'}
参考