Microsoft Research などが開発をしているマルチエージェントフレームワークである AutoGen v0.4 を使ってマルチエージェントの実装を理解するシリーズの第三弾です。
AutoGen v0.4 では Microsoft Research が別途公開している汎用マルチエージェントシステムである Magentic-One を AgentChat として取り込んでいます。Magentic-One のオーケストレーターエージェントは、実行計画を作成し、他のエージェントにタスクを委任し、目標に向けた進捗状況を追跡して、必要に応じて計画を動的に修正します。
Architecture
Magentic-One は Inner Loop と Outer Loop の二重のループ構造を持ちます。オーケストレーターとしてMagenticOneOrchestrator
が定義されており、タスクの進捗状況を追跡し、次に発言すべきエージェントを選択するために、台帳(LLM によって生成された JSON として実装)を使用します。
一 個 一 個 見 て い き ま し ょ う ^^
1. Outer Loop(外側のループ):
タスクの初期計画を作成し、進行状況を管理する役割を持ちます。タスク台帳 (Task Ledger) を維持し、与えられた情報、検証済みの事実、未調査の事実、推測情報を格納します。
さらに各エージェントの役割を考慮しながら、タスクを分解し、作業計画を立案します。計画が更新されるたびに、すべてのエージェントの状態をリセットします。
1.1 Task Ledger (FACTs)
Task Ledger(タスク台帳)では 4 点の事実(FACTs)、(※正確には 3 点の事実と 1 点の推測)と 1 点の 実行計画(PLAN)を管理します。タスクを受け取ると、オーケストレーターは要求を反映し、タスク台帳に重要な情報を事前に入力します。
ORCHESTRATOR_TASK_LEDGER_FACTS_PROMPT
1. 与えられた事実または確認済みの事実:
依頼文自体に記載されている具体的な事実や数値をすべて挙げてください。該当するものがない場合もあります。
2. 調査すべき事実:
調査が必要な可能性のある事実をすべて挙げてください。また、それらの事実がどこに記載されているかを具体的に示してください。場合によっては、信頼できる情報源が依頼文自体に記載されていることもあります。
3. 導出すべき事実:
導出が必要な可能性のある事実をすべて挙げてください(例:論理的推論、シミュレーション、計算など)。
4. 経験則に基づく推測:
記憶、直感、根拠のある推測などから思い出す事実をすべて列挙してください。
(抜粋,訳)
1.2. Task Ledger (PLAN)
ORCHESTRATOR_TASK_LEDGER_PLAN_PROMPT
素晴らしい。このリクエストに対応するため、以下のチームを編成しました。
{team}
チームの構成や既知の事実、未知の事実に基づいて、当初の依頼に対応するための短い箇条書きの計画を立ててください。
チームメンバー全員が関与する必要はないことを覚えておいてください。
この作業には、チームメンバーの特定の専門知識が必要ない場合もあります。
(抜粋,訳)
例:
Question: 1週間のドバイ海外旅行で、おすすめの観光地とホテルを教えてください。
travel_agent = AssistantAgent(
"travel_agent",
description="あなたは総合トラベルエージェントです",
model_client=client,
#tools=[search_website],
reflect_on_tool_use=True,
system_message="""あなたは優秀な総合トラベルエージェントです。
地方のトラベルエージェントが回答した情報をもとに、最終的な回答を作成します。
最終回答が完成したら調査結果を要約し、文の最後に TERMINATE を含めること!
""",
)
surfer = MultimodalWebSurfer(
"WebSurfer",
model_client=client,
to_save_screenshots=True,
browser_data_dir="./browser_data",
debug_dir="./debug",
downloads_folder="./downloads",
)
with tracer.start_as_current_span("magenticone") as rollspan:
team = MagenticOneGroupChat([travel_agent, surfer], model_client=client, termination_condition=combined_termination, max_turns=10)
await Console(team.run_stream(task="""
1週間のドバイ海外旅行で、おすすめの観光地とホテルを教えてください。
API_KEYが必要になるようなAPIは呼ばないでください。
"""
))
1.3. 事実と推測を台帳に記載 [1: GPT-4o コールNo.]
FACTs
1. 与えられた、あるいは検証された事実:
- ドバイに1週間旅行する際のおすすめスポットを教えてほしい。
- お勧めの観光スポットやホテルが含まれていなければならない。
- APIキーはリクエストを満たすために使用されたり要求されたりしてはならない。
2. 調べるべき事実:
- ドバイの現在の人気観光スポット
- ドバイの現在のベストまたは高評価のホテル。
3. 導き出される事実:
- トップアトラクションに基づく、ドバイに1週間滞在するための最適な旅程。
- 多様な興味(例:文化、モダン、レクリエーション)をカバーするために、観光スポットをバランスよく選択すること。
4. 推測:
- ブルジュ・ハリファ、ドバイ・モール、パーム・ジュメイラ、ドバイ・マリーナなどのよく知られた観光スポットがリストに入るかもしれない。
- バージュ・アル・アラブ・ジュメイラ、アトランティス・ザ・パーム、ジュメイラ・ビーチ・ホテルなどの有名ホテルもお勧めできるだろう。
1.4. 実行計画を台帳に記載 [2]
タスク台帳に事実と推測が入力された後でのみ、オーケストレーターは指揮するチームの構成を考慮します。具体的には、各エージェントの説明と現在のタスク台帳を使用して、段階的な計画を考案します。計画は自然言語で表現され、一連の手順と個々のエージェントへのそれらの手順の割り当てで構成されます。
PLAN
以下は、その要望に応えるための計画である:
1. 情報収集:
- 個人的な知識とリソースを使って、ドバイの人気観光スポットをリストアップする。
- 個人的な知識を使って、ドバイのおすすめホテルをリストアップする。
2. 推奨事項の検証と詳細化:
- WebSurferにドバイの現在の人気観光スポットを検索してもらい、最初のリストを検証し、拡張する。
- WebSurferにドバイの人気ホテルを検索してもらい、最初のリストを検証し、拡張する。
3. 推奨事項のまとめ:
- WebSurferから収集した情報と個人的な知識を組み合わせて、1週間の旅行に最適な観光名所とホテルの包括的かつバランスのとれたリストを作成する。
4. 推奨事項の提示:
- アトラクションのための提案された旅程と、簡単な説明と場合によっては星評価やユニークな特徴を持つホテルのリストを含む、最終的な推奨事項をユーザーに提供する。
### 例の箇条書き
1. アトラクションの推奨:
- ブルジュ・ハリファ
- ドバイ・モール
- パーム・ジュメイラ
- ドバイ・マリーナ
- ドバイ・ファウンテン
- デザート・サファリ
- ドバイ博物館
- ジュメイラ・モスク
2. ホテルの推奨:
- ブルジュ・アル・アラブ・ジュメイラ
- アトランティス・ザ・パーム
- ジュメイラ・ビーチ・ホテル
- ザ・アドレス・ダウンタウン・ドバイ
- アルマーニ・ホテル・ドバイ
3. 詳細な旅程とホテルの説明:
- さまざまなアトラクションをカバーする日ごとの推奨旅程
- 推奨ホテルの各詳細と特徴
WebSurferで最初のステップを実行し、アトラクションとホテルのリストを検証し、拡張することで、計画を実行します。
これでタスク台帳が埋まりましたね。
参考 状態管理(MagenticOneOrchestrator)
オーケストレーターの状態管理についてのデータの持ち方を見ておきましょう。message_thread
とは別にタスク台帳の項目 facts
, plan
を保持します。
与えたタスクは内部理解のためにシンプル化しているので、以下の 2 点を収集することが今回の目標となります。
- ドバイの人気観光スポットをリストアップ
- ドバイのおすすめホテルをリストアップ
2. Inner Loop(内側のループ)
タスク進行中に、エージェントの動作を調整し、失敗時の対応を決定します。進捗台帳 (Progress Ledger) を維持し、作業の進行状況、繰り返し発生している問題、どのエージェントが次に動作するかを記録します。
以下の 5 つの質問に基づいて、次のアクションを決定します:
1. タスクは完了したか?
2. 無駄なループが発生していないか?
3. 進捗はあるか?
4. 次にどのエージェントが動くべきか?
5. 次のエージェントにはどんな指示を出すべきか?
ちなみに制限回数以上のループや停滞が発生すると、Outer Loop に戻り、計画を再評価します。また、MagenticOneOrchestrator
のデフォルト実装では async/await による非同期設計になっているものの、実行フロー自体は「オーケストレーターが呼び出して結果を待つ→次へ進む」という形で、論理的には逐次的(同期的)に振る舞います。
Azure OpenAI Call トレースタイムライン
2.1. Progress Ledger(進捗台帳)
ORCHESTRATOR_PROGRESS_LEDGER_PROMPT
私たちは次のリクエストに取り組んでいることを思い出してください:
{task}
そして、次のチームを編成しました:
{team}
リクエストの進捗状況を確認するために、以下の質問に回答してください。必要な理由も含めてください。
リクエストは完全に満たされていますか?(完了している場合は「True」、元のリクエストがまだ「SUCCESSFULLY and FULLY」に対処されていない場合は「False」)
同じリクエストを繰り返したり、以前と同じ応答を受け取ったりするループにはまっていませんか? ループは複数回にわたることもあり、何度もスクロールアップやスクロールダウンを繰り返すことも含まれます。
前進しているか?(開始したばかりの場合、または最近のメッセージに価値が加わっている場合は「はい」。最近のメッセージにループに陥っている兆候が見られる場合、または成功を妨げる重大な障害がある証拠がある場合は「いいえ」)
次に誰が話すか?({names}から選択)
このチームメンバーにどのような指示や質問をするか?(そのメンバーに直接話しかけるような表現で、必要な具体的な情報を含める)
以下のスキーマに従って、純粋なJSON形式で回答を出力してください。JSONオブジェクトはそのまま解析可能な状態でなければなりません。JSON以外のものを出力したり、このスキーマから逸脱したりしないでください。
(抜粋,訳)
2.2. 進捗台帳作成 [3]
Progress Ledger(進捗台帳)の実体(JSON)
{
"is_request_satisfied": {
"reason": "ドバイの1週間の旅行における観光名所とホテルの推薦がまだ完全には収集・提示されていないため。",
"answer": false
},
"is_in_loop": {
"reason": "これまでに同じ処理やリクエストの繰り返しは発生しておらず、まだ情報収集の初期段階にあるため。",
"answer": false
},
"is_progress_being_made": {
"reason": "明確な計画を立て、ユーザーのリクエストを満たすために必要な情報を収集し始めているため。",
"answer": true
},
"next_speaker": {
"reason": "次のステップとして、初期リストの観光名所とホテルの情報を確認し、拡充する必要があるため。",
"answer": "WebSurfer"
},
"instruction_or_question": {
"reason": "ドバイの主要な観光名所と高評価のホテルに関する最新かつ正確な情報を収集するため。",
"answer": "現在のドバイの主要な観光名所を検索し、また高評価のホテルについても検索してください。それぞれのカテゴリの結果を要約してください。"
}
}
進捗台帳は非常に重要なコンポーネントなので、詳しく見ていきましょう。
is_request_satisfied | is_in_loop | is_progress_being_made | next_speaker | instruction_or_question | |
---|---|---|---|---|---|
解説 | タスクは完了したか? | 無駄なループが発生していないか? | 進捗はあるか? | 次にどのエージェントが動くべきか? | 次のエージェントにはどんな指示を出すべきか? |
answer | False | False | True | WebSurfer | 現在のドバイの主要な観光名所を検索し、また高評価のホテルについても検索してください。それぞれのカテゴリの結果を要約してください。 |
reason | ドバイの1週間の旅行における観光名所とホテルの推薦がまだ完全には収集・提示されていないため。 | これまでに同じ処理やリクエストの繰り返しは発生しておらず、まだ情報収集の初期段階にあるため。 | 明確な計画を立て、ユーザーのリクエストを満たすために必要な情報を収集し始めているため。 | 次のステップとして、初期リストの観光名所とホテルの情報を確認し、拡充する必要があるため。 | ドバイの主要な観光名所と高評価のホテルに関する最新かつ正確な情報を収集するため。 |
進捗台帳のチェックは各エージェントの発話ごとに実行され、現在のタスクの進捗を更新します。進捗台帳では 5 項目について進捗しているかの判定(answer
)およびその理由(reason
)を記載します。
PLAN の策定直後の 1 回目の進捗チェックですので、is_request_satisfied
や is_in_loop
は False
となっていますね。今後の PLAN が決まりましたので、is_progress_being_made
は True
となり、停滞判定の内部カウント self._stall_counter
は増加しません。
進捗台帳では次に遷移するエージェントも決定します。与えられたコンテキストから next_speaker
にWebSurfer
を呼ぶようにと判定されました。その際に与えるべき指示の内容も同時に記載されます。
進捗台帳はこのようにして議論がちゃんと進んでいるか、タスクが完了したか、次に呼ぶのは誰かを毎ターンチェックしているのです。
3. 組み込みエージェント
Magentic-One にあらかじめ組み込まれたエージェントは、さまざまなオープンエンドの問題を解決するために必要なツールと機能をオーケストレーターに提供するほか、動的かつ常に変化する Web およびファイル システム環境に自律的に適応して動作する機能も提供しています。コーディング、実行、エラー修正の Self-Reflection 実行も可能になります。
今回は情報収集のために、WebSurfer
(MultimodalWebSurfer
) をオーケストレーターに追加しました。
WebSurfer
は LLM ベースのエージェントで、Chromium ベースのウェブブラウザの操作と管理に精通しています。リクエストが届くたびに、WebSurfer はブラウザ上でアクションを実行し、ウェブページの新しい状態を報告します。
WebSurferのアクションスペースには、ナビゲーション(URLの訪問、ウェブ検索など)、ウェブページアクション(クリックやタイピングなど)、読み取りアクション(要約や質問への回答など)が含まれます。
WebSurferは、ブラウザのアクセシビリティツリーと、その動作を実行するためのマークセットプロンプトに依存しています。
MultimodalWebSurfer
が検索ページにアクセス→その画面キャプチャを LLM に送信→検索せよとの tool_calls
→検索ワードを入力して検索→その画面キャプチャを LLM に送信→スクロールせよとの tool_calls
→...
というように LLM のマルチモーダル機能を利用してブラウジングを自動操作させているということです。
3.1. MultimodalWebSurfer エージェント
MultimodalWebSurfer
では、Web ページの操作(遷移、スクロール、クリック、入力)を行うために Playwright を利用しています。Playwright は、Microsoft が開発したオープンソースのエンドツーエンド(E2E)テストフレームワークで、Webアプリケーションを自動的に操作するためのツールです。ブラウザ(Chromium、Firefox、WebKit)をプログラムからヘッドレスモードで操作できます。
評価時点では GPT-4o のモデルバージョンは 2024-05-13
である必要がありました。
3.1.1. Web 検索を実行せよと判定 [4]
context
1 つ前に実行した進捗台帳の instruction_or_question
項目の answer
をコンテキストとして、Function calling を実行。
ドバイの現在の人気観光スポットと、ドバイの人気ホテルを検索してください。各カテゴリーの結果を要約してください。
tool_calls: web_search
{"reasoning":"ドバイの様々な予算カテゴリーにおける一流ホテルの詳細情報を収集し、総合的な推薦を行う。",
"query":"ドバイの現在の人気観光スポット"}
WebSurfer のナビゲートに関する Tool 定義は以下のようなものが準備されています。tool_calls
で web_search
が選択されましたので、クエリに従って以下の web_search
アクションが実行されます。
アクション | 説明 |
---|---|
visit_url |
指定URLへ移動 (playwright.goto() ) |
history_back |
前のページへ戻る (playwright.back() ) |
web_search |
検索エンジンで検索 (bing.com/search?q=... ) |
click |
指定されたボタンをクリック (playwright.click() ) |
input_text |
フォームにテキストを入力 (playwright.fill() ) |
page_up / page_down
|
ページをスクロール |
answer_question |
ページの内容をもとに質問に回答 |
summarize_page |
ページの要約を取得 |
sleep |
しばらく待機 (playwright.sleep() ) |
to_save_screenshots
を true
にしてありますので、以下のようにブラウザのナビゲート中のスクリーンショットが保存されます。ページ上のインタラクティブな要素(クリック可能なボタンやリンクなど)を抽出し、それらの境界を示すマーク付きのスクリーンショットを作成します。
参考 ブラウザの操作例
1. tool_calls
で input_text
が選択された場合
{"reasoning":"ドバイの様々な予算カテゴリーにおける一流ホテルの詳細情報を収集し、総合的な推薦を行う。",
"input_field_id":51,
"text_value":"ドバイの人気観光スポットと、高級、中級、格安に分類された最高評価のホテル"}
2. tool_calls
で click
が選択された場合
{"reasoning":"ドバイの最高評価ホテルが掲載されているXX Travellerのウェブページを訪問する",
"target_id":114}
3.1.2. 進捗台帳更新 [5]
is_request_satisfied | is_in_loop | is_progress_being_made | next_speaker | instruction_or_question | |
---|---|---|---|---|---|
answer | False | False | True | WebSurfer | 検索結果に基づいて、ドバイの人気観光スポットをまとめてください。次に、ドバイの人気ホテルについても同様に行ってください。 |
3.1.3. ページの内容をサマリーせよと判定 [6]
tool_calls: summarize_page
tool_calls.0.arguments:
{"reasoning": "検索結果に基づいてドバイの主要な観光スポットをまとめ、正確で包括的な推奨情報を収集する" }
context
私はブラウザの検索バーに「ドバイの現在の人気観光スポット」と入力しました。
ウェブページのスクリーンショットは次の通りです:[ドバイの現在の人気観光スポット - 検索] (https://www.bing.com/search?q=current+top+tourist+attractions+in+Dubai&FORM=QBLH&rdr=1&rdrig=868C3F9F277B4E4EA0F9FFCEBDAF4FA7)。
ビューポートはウェブページの13%を表示し、ページの一番上に配置されています。
ウェブページから以下のメタデータが抽出されました。
...
3.1.4. ページの要約ツールを実行 [7]
summarize_page
実行
このウェブページでは、ドバイの人気観光スポットの総合的なリストを提供しており、ブルジュ・ハリファ、ドバイ・モール、アル・クッズ・アート・ディストリクトなどの観光スポットが強調されています。検索結果には、PlanetWare、Time Out Dubai、Visit Dubai、Tripadvisor などのさまざまなソースが含まれており、市内の必見の観光スポットやアクティビティを幅広くカバーしています。これらのアトラクションは、ドバイならではの近代建築の驚異、高級ショッピングスポット、文化的な展示、砂漠サファリなどのアウトドア・アドベンチャーを融合したものです。さらに、このサイトでは、無料アクティビティ、夜のお出かけ、おすすめのビーチなど、ドバイ旅行を最大限に楽しむためのガイドやヒントを提供しています。
3.1.5. 進捗台帳更新 [8]
Bing 検索結果一覧を見ただけの薄い調査ではありますが、1 つ目の目標である人気観光スポットを探すことはできちゃったようですので、次にホテルの検索に移るようです。
is_request_satisfied | is_in_loop | is_progress_being_made | next_speaker | instruction_or_question | |
---|---|---|---|---|---|
answer | False | False | True | WebSurfer | ドバイの高評価ホテルを検索し、その結果を要約してください。 |
→同様にホテルの検索を行う 4 回 GPT-4o 実行 [9~12省略]
4. Inner Loop 完了:進捗台帳更新 [13]
2 つめの目標であるホテルの検索が完了したので、最終回答を行うために travel_agent
を次に呼ぶべきと判定されました。また、タスクの完了を示す is_request_satisfied
が True
になりましたね!
is_request_satisfied | is_in_loop | is_progress_being_made | next_speaker | instruction_or_question | |
---|---|---|---|---|---|
answer | True | False | True | travel_agent | 収集した情報を統合し、ドバイでの1週間の旅行におすすめの観光名所とホテルのリストを作成してください。推奨する旅程とホテルの簡単な説明を含めてください。 |
5. Travel Agent:最終回答 [14]
ユーザーへの最終回答は travel_agent
が担当しますので、進捗台帳のnext_speaker
の通り travel_agent
へ遷移して最後の推論を実行します。
1週間のドバイ海外旅行を計画されているとのこと、素晴らしいですね!以下におすすめの観光地とホテルをリストアップしました。
### おすすめ観光地
1. **バージ・ハリファ(Burj Khalifa)** - 世界で最も高い建物、展望台からの絶景を楽しんでください。
2. **ドバイモール(Dubai Mall)** - 世界最大級のショッピングモールで、ショッピングや飲食、エンターテインメントを楽しめます。
3. **パーム・ジュメイラ(Palm Jumeirah)** - アイコニックな人工島で、ビーチリゾートやアトラクションを満喫できます。
4. **ドバイマリーナ(Dubai Marina)** - 高層ビルが立ち並ぶエリアで、クルーズやダイニングを楽しんでください。
5. **ドバイファウンテン(Dubai Fountain)** - バージ・ハリファのふもとにある噴水ショーは圧巻です。
6. **デザートサファリ(Desert Safari)** - 砂漠でのアドベンチャーを体験できます。
7. **ドバイ博物館(Dubai Museum)** - ドバイの歴史と文化を学べる博物館です。
8. **ジュメイラモスク(Jumeirah Mosque)** - イスラム文化を体験できる美しいモスクです。
### おすすめホテル
1. **バージ・アル・アラブ・ジュメイラ(Burj Al Arab Jumeirah)** - 世界で最も豪華なホテルの一つです。
2. **アトランティス・ザ・パーム(Atlantis, The Palm)** - パームジュメイラにあるリゾートホテルで、ウォーターパークも併設しています。
3. **ジュメイラビーチホテル(Jumeirah Beach Hotel)** - ビーチフロントの豪華ホテルです。
4. **ザ・アドレス・ダウンタウン・ドバイ(The Address Downtown Dubai)** - ドバイモールやバージ・ハリファに近いラグジュアリーホテルです。
5. **アルマーニ・ホテル・ドバイ(Armani Hotel Dubai)** - バージ・ハリファ内にあるスタイリッシュなホテルです。
これらの観光地とホテルで、充実した一週間を過ごしてください。素晴らしい旅をお楽しみください!
極めてシンプルなシナリオでしたが、内部の動作を確認できました。次回はより高度なオーケストレーションを試しましょう。
6. 注意点
MultimodalWebSurfer
エージェントのような実世界に影響を与えるエージェントを何も考えず LLM のみの判断で利用することは、Unmanaged/Uncontrollable になってしまう可能性があり、危険性があると感じました。エンタープライズシステムにソリューションの機能として実装するには Responsible AI の観点での実装、サンドボックス環境での実行、指定されたサイトのみのアクセス制限、禁止操作の定義、機能の制限された REST API による代替等の多重のセキュリティガードレールの実装が不可欠であると考えています。正しくガードレールを整備したのであれば、非常に有用なツールになることは間違い無いでしょう。
6.1. エラー分析
Microsoft Research のチームは論文の中で、発生したエラーの統計解析を行っており、多い順から以下のような物を挙げています。
6.1.1. 持続的な非効率的行動
- エージェントが同じ失敗を繰り返し、適応できない問題
- 例:
MultimodalWebSurfer
が誤った検索クエリを何度も試みる、あるいは不要なデータを何度も取得するケース
6.1.2. 検証不足によるミス
- 収集した情報やコードの実行結果を十分に検証しないことで誤った結論を出してしまう
- 例:ファイルの内容を正しく読み取らないまま次のステップに進んでしまう
6.1.3. ナビゲーションの非効率性
- Web ページやファイルを適切にナビゲートできず、目的の情報に到達できない問題
- 例:
MultimodalWebSurfer
が適切なリンクを見つけられない、またはページ内検索に失敗するケース
6.2. セキュリティ観点
6.2.1. Webサイトへのログイン試行の失敗
- エージェントが何度もログインを試行し、アカウントが一時的に停止された
- ログイン失敗後、エージェントが自動的にパスワードリセットを試みた
6.2.2. 人間の支援を求める試み
- ソーシャルメディアに投稿し、他の人に助けを求めようとした
- 教科書の著者に電子メールを送信し、情報を得ようとした
- 政府機関への情報公開請求を作成し、必要なデータを取得しようとした
これらの試みは、以下の理由で未遂に終わったとのこと。
- 必要なツールやアカウントが不足していた
- 人間の観察者が介入し、エージェントを明示的に停止した
このような問題を防ぐためには、エージェントにリスクの高いアクションを事前に検証する仕組みや実行前に人間の承認を求める Human-in-the-Loop 機能を追加する必要があると考えられます。私も Coder エージェントを有効化した際、執拗に API キーを必要とする REST API を呼ぼうと何回もトライする動作が見られたりして、論文と似た現象が起こりました。他にも多数のエラーをまとめていてインサイトに富んでいるので、把握しておけば事前に緩和策を講じることができるので非常に有用だと感じています。
今後
タスク台帳 (Task Ledger) と進捗台帳 (Progress Ledger)の二重ループの仕組みは複雑なタスクを解いたり自律性の高いエージェントのコントロールの目的に使えそうです。今回は動作の確認のためシンプルなタスクを与えましたが、より複雑なタスクを与えた場合どうなるか更なる検証が必要です。
GitHub
参考