25 · O feedback e o vocabulário aprendido¶
O roteador lê um turno pelas palavras que as suas ferramentas declaram. Os seus usuários têm palavras
próprias -- tire o pedido 4411 do cartão onde a sua ferramenta diz refund_card --, e os polegares deles
ensinam essas palavras ao roteador. Este capítulo é o que um polegar registra, como o minerador hospedado
transforma polegares num novo vocabulário e como um vocabulário é revertido.
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.
Um polegar¶
O polegar de uma pessoa, para cima ou para baixo, sobre o que o roteador escolheu é um registro de feedback. Numa sessão:
with Client() as client:
chat = client.session("desk", catalogue=catalogue, rulebook=rulebook)
plan = chat.read("mostre o pedido 4411")
print(chat.thumbs(plan, up=True)) # o roteador escolheu bem
plan = chat.read("tire o pedido 4411 do cartão")
print(plan.steps[0].selection.tool, "->", chat.thumbs(plan, up=False, corrected="refund_card"))
O segundo turno chegou a get_order, e o polegar para baixo diz que a ferramenta certa era refund_card
(corrected). O mesmo polegar repetido é um registro só no serviço. Um agente da Parte I faz o mesmo com
agent.thumbs(reply, up=...), e o callback do LangChain com StalwartFeedbackCallback (capítulo
27).
Um polegar para baixo vale mais com o que se quis dizer. agent.meant_choices(reply) -- meant_choices(rated) ao
lado do callback do LangChain -- lista o que oferecer à pessoa:
primeiro as ferramentas que o roteador pesou -- as que ele perguntou entre si, ou as duas leituras de uma
palavra que ele leu de dois jeitos --, depois todas as outras que o agente podia alcançar, e "" por último
para "nenhuma delas". A resposta é o corrected.
O que um registro contém¶
desk = Agent.from_file("agent.yaml")
reply = desk.chat("mostre o pedido 4411", user="u-17")
print(json.dumps(desk.feedback_record(reply, up=True), indent=1, sort_keys=True))
{'accepted': 1}
get_order -> {'accepted': 1}
{
"agent": "desk",
"cited": [],
"context": {
"before": [],
"history": "first",
"previous": [],
"readings": [],
"step": 0,
"steps": 1
},
"corrected": "",
"decided_by": "tool: admission",
"delegated": false,
"language": "pt-BR",
"outcomes": [
"get_order:done"
],
"reply_digest": "1bfd98bf2f6401b4e33432e2778566c3d8b4d5a315f0b10ca25d1706a6a2d733",
"rewrites": [],
"router_digest": "",
"thumb": "up",
"tool": "get_order",
"turn": "mostre o pedido 4411",
"verdict": "resolved",
"visible": [
"charge_card",
"get_order",
"hand_off",
"read_inbox",
"send_receipt"
],
"vocabulary_digest": "bdd0a20dc1bccb3a79e549d99b44a40a1039f2ce18c76d95a2fdc41fc0f3715d"
}
ThumbRefused: personal data in the request, so nothing was sent: a telephone number at turn. Remove it, or put a placeholder in its place (an address at example.com, say), and send the request again
O registro é as palavras do turno avaliado com a leitura que o roteador fez delas: o turno, o agente, as
ferramentas que ele podia ver (visible), a ferramenta que escolheu e a regra que a escolheu (decided_by),
o desfecho (verdict), o vocabulário com que leu e o polegar. O que a resposta disse fica guardado só como o
que foi feito -- o resultado de cada ação (outcomes) e os trechos que ela citou -- e um digest do seu
texto: nunca as palavras da resposta, o valor de um argumento, o resultado de uma ferramenta ou um turno
anterior.
Um registro também guarda o contexto em que o turno foi lido (context), porque o roteador lê pelo
contexto e só acerta ou erra dentro dele: tag lists please pede as listas de tags onde as suas ferramentas só
as listam, e marca listas onde uma ferramenta as marca. O contexto é o lugar da etapa avaliada no plano
(step, steps) e as ferramentas das etapas antes dela (before), o que o turno anterior fez -- first,
asked, answered ou declined (history) -- e as ferramentas que ele chamou ou entre as quais perguntou
(previous), e, onde o roteador leu uma palavra de dois jeitos, as ferramentas que as duas leituras alcançaram
(readings). Só nomes de ferramentas: nenhuma palavra de um turno anterior.
O minerador aprende com as palavras do turno, então o registro é examinado atrás de dados pessoais na sua máquina antes de ser enviado, e um polegar sobre um turno que os contém é recusado, sem nada enviado:
reply = desk.chat("mostre o pedido 4411, o meu telefone é (11) 91234-5678", user="u-17")
try:
desk.thumbs(reply, up=True)
except ThumbRefused as refused:
print("ThumbRefused:", refused)
A última linha da saída. Um polegar sobre um turno inteiro de várias instruções, sobre uma resposta que a conversa decidiu ou sobre a resposta depois de uma confirmação também é recusado, nomeando o que avaliar no lugar: essas não são leituras das palavras da pessoa.
Os registros são guardados pela retenção do seu plano (capítulo 16), lidos por mais
ninguém e nunca usados para treinamento. GET /v1/feedback/summary conta os polegares dos últimos trinta dias
pelo que avaliaram -- uma ferramenta que o roteador escolheu, um turno que o modelo assumiu, uma pergunta que o
roteador fez, uma resposta a partir das suas fontes --, e GET /v1/feedback/export dá cada registro guardado
como uma linha de JSON, que é o que uma equipe que roda o seu próprio minerador lê.
O minerador hospedado¶
POST /v1/vocabulary/mine (ou client.mine(model)) enfileira uma execução de aprendizado sobre o seu feedback
guardado e o seu vocabulário em vigor, num idioma só (abaixo). Ela propõe palavras que os seus usuários usaram para as suas
ferramentas, e só as aplica quando cada uma das suas cinco barreiras se mantém e o vocabulário em vigor ainda
é a versão sobre a qual ela minerou. As barreiras: nenhuma escrita é alcançada por engano, no seu corpus de
avaliação ou em qualquer caso de feedback; o feedback deixado de fora do aprendizado não é respondido pior do
que antes; a linha de base do seu corpus e as dos seus diálogos, onde você as tem, continuam valendo; e o novo
arquivo passa limpo nas verificações. A execução é respondida na hora com um id; GET
/v1/vocabulary/mine/{run_id} (client.ledger(run_id)) lê o seu estado -- queued, running, finished,
failed ou cancelled --, se ela aplicou, a versão que pôs em vigor ou a barreira que a segurou. O seu
registro nomeia cada caso por digest, nunca pelas suas palavras. DELETE /v1/vocabulary/mine/{run_id} retira
uma execução na fila; uma que já está rodando termina.
A página Miner do console mostra as mesmas execuções, e a página Vocabulary cada versão e o que o seu registro
diz (GET /v1/vocabulary/history).
Um vocabulário, com versões¶
O vocabulário em vigor (GET /v1/vocabulary, client.vocabulary()) é um arquivo com as suas palavras e as
ferramentas que elas querem dizer. Uma versão fica guardada quando a próxima entra em vigor, então POST
/v1/vocabulary/revert -- ou client.revert_vocabulary(), ou a página Vocabulary -- põe em vigor de novo a
anterior, uma versão por chamada. PUT /v1/vocabulary publica uma versão que você mesmo escreveu. Todo plano
nomeia o vocabulário com que leu (vocabulary_digest), então um plano que mudou pode ser rastreado até a
versão que o mudou.
Uma versão fica em vigor para cada idioma que o roteador lê: um arquivo é do idioma que o seu
settings.language nomeia -- en ou pt-BR -- e do inglês quando não nomeia nenhum. GET /v1/vocabulary e
POST /v1/vocabulary/revert aceitam ?language= -- ou senão o idioma da sua página Settings -- um registro
de feedback traz o idioma em que o seu turno foi lido, e uma execução de aprendizado minera um idioma -- o
language que o seu corpo nomeia, ou senão o da sua página Settings -- só para o arquivo desse idioma. Um
polegar em português nunca ensina uma palavra ao arquivo em inglês.
O runtime na sua máquina recebe a versão em vigor na próxima renovação da sua licença, então uma versão posta em vigor, ou revertida, chega aos seus agentes nesse prazo.
A forma de uma frase que o roteador não conseguiu ler de jeito nenhum -- não uma palavra, mas como a frase é
construída -- é guardada por uma execução de mineração só como forma, no próprio alfabeto do roteador e nunca
com uma palavra sua. GET /v1/grammar-reports/shipped lista as suas formas que uma versão do roteador agora
lê. Uma forma vai com a forma do seu contexto, nunca com o contexto: o que o turno anterior fez, onde a etapa
estava no plano, quantas ferramentas uma palavra lida de dois jeitos alcançou, e cada ferramenta antes dela
como as classes de palavra do seu nome (ACTION OBJECT), nunca o nome. Uma forma só é guardada onde cinco turnos
distintos a compartilham num mesmo contexto. Enviar uma você mesmo é opcional: um relatório sem consentimento é recusado
(grammar_report_not_consented), e também um num alfabeto que nenhuma versão trouxe
(grammar_report_alphabet_unknown).
Os limites¶
Os limites do capítulo 20 valem aqui, e mais estes:
- Um vocabulário ensina palavras ao roteador, não discernimento: uma palavra aplicada a uma ferramenta lê essa ferramenta onde quer que seja dita.
- O minerador só aplica o que as suas barreiras sustentam, e as barreiras leem os casos que você tem. Uma palavra que ninguém avaliou não é aprendida.