Aula 08 · simultâneo

Deixe o agente funcionar sozinho sem bloqueá-lo.

「Fire and forget — the agent doesn't block while the command runs.」

⏱ ~10 min · 📝 3 componentes interativos · 🧑‍💻 Baseado em shareAI-lab · s08_background_tasks.py

A dor de bloquear chamadas

A ferramenta bash no S02 é síncrona: subprocess.run(..., timeout=120). A execução de um comando como npm install leva 90 segundos e todo o loop do agente fica travado por 90 segundos. O usuário olha para o terminal, sem saber se ele está desligado ou funcionando.

Solução para s08: Forneça ao agente uma ferramenta background_run. Ele retorna imediatamente um task_id e o comando é executado em outro thread. O agente continua fazendo loop e fazendo outras coisas; quando a tarefa BG for concluída, os resultados serão adicionados à fila de notificação.

def executar(self, comando: str) -> str:
    task_id = str(uuid.uuid4())[:8]
    self.tasks[task_id] = {"status":"em execução", ...}
    thread = threading.Thread(target=self._execute, args=(task_id, comando), daemon=True)
    thread.start()
    retornar f"Tarefa em segundo plano {task_id} iniciada" # Retornar imediatamente

Como devolver o resultado ao agente?

A chave é uma fila thread-safe: quando o thread bg é concluído, ele é anexado à fila; antes de cada chamada LLM pelo thread principal a fila é drenada e a notificação de conclusão é inserida nas mensagens como mensagens do usuário.

def agent_loop(mensagens):
    while Verdadeiro:
        # Drenar notificações de BG antes de cada chamada do LLM
        notificações = BG.drain_notifications()
        Notificações if:
            mensagens.append({
                "função": "usuário",
                "content": f"<background-results>{notif_text}</background-results>",
            })
        resposta=cliente.messages.create(...)
        ...

      

Dessa forma, o agente gera uma tarefa BG na enésima rodada. Quando a tarefa for concluída na rodada N+3, a próxima chamada LLM trará automaticamente os resultados - o modelo saberá quando vir o bloco <background-results>: "Ah, essa tarefa foi concluída, vou continuar."

Demonstração da linha do tempo

O widget a seguir permite simular: o thread principal funciona a cada segundo (simulando a batida do ciclo do agente); você pode gerar a tarefa BG a qualquer momento. Observe como as duas pistas se encontram no “ponto de drenagem”.

Quais comandos devem ser colocados em segundo plano?

Nem todos os comandos devem ser colocados em segundo plano. Existem dois critérios:

  1. Demora: a execução síncrona em poucos segundos é mais simples, eliminando a necessidade de manter filas.
  2. Importância do resultado: Se o resultado for usado imediatamente na próxima etapa (como cat file.txt imediatamente seguido por grep), o plano de fundo não terá sentido - você ainda terá que esperar por ele.
Interativo

Widget 1 · Linha do tempo · Tópico principal + 2 tópicos BG

Clique em Spawn para despachar o trabalho para o thread do BG. O thread principal verifica a fila de notificação a cada tick. Veja como as três raias se entrelaçam.

🧠 Main (agent loop)
⚙ Background thread A
(idle)
⚙ Background thread B
(idle)
queue: []
Interativo

Widget 2 · Fire & Forget Judgment · 8 comandos, quais valem a pena apoiar?

Escolha primeiro plano (síncrono, etc.) ou plano de fundo (geração assíncrona) para cada comando. Preste atenção às duas dimensões “deve esperar pelo resultado” + “demorado”.

答对 0 / 8
Interativo

Widget 3 · Tempo de drenagem · Em qual rodada a notificação foi vista

Regra principal: O thread principal drena a fila antes de cada chamada LLM. Dê a você 5 cenários. Resposta: Após a conclusão da tarefa BG, em qual rodada os resultados entrarão no campo de visão do agente.

答对 0 / 5