🔖
【LangChain】エージェントをざっくり理解する
前回の記事が少し長くなったので、分割しました。
エージェントのタイプ
前回、Tavilyで検索して回答を返すだけの(いわゆる下請け丸投げ)電通エージェントを作成しました。
from langchain import hub
from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_openai import ChatOpenAI
# ① tools、prompt、llmを定義
tools = [TavilySearchResults(max_results=1)]
prompt = hub.pull("hwchase17/openai-tools-agent")
llm = ChatOpenAI(model="gpt-3.5-turbo-1106", temperature=0)
# ② agentを作成
agent = create_openai_tools_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
# ③ 実行
agent_executor.invoke({"input": "what is LangChain?"})
hubというのが、適切な二次下請けを探して、その下請けに丸投げする電通社員なのですが、当然ながら丸投げして回答をそのまま依頼主に返す社員だけでなく、適切な形(XMLやJSON)に加工する社員を選ぶこともできます。
- openai-functions-agent
- openai-tools-agent
- xml-agent-convo
- react-chat-json
- structured-chat-agent
それぞれのエージェントが何をしているのかは公式ドキュメントを参照。
エージェントを通じて会話する
公式のQuickstartをもとに作成しています。
チャットをするために特別難しいことをする必要はなく、実行時にinputに加えてchat_historyを与えれば会話できます。
(ただし、これはhubにopenai-functions-agentなど会話できるエージェントを指定した時だけです。とはいえ、上記に挙げたエージェントは全て会話機能を備えていますので、普通のエージェントは会話できると考えてOKと思います)
from langchain import hub
from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage,AIMessage
# ① tools、prompt、llmを定義
tools = [TavilySearchResults(max_results=1)]
prompt = hub.pull("hwchase17/openai-functions-agent")
llm = ChatOpenAI(model="gpt-3.5-turbo-1106", temperature=0)
# ② agentを作成
agent = create_openai_tools_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
会話履歴を与えず実行
agent_executor.invoke({"input": "初めまして。私の名前はボブです", "chat_history": []})
#->
> Entering new AgentExecutor chain...
初めまして、ボブさん!お会いできて嬉しいです。何かお手伝いできることはありますか?
> Finished chain.
会話履歴を与えて実行
agent_executor.invoke(
{
"chat_history": [
HumanMessage(content="初めまして。私の名前はボブです"),
AIMessage(content="初めまして、ボブさん!お会いできて嬉しいです。何かお手伝いできることはありますか?"),
],
"input": "私の名前は何ですか?",
}
)
#->
> Entering new AgentExecutor chain...
あなたの名前はボブです。
> Finished chain.
toolsにTavilyを入れていますが、今回の会話においてネット検索をする必要はありません。
しかし、toolsを空配列にしたり、agent作成時に何も渡さないとエラーがでます。
まるで技術的なことは下請けに依頼しないと自分では何もできない大企業の社員みたいですね。
実際のアプリ開発では特定のユーザーとの会話履歴を追うために、RunnableWithMessageHistoryを使って実装する必要がありそうです。
RunnableWithMessageHistoryについてはまた使う場面で理解しようと思います。
Discussion