43 · Segurança das respostas¶
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.
Com replies: {rules: ...} configurado, todo turno que uma pessoa envia é examinado em busca de dados pessoais
antes que o roteador ou o modelo o leia, e toda resposta que o modelo escreve é examinada de novo antes de ser
mostrada, tenha havido uma ação antes dela ou não. As suas regras dizem o que cada classe de dado pessoal
recebe, quais expressões nunca são ditas, quais ofertas uma resposta pode fazer e quais frases precisam
acompanhar uma escrita. Nenhum modelo julga nada disso: o runtime na sua máquina decide cada regra.
Dados pessoais¶
As classes que o runtime encontra, como cada uma é encontrada, o que ela recebe quando as suas regras não dizem nada, e como é mascarada, gerados a partir dos detectores do runtime:
| Classe | Como é encontrada | Padrão | Mascarada como |
|---|---|---|---|
email |
um endereço da forma nome@domínio | allow |
j***@example.com |
iban |
um número de conta com o comprimento que o seu país define, cujos dígitos de verificação conferem | redact |
GB** **** 2681 |
national_id |
um social security number dos EUA, um national insurance number do Reino Unido, ou um CPF cujos dígitos verificadores conferem | redact |
***6789 |
card |
de 13 a 19 dígitos cuja soma de verificação (Luhn) confere: um número que não confere fica como está | redact |
**** 1111 |
phone |
um número internacional de 8 a 15 dígitos, ou um nacional de 10 ou 11 | allow |
***0123 |
Um número de cartão é encontrado pela sua soma de verificação, não pela sua forma: dezesseis dígitos que não passam na verificação de Luhn ficam como estão, porque não são um número de cartão. Cada classe recebe uma de três ações:
| Ação | Num turno enviado ao modelo | Numa resposta que o modelo escreveu |
|---|---|---|
redact |
mascarado antes que o roteador e o modelo leiam o turno | mascarado na frase |
withhold |
o turno inteiro é retido: nada o lê, e a pessoa é convidada a enviá-lo de novo sem o valor | a frase é removida |
allow |
deixado como está | deixado como está |
Um valor que uma frase de resultado pode repetir. Uma frase que relata uma escrita pode citar um valor que a escrita recebeu -- o cartão para onde foi um reembolso -- e esse valor é mascarado nela em vez de removido, qualquer que seja a ação da classe, a menos que a classe seja permitida.
Redação¶
never_say: expressões que nunca são ditas. Uma frase que contenha uma delas, em palavras inteiras e em qualquer caixa, é removida.offers: as ofertas que uma resposta pode fazer. Uma frase que contenha um dosmarkers(como discount ou voucher) e nenhuma das ofertasallowedé removida.must_accompany: frases que precisam acompanhar algo: um aviso acrescentado quando a chamada de uma ferramenta rodou neste turno (when_done), ou quando uma resposta cita uma passagem com uma etiqueta (when_cited). Ele é acrescentado uma vez, onde a resposta ainda não o diz.
O arquivo de regras de resposta¶
As regras são um arquivo, YAML ou JSON, nomeado no agent.yaml como replies: {rules: reply-rules.yaml} ou em
Python como Agent(..., replies={"rules": "reply-rules.yaml"}). O da loja:
# As regras de resposta da loja, como a página Reply rules do console as salva.
personal_data:
card: redact # o padrão, escrito por extenso
national_id: withhold # um turno com um deles não chega a nenhum modelo; uma resposta com um deles perde a frase
email: allow
never_say:
- "estorno garantido"
must_accompany:
- when_done: refund_card
add: "Os estornos chegam ao cartão em três a cinco dias úteis."
Cada chave que o runtime lê, gerada a partir do runtime:
| Chave | O que diz |
|---|---|
personal_data |
para cada classe de dado pessoal, redact, withhold ou allow |
must_accompany |
frases que precisam acompanhar uma escrita feita ou uma passagem citada |
must_accompany[].add |
a frase acrescentada |
must_accompany[].when_done |
acrescentada quando a chamada desta ferramenta rodou neste turno |
must_accompany[].when_cited |
acrescentada quando uma resposta cita uma passagem com esta etiqueta |
reply_exactly |
respostas dadas palavra por palavra no lugar de qualquer outra resposta, sem modelo e sem nada acrescentado |
reply_exactly[].when_cited |
dada quando uma resposta cita uma passagem com esta etiqueta |
reply_exactly[].when_asked |
dada quando o turno diz uma das expressões do assunto: as suas words ou, sem elas, o nome do assunto com _ e - lidos como espaços |
reply_exactly[].say |
a resposta exata, sem nada acrescentado |
reply_exactly[].words |
com when_asked: as expressões que perguntam sobre o assunto, comparadas como palavras inteiras, sem distinguir maiúsculas, por exemplo alergia, alérgico, amendoim |
never_say |
expressões que nunca se devem dizer: uma frase que contenha uma delas é removida |
offers |
as ofertas que uma resposta pode fazer |
offers.allowed |
as ofertas permitidas |
offers.markers |
as palavras que fazem de uma frase uma oferta: uma frase com um marcador e sem oferta permitida é removida |
As mesmas regras ficam na página Regras de resposta do console, como um formulário sobre o mesmo arquivo, e em
/v1/reply-rules, em versões. Um arquivo que o runtime não consegue ler -- uma classe que ele não conhece, uma
ação que não é uma das três -- é recusado com a chave que está errada.
As respostas da loja, examinadas¶
A loja roda com uma licença Enterprise. Os pedidos dela guardam o cartão cadastrado e o cliente, que são dados pessoais, e um modelo lê os dados pessoais que uma ferramenta devolve só no Enterprise, com a sua própria chave; em outro plano, a resposta diz que foi escrita sem um modelo.
O modelo abaixo faz o papel do seu, e registra o que recebeu:
SEEN = [] # o que o modelo recebeu, turno a turno
# Faz as vezes do seu modelo: o que lhe perguntam, e a resposta que ele escreve.
SCRIPT = {
"zork": (None, ""),
"o meu cartão é **** 1111, ele está cadastrado?": (
None,
"O seu cartão 4111 1111 1111 1111 está cadastrado; o cartão 4111 1111 1111 1112 não está."),
"a encomenda do 4412 desapareceu": (
{"name": "refund_card", "arguments": {"order_id": "4412", "amount": 12.50}},
"Estornei 12,50 reais pelo pedido 4412. É um estorno garantido."),
}
def model(conversation):
turn = [m for m in conversation if m["role"] == "user"][-1]["content"]
SEEN.append(turn)
call, reply = SCRIPT[turn]
if conversation[-1]["role"] == "user" and call:
return {"content": "", "tool_calls": [call]}
return reply
desk = Agent("desk", tools=[get_order, refund_card], model=model, on_unread="model",
replies={"rules": "reply-rules.yaml", "language": "pt"})
for text in ("zork",
"o meu cartão é 4111 1111 1111 1111, ele está cadastrado?",
"o meu CPF é 123.456.789-09",
"a encomenda do 4412 desapareceu"):
reply = desk.chat(text, user="u-17")
if reply.waiting:
reply = desk.confirm("u-17", "approve")
print(f"{text}\n -> {reply.text}")
print("O modelo recebeu:", SEEN)
zork
-> Não reconheci nada nisso. Posso get order ou refund card. Pode dizer qual ferramenta ou qual item você quer?
o meu cartão é 4111 1111 1111 1111, ele está cadastrado?
-> O seu cartão **** 1111 está cadastrado; o cartão 4111 1111 1111 1112 não está.
o meu CPF é 123.456.789-09
-> Essa mensagem tinha dados que não posso receber aqui, então não a li nem fiz nada. Envie de novo sem eles, por favor.
a encomenda do 4412 desapareceu
-> Estornei 12,50 reais pelo pedido 4412. Os estornos chegam ao cartão em três a cinco dias úteis.
O modelo recebeu: ['o meu cartão é **** 1111, ele está cadastrado?', 'a encomenda do 4412 desapareceu', 'a encomenda do 4412 desapareceu']
- O número de cartão que a pessoa digitou foi mascarado antes que algo lesse o turno: o modelo recebeu
**** 1111. - A resposta do modelo citou o mesmo cartão válido, mascarado, e um número de dezesseis dígitos que não passa na soma de verificação, deixado como está.
- O turno com um CPF foi retido inteiro, sob
national_id: withhold: nada o leu, e a pessoa foi convidada a enviá-lo de novo sem o número. Ele não está no que o modelo recebeu. - Depois que o reembolso rodou, É um estorno garantido. foi removida (
never_say), e o aviso que as regras exigem para um reembolso foi acrescentado.
As contagens¶
Cada verificação é contada, pelo medidor sob o qual é registrada, com os outros medidores da sua licença. Uma contagem é um número: não carrega nenhum texto, nenhum valor e nenhum turno.
| Contagem | O que conta |
|---|---|
reply_temperature_kept |
uma variação que, relida, teve outro modo ou outras palavras travadas, então a própria frase do modelo foi enviada |
reply_temperature_varied |
uma frase do modelo dita de outro jeito, com a temperatura das respostas ligada |
reply_exact_reply |
uma resposta dada palavra por palavra no lugar de qualquer outra, por reply_exactly |
reply_pd_detected_<class> |
um valor daquela classe de dado pessoal encontrado |
reply_pd_masked |
um valor enviado a uma escrita, repetido na frase do seu próprio resultado, mascarado |
reply_pd_withheld |
um turno retido, ou uma frase removida, por um valor que as regras retêm |
reply_pd_redacted |
um valor mascarado porque as regras ocultam a sua classe |
reply_assertion_refused |
uma frase dizendo que uma escrita foi feita sem que nada na sessão a tentasse, substituída |
reply_outcome_replaced |
uma frase que o resultado da sua ação não permite, substituída pela formulação |
reply_value_highlighted |
uma frase num trabalho da equipe que afirma um valor que nenhum registro tem, mantida e destacada |
reply_value_replaced |
uma frase que afirma um valor que a sua ação não recebeu nem devolveu, substituída |
reply_outcome_added |
uma escrita deste turno que a resposta omitiu, acrescentada a partir da sua formulação |
reply_wording_removed |
uma frase com uma expressão que nunca se deve dizer, removida |
reply_offer_removed |
uma frase que faz uma oferta fora das permitidas, removida |
reply_wording_added |
uma frase que as regras exigem, acrescentada |
reply_facts_untraced |
um valor que a resposta afirma e que nenhum registro de chamada tem |
reply_facts_traced |
um valor que a resposta afirma, rastreado até a chamada e o campo de onde veio |
reply_facts_conflict |
um valor rastreado que outra fonte deste turno dá diferente, para a mesma coisa |
reply_facts_stale |
um valor rastreado lido há mais tempo do que a fonte diz que um resultado vale |
reply_facts_out_of_range |
um valor rastreado fora do intervalo que o esquema de saída da ferramenta permite |
Os limites¶
- Um detector encontra as classes que nomeia, e nenhuma outra. Um nome, um endereço postal, uma data de nascimento ou um identificador de outro país não é detectado, e fica como está.
- Um detector encontra um valor escrito como ele o lê. Um número de cartão escrito por extenso, ou dividido em duas mensagens, não é encontrado.
- Nenhum modelo julga uma resposta. Uma regra casa com as palavras que recebe: uma expressão dita com outras
palavras não é uma expressão que
never_saylista. - O exame cobre os turnos que o agente lê e as respostas que o seu modelo escreve. Uma resposta que nenhum modelo escreveu -- uma pergunta fixa, uma recusa, uma formulação -- é o texto do próprio produto.