agent-toolgate
v0.1.1
Published
Permission, human-confirmation and audit-log guardrails for LLM tool calling.
Maintainers
Readme
agent-toolgate
Camada de segurança para agentes de IA com function calling: controle de acesso por papel, portão de confirmação humana para ações perigosas, e auditoria automática — tudo isolado por trás de uma interface trocável de modelo, então os testes nunca precisam chamar uma API paga.
Por que
A maioria dos exemplos de "agente de IA" por aí dá ao modelo acesso direto a tudo e torce pra ele não fazer besteira. Esse projeto nasceu de um caso real: conectar um LLM a dados internos de uma empresa, onde "o modelo decidiu sozinho" não é uma resposta aceitável pra uma ação que mexe com dinheiro ou dado de terceiro. agent-toolgate é a parte reutilizável disso — o "motor de segurança" em volta da chamada de ferramenta, sem nenhuma lógica específica de negócio.
Instalação
npm install agent-toolgate zodUso rápido
import { z } from "zod";
import { Agent, Tool, ConsoleAuditLog, AnthropicModel } from "agent-toolgate";
const tools = [
Tool.define({
name: "consultar_estoque",
description: "Consulta o estoque de um produto",
parameters: z.object({ produto: z.string() }),
allowedRoles: ["estoque", "vendas"],
handler: async ({ produto }) => buscarEstoque(produto), // sua lógica real aqui
}),
Tool.define({
name: "cancelar_pedido",
description: "Cancela um pedido",
parameters: z.object({ pedidoId: z.string() }),
allowedRoles: ["financeiro"],
requiresConfirmation: true, // nunca executa sozinho
handler: async ({ pedidoId }) => cancelarPedido(pedidoId),
}),
];
const agent = new Agent({
tools,
model: new AnthropicModel(), // lê ANTHROPIC_API_KEY do ambiente
auditLog: new ConsoleAuditLog(),
});
const result = await agent.ask(
"quais pedidos do cliente X ainda não foram entregues?",
{ user: "matheus", role: "vendas" }
);
if (result.type === "pending_confirmation") {
// mostre `result.token` pro usuário aprovar antes de chamar agent.confirm(token)
}Conceitos centrais
| Peça | O que faz |
|---|---|
| Tool.define() | Declara uma ferramenta: nome, descrição, schema Zod dos argumentos, quem pode chamar, se precisa de confirmação, e o handler que roda de verdade. |
| Agent | Orquestra tudo: filtra ferramentas pelo papel do usuário, pede ao modelo pra decidir, valida os argumentos, segura ações perigosas, executa, e resume o resultado em linguagem natural. |
| ModelClient | A fronteira trocável entre "decidir qual ferramenta usar" e o resto do sistema — permite usar um modelo real (AnthropicModel) ou um falso (MockModel) sem mudar nada mais. |
| AuditLog | Registra toda pergunta, decisão e resultado — inclusive quando é negado ou dá erro. |
O fluxo de segurança, em ordem
- As ferramentas são filtradas pelo papel do usuário antes do modelo sequer saber que elas existem.
- Se o modelo tenta chamar algo fora da lista permitida, é barrado de novo (defesa em camadas).
- Os argumentos que o modelo devolve são validados contra o schema Zod — nunca se confia cegamente no formato.
- Ferramentas marcadas
requiresConfirmationnão executam — ficam pendentes até alguém chamaragent.confirm(token)explicitamente. - Todo caminho — sucesso, negação ou erro — é gravado no
AuditLog.
Testando sem gastar nada
A lógica de permissão, confirmação e auditoria não depende de IA nenhuma — é código determinístico. Use o MockModel pra testar tudo isso de graça, programando as respostas com antecedência:
import { MockModel, InMemoryAuditLog, Agent } from "agent-toolgate";
const model = new MockModel()
.queueDecision({ type: "tool_call", toolName: "consultar_estoque", args: { produto: "arroz" } })
.queueSummary("Temos 42 unidades de arroz em estoque.");
const agent = new Agent({ tools, model, auditLog: new InMemoryAuditLog() });
const result = await agent.ask("quanto temos de arroz?", { user: "ana", role: "estoque" });O AnthropicModel (que gasta créditos de verdade) só entra em cena na demonstração final, nunca nos testes automatizados.
Exemplo completo
Em examples/biblioteca-demo tem um domínio fictício (uma biblioteca) mostrando o fluxo inteiro, incluindo confirmação interativa no terminal:
git clone https://github.com/Matheusedu01/agent-toolgate.git
cd agent-toolgate
npm install
ANTHROPIC_API_KEY=sk-... npm run demo -- "A Dom Casmurro está disponível?"Desenvolvimento
npm install
npm test # roda os testes (MockModel, zero custo)
npm run typecheck # checa os tipos, incluindo o exemplo
npm run build # compila pra dist/Estrutura do projeto
src/
types.ts → contratos centrais (Tool, ModelClient, AuditLog...)
tool.ts → Tool.define()
agent.ts → orquestração (permissão, confirmação, execução)
confirmation-store.ts → memória de ações pendentes
audit-log.ts → ConsoleAuditLog / InMemoryAuditLog
models/
mock-model.ts → LLM falso, usado nos testes
anthropic-model.ts → LLM real (Claude), usado só na demo
test/ → testes automatizados (MockModel)
examples/biblioteca-demo/ → domínio fake de ponta a pontaRoadmap
- [ ] Suporte a outros provedores de LLM (OpenAI) via a mesma interface
ModelClient - [ ]
AuditLogcom adaptador de banco de dados - [ ] Expiração automática de tokens de confirmação
Licença
MIT
