29 · O caçador de bugs e o seletor juntos¶
O seletor decide o que o seu agente faz com um turno: qual ferramenta, com quais valores, ou nada. O caçador de bugs encontra cada caminho que as suas regras deixam até uma ação, ou não encontra nenhum. Juntos, eles respondem a uma pergunta que nenhum responde sozinho: toda chamada de ferramenta passa pelo seletor? Este capítulo é essa busca sobre o reembolso da loja, e o portão que a mantém verdadeira quando alguém acrescenta um caminho que a contorna.
Idiomas
O seletor lê turnos escritos em inglês e em português do Brasil (pt-BR). O idioma é escolhido, nunca adivinhado a partir do turno: na página Settings do console (Language the selector reads), em language numa requisição de plano, ou no settings.language do seu arquivo de vocabulário; sem nenhum deles, inglês. Um turno em português pode ser digitado com os acentos ou sem eles. O português europeu não é uma gramática que o seletor tenha, e um turno em qualquer outra língua não é lido.
Por que eles se combinam¶
Uma política de guardrail que chama uma ferramenta decide, nos seus próprios fluxos, quando a chamada roda. A verificação do seletor (capítulo 24) decide cada chamada pelo seu catálogo e pelo seu rulebook -- mas só as chamadas que lhe são enviadas. Um fluxo que chama a ferramenta direto nunca pergunta. Então o seletor só vale tanto quanto a promessa da política de perguntar a ele toda vez, e essa promessa é exatamente o que o caçador busca: um caminho até uma ação que não pode rodar sem um controle.
Os rails¶
O reembolso da loja atrás das duas ações NeMo do capítulo 27:
stalwart_route lê a mensagem do usuário num plano e recusa o que o plano recusa, e stalwart_check_tool
verifica o reembolso antes de o fluxo rodá-lo. Este é o próprio snippet em Colang 1.0 do SDK, com a intenção e
a ferramenta da loja:
# O estorno da loja atrás do rail de entrada e da guarda de execução da Stalwart, do
# stalwart_agents.langchain.nemo.snippet("1.0"), com a intenção e a ferramenta da loja, em português.
define user request refund
"estorne o meu pedido"
"quero o meu dinheiro de volta"
define bot refuse stalwart declined
"Não posso fazer isso: não é algo que este assistente possa fazer."
define bot refuse stalwart tool
"Não posso fazer isso: a verificação não permitiu."
define bot confirm refund
"O estorno foi feito."
define flow stalwart route input
user request refund
execute stalwart_route
if $stalwart_declined
bot refuse stalwart declined
stop
define flow stalwart guarded refund
user request refund
execute stalwart_check_tool
if $stalwart_allowed
execute refund_card
bot confirm refund
else
bot refuse stalwart tool
A obrigação¶
A equipe escreve a promessa como uma linha da sua tabela de propriedades (capítulo 11):
o reembolso não pode rodar sem $stalwart_allowed, que só a verificação define.
{
"policy": "rails.co",
"properties": [
{
"id": "SEL-01",
"description": "Um estorno roda sem que a verificação do seletor o permita.",
"action": "refund_card",
"context": "stalwart_allowed",
"pins": {},
"expect": "UNSAT",
"gate": "hard"
}
]
}
Enviada com a varredura (properties), a linha se junta às perguntas do próprio caçador como uma da equipe, e
é feita a todo fluxo que chega ao reembolso:
result = client.hunt("rails.co", properties="properties.json", gate=True)
print("gate passed:", result.result["gate"]["passed"])
for finding in result.findings:
print(f"{finding.rule} {finding.raw['title']} ({finding.raw['type']}) on {finding.raw['action']}")
gate passed: True
QG101 Unchecked action (hotspot) on stalwart_route
QG101 Unchecked action (hotspot) on stalwart_check_tool
gate passed: False | no_new_unshippable: QG005 42d4d03a70a3
QG002 Escapable guard at rails.hurried.co:28 (stalwart guarded refund) | row SEL-01
The policy gates 'refund_card' on 'stalwart_allowed', and there is a way past it.
QG005 Unshippable policy at rails.hurried.co:40 (quick refund)
line 40: tool action 'refund_card' is registered from flow 'quick refund' as well as from 'stalwart guarded refund'
A primeira varredura passa. Os seus dois achados são hotspots, itens de revisão que nunca reprovam o portão:
stalwart_route e stalwart_check_tool rodam sob nenhum controle, porque eles são o controle, rodando em
todo turno correspondente por projeto. O snippet do SDK diz isso nos seus próprios comentários.
O portão que a mantém verdadeira¶
Um colega acrescenta um reembolso direto da intenção:
# Acrescentado às pressas: um estorno direto da intenção.
define user ask quick refund
"só estorna"
define flow quick refund
user ask quick refund
execute refund_card
result = client.hunt("rails.hurried.co", properties="properties.json", gate=True)
print("gate passed:", result.result["gate"]["passed"], "|", "; ".join(result.result["gate"]["failed"]))
for finding in result.findings:
if finding.raw["type"] != "hotspot":
where = finding.location
print(f"{finding.rule} {finding.raw['title']} at {where['file']}:{where['line']} ({where['flow']})",
f"| row {finding.raw['obligation']}" if finding.raw["obligation"] else "")
print(" ", finding.raw["message"].split(";")[0])
A segunda varredura, na saída acima, reprova o portão. QG002 nomeia a linha que ela quebra, SEL-01, na
linha protegida que a equipe lê como segura: o reembolso está condicionado à verificação, e agora há um
caminho que passa por ela. QG005 acrescenta que o reembolso está registrado por dois fluxos, então o mais
fraco decide, e uma política que não pode ser entregue é o que reprova o portão; QG002 sozinho, numa
escrita que não é crítica, seria um aviso. Rodada na CI pela GitHub Action num projeto (capítulo 28), esta é a
verificação reprovada do pull request, antes que o fluxo chegue a alguém.
Um agente da Parte I não precisa de linha: o grafo que o agent.yaml monta põe toda ferramenta no passo de
ferramentas protegido, e stalwart verify busca, em cada caminho, um que chegue a uma ferramenta contornando-o
(capítulo 31). O capítulo 27 mostra a mesma busca
reprovando quando um passo que contorna a verificação é acrescentado à mão.
O que uma varredura limpa significa, e o que não significa¶
- Ela não encontrou caminho até o reembolso que contorne a verificação do seletor: nenhum fluxo, e
nenhuma sequência de turnos que a varredura desdobra, chega a
refund_cardsem$stalwart_allowed. - Ela não diz nada sobre se o seletor escolheu bem. Se a verificação permitiu a chamada certa para o turno é decisão do roteador, lida pelas suas regras a partir do que as suas ferramentas declaram -- os limites do capítulo 20, que uma varredura não consegue levantar.
- Ela cobre as obrigações que recebeu. Uma ferramenta sem linha é relatada como hotspot onde nada a protege, não provada; escreva uma linha para toda ferramenta que precisa passar pelo seletor.