エージェントをブロックせずにエージェントを単独で実行させます。
「起動したら忘れる - コマンドの実行中、エージェントはブロックしません。」
通話をブロックする苦痛
S02 の bash ツールは同期です: subprocess.run(..., timeout=120)、npm install のようなコマンドの実行には 90 秒かかり、エージェント ループ全体が 90 秒間停止します。ユーザーは、端末がハングアップしているのか、動作しているのかわからず、端末を見つめます。
s08 の解決策: エージェントに background_run ツールを提供します。すぐに task_id が返され、コマンドは別のスレッドで実行されます。エージェントはループを続けて他のことを行います。 bg タスクが完了すると、 結果が通知キューに追加されます。
def run(self, command: str) -> str: task_id = str(uuid.uuid4())[:8] self.tasks[task_id] = {"status":"running", ...} thread = threading.Thread(target=self._execute, args=(task_id, command), daemon=True) thread.start() return f"Background task {task_id} started" # 立即返回
結果をエージェントに返すにはどうすればよいですか?
重要なのはスレッドセーフなキューです。BG スレッドが完了すると、キューに追加されます。 メインスレッドによる各 LLM 呼び出しの前にキューが空になり、完了通知がユーザーメッセージとしてメッセージに詰め込まれます。
def agent_loop(messages): while True: # Drain bg notifications before each LLM call notifs = BG.drain_notifications() if notifs: messages.append({ "role": "user", "content": f"<background-results>{notif_text}</background-results>", }) response = client.messages.create(...) ...
このようにして、エージェントは N 番目のラウンドで bg タスクを生成します。タスクが N+3 ラウンドで完了すると、次の LLM 呼び出しで自動的に結果が返されます。モデルは <background-results> ブロックを見たときに「ああ、そのタスクは終了したので、続行します。」と認識します。
タイムラインのデモ
次のウィジェットを使用すると、メイン スレッドが毎秒動作します (エージェントのサイクル ビートをシミュレートします)。 bg タスクはいつでも生成できます。 2 つの手がかりが「流出点」でどのように出会うかに注目してください。
どのコマンドをバックグラウンドに配置する必要がありますか?
すべてのコマンドをバックグラウンドにスローする必要はありません。基準は 2 つあります:
<オル>cat file.txt の直後に grep が続く)、背景は意味がありません。それでも待機する必要があります。