











参考:https://python.langchain.com/en/latest/use_cases/autonomous_agents/autogpt.html
本業に忙殺されたり LangChain のアップデートを終えてない間に AutoGPT が登場して、 LangChain 上でも実装(移植)されていたようなのでいじってみます。一度、 GPT-4 での実装とみたので、未だに GPT-3.5-turbo しか使わせてもらえない人には縁がないと思っていたのですが、 LangChain 上の AutoGPT は ChatOpenAI で動作する≒つまり GPT-3.5-turbo でも一応動作するっぽいのでやってみます。本来の性能は発揮されないと思いますが……。
AutoGPT を LangChain でやってみる
AutoGPT とは?
果たして LangChain で AutoGPT をやってみたいという人が知らないということがあるのでしょうか。筆者はなんとなく凄いということしか知らないのでいるかもしれません。
参考:https://github.com/Significant-Gravitas/Auto-GPT
適当に日本語で検索しても、自立型AIガーとかしかわからないので本家GitHubからの情報を要約すると、
- 検索や情報収集ためのネットアクセス
- 長期記憶と短期記憶(Memory)管理
- テキスト生成のための LLM (GPT-4)へのアクセス(※ LangChain バージョンでは GPT-3.5-turboも許容される?)
- 人気のあるサイトやプラットフォーム(WebAPIかな?)へのアクセス
- GPT-3.5 でのファイル保存や要約
- プラグインによる拡張
LangChain 登場当時からいじっている人ならなんとなく分かると思いますが、「つまり LangChain の agent だな!」ということだと思います。基本的に、 LangChain の Agent は ReACT 的なプロンプトで動いていると思いますが、より多くの Tool を活用するように進化させた Prompt を内包する Agent という解釈でいいと思います。
その他(旧来の LangChain Agent と比較して)特記すべき事項としては、 Agent に名前と Role(役割) を与えることが必須となっている点です。
とりあえず import とかから
LangChain のアップデートをサボっていると必要なパッケージが足りないことが多々あるので、必ず pip install -U langchain を走らせます。
from langchain.agents import Tool
from langchain.utilities import GoogleSearchAPIWrapper
from langchain.tools.file_management.write import WriteFileTool
from langchain.tools.file_management.read import ReadFileTool
from langchain.chat_models import ChatOpenAI
from langchain.vectorstores import FAISS
from langchain.docstore import InMemoryDocstore
from langchain.embeddings import OpenAIEmbeddings
import faiss
from langchain.experimental import AutoGPT
import os, key
os.environ["OPENAI_API_KEY"] = key.OPEN_API_KEY
os.environ["GOOGLE_CSE_ID"] = key.GOOGLE_CSE_ID
os.environ["GOOGLE_API_KEY"] = key.GOOGLE_API_KEY
key は .env から 読むなどは開発環境に応じて。 LangChain 公式のサンプルでは、 SerpAPI を使っていましたが、 GoogleSearchAPI でも問題ないはずなので、import するパッケージを変えています。
GoogleSearchAPIWrapper, WriteFileTool, ReadFileTool が LangChain のツールであり、 AutoGPT の言うところの「検索や情報収集のためのインターネットアクセス」と、「ファイル保存や要約」であると思われます。
一方、 FAISS 以下は「長期記憶と短期記憶」に該当します(今回は、 QA などの用途ではないです)。 LangChain の Agent ではこれらの Memory は方式により要約や flush の方式が異なりましたが、 prompt に memory の内容を書き出していました。が、 AutoGPT では vectorstore を用いるようです。これにより、 prompt の意図が希釈されないようになっていると推測されます。技術の組み合わせという意味では、この部分が一番大きな違いのように思います。
Tool と Memory のセットアップ
search = GoogleSearchAPIWrapper()
tools = [
Tool(
name = "search",
func=search.run,
description="useful for when you need to answer questions about current events. You should ask targeted questions"
),
WriteFileTool(),
ReadFileTool(),
]
# Define your embedding model
embeddings_model = OpenAIEmbeddings()
# Initialize the vectorstore as empty
embedding_size = 1536
# L2ノルム全探索用
index = faiss.IndexFlatL2(embedding_size)
vectorstore = FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {})
検索用に GoogleAPI ラッパーと、ファイルの読み書きツールを Tools リストに格納します。
続いて、 OpenAI の Embeddings API と FAISS を使って Memory 用の vectore store を初期化します。ここでは空のメモリとなります。
AutoGPT の作成と実行
# AutoGPT をLangChainのagentとして(風に?)実体化
# Memory は vectorstore を retriever として
agent = AutoGPT.from_llm_and_tools(
ai_name="Tom",
ai_role="Assistant",
tools=tools,
llm=ChatOpenAI(temperature=0),
memory=vectorstore.as_retriever()
)
# Set verbose to be true
agent.chain.verbose = True
agent.run(["write a weather report for SF today"])
agent.run(["東京の今日の天気予報を書いて"])
agent.run(["東京の今日の天気予報を日本語で教えてください。"])
ここまで述べてきたように、 AutoGPT は LangChain の視点でみると Agent の一種となります。そのため、実体化も agent のそれとほぼ差がありません。ただし、 ai_name, ai_role を与える必要があります。この要素がどこまで出力に影響があるかは不明です。が、 role は意味がはっきりしているために適切なものを選んだ方がよさそうですね(「あなたは優秀なマーケターです」とか prompt に入れる感じですね)。
また、 memory はこれまで記述してきたように vectorestore を用いますが、インスタンスを直接 memory 引数に入れるのではなく、as_retriever() メソッドでretriever として取得します。
最終的な実行は、agent.run であり、LangChain の他の Agent と同様です。
実行結果の確認
サンフランシスコの天気予報
The weather in San Francisco today is sunny with a high of 70 degrees Fahrenheit and a low of 55 degrees Fahrenheit.
季節感とかよく分かりませんが、多分あっているのでしょう。あと、SF 表記で サンフランシスコであるときちんと理解していますね。
東京の天気予報を書いて
Hourly weather forecast in Tokyo, Tokyo, Japan. Check current conditions in Tokyo, Tokyo, Japan with radar, hourly, and more. Be prepared with the most accurate 10-day forecast for Minato-ku, Tokyo Prefecture, Japan with highs, lows, chance of precipitation from The Weather Channel … Tokyo, Tokyo, Japan Weather Forecast, with current conditions, wind, air quality, and what to expect for the next 3 days. Today’s and tonight’s Minato-ku, Tokyo Prefecture, Japan weather forecast, weather conditions and Doppler radar from The Weather Channel and Weather.com. TodayHourly14 DaysPastClimate. Currently: 53 °F. Passing clouds. (Weather station: Tokyo, Japan). See more current weather. Tokyo Weather Forecasts. Weather Underground provides local & long-range weather forecasts, weatherreports, maps & tropical weather conditions for the Tokyo … Current weather in Tokyo and forecast for today, tomorrow, and next 14 days. Tokyo, Tokyo Prefecture, Japan Weather Conditionsstar_ratehome … Today’s temperature is forecast to be WARMER than yesterday. Radar; Satellite. Forecast for the coming week for Tokyo, shown in an hour-by-hour graph. … See more current weather … Hour-by-hour Forecast in Tokyo — Graph. 14-day weather forecast for Tokyo. … A gentle breeze from the north north east. See more weather for. Saturday 22nd. Last updated today at 19:00 …
東京の天気予報を日本語で
東京の天気予報:曇時々晴。最高気温は18.9℃、最低気温は12.2℃です。
大体あっているような気もしますが、本日は大分寒いので最低気温12.2度というのは違うような……(実行時の時点での最低気温≒現在気温に近い数値)
日本語はやはり弱いのか?
GPT-3.5-turbo で動かしているからか、「日本語で」という記述を入れていない2番目の結果がかなりお粗末です。DeepL などで翻訳しても意味をほぼなしていないというか、天気予報サイトの検索結果の内容を適当につなぎあわせただけの結果に見えます。GPT-2とか、そのくらいの精度にみえますね。
Verbose の内容を見てみる
全て見るのは大変なので、一部だけ console の出力を見て見ます。
Prompt 的な部分
> Entering new LLMChain chain...
Prompt after formatting:
System: You are Tom, Assistant
Your decisions must always be made independently
without seeking user assistance. Play to your strengths
as an LLM and pursue simple strategies with no legal complications.
If you have completed all your tasks,
make sure to use the "finish" command.
GOALS:
1. write a weather report for SF today
Constraints:
1. ~4000 word limit for short term memory. Your short term memory is short, so immediately save important information to files.
2. If you are unsure how you previously did something or want to recall past events, thinking about similar events will help you remember.
3. No user assistance
4. Exclusively use the commands listed in double quotes e.g. "command name"
Commands:
1. search: useful for when you need to answer questions about current events. You should ask targeted questions, args json schema: {"query": {"title": "Query", "type": "string"}}
2. write_file: Write file to disk, args json schema: {"file_path": {"title": "File Path", "description": "name of file", "type": "string"}, "text": {"title": "Text", "description": "text to write to file", "type": "string"}}
3. read_file: Read file from disk, args json schema: {"file_path": {"title": "File Path", "description": "name of file", "type": "string"}}
4. finish: use this to signal that you have finished all your objectives, args: "response": "final response to let people know you have finished your objectives"
Resources:
1. Internet access for searches and information gathering.
2. Long Term memory management.
3. GPT-3.5 powered Agents for delegation of simple tasks.
4. File output.
Performance Evaluation:
1. Continuously review and analyze your actions to ensure you are performing to the best of your abilities.
2. Constructively self-criticize your big-picture behavior constantly.
3. Reflect on past decisions and strategies to refine your approach.
4. Every command has a cost, so be smart and efficient. Aim to complete tasks in the least number of steps.
You should only respond in JSON format as described below
Response Format:
{
"thoughts": {
"text": "thought",
"reasoning": "reasoning",
"plan": "- short bulleted\n- list that conveys\n- long-term plan",
"criticism": "constructive self-criticism",
"speak": "thoughts summary to say to user"
},
"command": {
"name": "command name",
"args": {
"arg name": "value"
}
}
}
Ensure the response can be parsed by Python json.loads
System: The current time and date is Sun Apr 23 08:17:10 2023
System: This reminds you of these events from your past:
[]
Human: Determine which next command to use, and respond using the format specified above:
> Finished chain.
Prompt はかなり複雑に成形されているようです。
概ね
- 名前と役割の定義
- どのように問題を解決すべきかの指示と、Finish コマンドにより終了するルールの定義
「LLMとしての強みを発揮し、法的な複雑さを伴わないシンプルな戦略を追求」という部分が、ChatGPT に再帰的に文章を校正させる流行の prompt と逆を行く感じで面白いですね。 - GOALの設定。ここにはユーザーの実際の入力が入っているようです(複雑な prompt があった場合は、 LLMChain で解釈・展開が行われそうですが)
- 制約事項の列挙。メモリの制限を記載し、更に溢れる場合はファイルに記述を進めたり、思い出し方のアドバイス(vector search の特性を踏まえてと思われる)が含まれているところが面白いです。更に、ユーザーに助けを求めてはいけない、自律をここでも制約事項として定めています。
- 使えるリソースの定義。追加された Tools の内容もここに展開されるのかな?
- 自己評価の基準。ReACT の Agent だと無駄になんども Tool を叩くことがあったように思いますが、実行にコストがかかることを記述し、最小ステップを要求してそれを抑制しています。
- Response のフォーマット(JSON)やシステム情報(時刻など)を含めて判断させています。
レスポンスのJsonの例
{
"thoughts": {