Aula 02 · Base

O ciclo não mudou, apenas existem mais ferramentas

"O loop não mudou em nada, apenas adicionei coisas ao array TOOLS." - s02_tool_use.py Palavras originais.

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

Quantos lugares você precisa mover para adicionar uma ferramenta?

O agente de S01 conhece apenas bash. Como você mudaria para ativar também read_file / write_file / edit_file?

A primeira reação de muitas pessoas é: ciclo de mudança. errado. Não toque em uma única linha do loop. Só são necessárias três coisas:

  1. Escreva uma função manipuladora Python (run_read(path, limit)).
  2. Registre-o na tabela de mapeamento TOOL_HANDLERS ("read_file": lambda **kw: run_read(...)).
  3. Adicione uma instrução de esquema JSON ao array TOOLS (informando ao modelo como a ferramenta é chamada e quais parâmetros ela aceita).

Quando o loop vê um bloco tool_use, pressione block.name para pesquisar a função no mapa de despacho, execute-a e coloque a saída de volta em tool_result. Ele segue exatamente o mesmo caminho do bash.

# Mapa de despacho: nome → manipulador lambda
TOOL_HANDLERS = {
    "bash": lambda **kw: run_bash(kw["comando"]),
    "read_file": lambda **kw: run_read(kw["caminho"], kw.get("limit")),
    "write_file": lambda **kw: run_write(kw["caminho"], kw["content"]),
    "edit_file": lambda **kw: run_edit(kw["caminho"], kw["old_text"], kw["new_text"]),
}

Veja como o despacho é roteado

O widget a seguir permite clicar em uma solicitação tool_use que pode ser enviada por um modelo para ver como ela é roteada para uma função Python específica. Nota: block.name determina qual linha seguir.

safe_path: uma linha de defesa que não pode ser omitida

Conceda ao agente direitos de acesso aos arquivos. A falha de segurança mais provável é o path escape: o modelo deveria estar funcionando em /home/user/project/, mas acabou enviando um read_file("../../etc/passwd").

Existe uma pequena função em s02 que trata disso:

def safe_path(p: str) -> Caminho:
    path = (WORKDIR / p).resolve() # Normalizar, resolver .. e soft links
    se não path.is_relative_to(WORKDIR):
        raise ValueError(f"Path escapa do espaço de trabalho: {p}")
    caminho de retorno

A chave está nas duas etapas de .resolve() + .is_relative_to() - analisar o caminho absoluto e depois verificar se ele ainda está na sandbox. Sem o primeiro, foo/../../etc pode passar; sem este último, nenhuma verificação é feita.

Identifique a segurança do caminho

Os 5 caminhos a seguir são todos parâmetros read_file que podem ser enviados pelo modelo. Quais serão permitidos pelo safe_path e quais serão rejeitados? Suponha que WORKDIR = /home/user/project.

Não adicione ferramentas perigosas ao agente

É fácil adicionar ferramentas, mas lembre-se: Cada ferramenta adicionada é um novo limite de capacidade do modelo. Em s02, bash já tem uma lista negra (rm -rf /, sudo, shutdown) e write_file tem restrições de safe_path. Faça três perguntas a si mesmo antes de adicionar ferramentas à produção:

  • Essa ferramenta pode permitir que o modelo faça coisas irreversíveis? (rm, enviar e-mail, git push)
  • O que podevazar? (env vars, .ssh, cookies)
  • A saída de erro será tratada como feedback de comando? (injeção imediata via saída da ferramenta)

A aula s07 adicionará uma "camada de permissão" para extrair essas decisões do código e torná-las declarativas.

Interativo

Widget 1 · Envio de ferramentas · Como tool_use é roteado para o manipulador

Clique em uma solicitação tool_use e veja como block.name no loop encontra a função correspondente, a executa e coloca a saída de volta no bloco tool_result.

模型发来的 tool_use 块
TOOL_HANDLERS 映射表

        
执行结果 · tool_result 块
(点上面任意一条 tool_use 触发路由)
Interativo

Widget 2 · Caminho Seguro · Detecção de fuga para 5 caminhos

Cada caminho será processado por safe_path(). Suponha que WORKDIR = /home/user/project, clique em "Liberar" ou "Rejeitar" - depende se sua intuição sobre o escape do caminho está correta.

答对 0 / 5
Interativo

Widget 3 · Adicionar uma ferramenta · O que precisa ser alterado para adicionar uma ferramenta global ao agente?

Suponha que você queira adicionar uma nova ferramenta glob(pattern) para permitir que o agente encontre arquivos em lotes. Preencha os espaços em branco: Todos os três devem ser alterados, nenhum deles pode faltar.

第 1 处 · 写一个 handler 函数
def run_glob(pattern: str) -> str:
    import glob
    return "\n".join(glob.glob(pattern))
第 2 处 · 注册到 dispatch map(选正确一行)
第 3 处 · 在 TOOLS 数组里加 schema(选正确一组)