Ligar e desligar
Os registros de turno são a funcionalidadeturns do espaço, ligada por padrão; um espaço a desliga no documento features, por um diff aprovado do papel security. Com ela desligada, POST /v1/turns e as rotas de replay respondem 404, e os SDKs não gravam nada, mesmo com a captura ligada no código. O documento recording, do papel integration, diz o modo de conteúdo do espaço e de cada fonte, os pinos exigidos, quanto tempo a camada guardada mantém um turno (kept_days, 30 por padrão, de 7 a 90), quanto tempo um cenário de replay guarda os turnos dele (scenario_days, 180 por padrão), se o modelo de dado pessoal passa nos registros guardados (pii_model) e a fração das conversas guardadas inteiras por amostra (sample_rate, 5% por padrão). Mudar o modo de conteúdo para um que guarda mais pede também o papel security.
O que é um turno
Um turno vai da entrada dele até a última coisa que emitiu à pessoa ou a um documento. A entrada pode ser uma mensagem (kind: message), uma ação de interface, como um toque num item ou num “ver mais” (action), um evento de sistema (event) ou um temporizador que disparou (timer). Uma ação de interface é um turno por si, mesmo sem chamada de modelo. Um subagente, ou um agente chamado como ferramenta, abre um subturno, com turn_id próprio e o turno que o abriu em agent.parent_turn_id.
Capturar
O SDK captura no processo do agente, no momento em que cada coisa acontece, por cópia: os argumentos e o resultado de uma ferramenta são copiados como JSON quando a chamada volta, o que custa a um resultado de 25 KB 0,05 ms no percentil 95; o digest é calculado depois, no envio. Quando um resultado existe em duas formas, as duas são gravadas: a que o modelo viu (result_model) e a que a interface recebeu (result_ui). Um gerador é gravado depois de consumido por inteiro. A captura nunca atrasa a resposta: o envio acontece depois e à parte do turno, e uma falha na gravação marca o registro completeness: incomplete sem tocar no agente.
turn_id é criado quando o turno começa e segue o turno através de tarefas assíncronas e sessões filhas, então toda chamada feita em nome dele cai no mesmo registro; em Python, um framework que roda ferramentas num pool de threads usa niadra.turns.bind(fn), e em TypeScript o turno em andamento segue o AsyncLocalStorage. Os adaptadores de framework abrem e fecham o turno por você com turns=True (turns: true): Google ADK, OpenAI Agents, LangGraph e LangChain em Python; LangChain e LangGraph, Mastra, o Vercel AI SDK, OpenAI Agents JS, Google ADK e VoltAgent em TypeScript. Uma ferramenta envolvida com tool() dentro de uma ferramenta do framework toma a chamada que o adaptador já gravou, então cada chamada é gravada uma vez; num replay, as ferramentas do LangGraph, do Google ADK e do Mastra respondem do registro, e as do OpenAI Agents e do VoltAgent precisam estar envolvidas com tool(), porque os ganchos deles não param uma ferramenta. Uma chamada de modelo é gravada pelo adaptador que vê os tokens dela. provenance transforma o resultado de uma ferramenta nos objetos que ele mostrou, cada um com a referência, os campos e a proveniência; sem proveniência, uma observação é só para exibição e nunca atualiza o estado tipado.
O registro também guarda o que o turno leu da memória, pela versão (o contexto pelo ETag, um bloco pela versão dele), as decisões de coordenação em que se apoiou e os efeitos com o estado de cada um, o que a pessoa viu ou fez (as interações) e os vereditos do contrato de afirmação. O que o turno disse não é repetido: output.event_keys aponta para os eventos que track() já enviou.
A build e os pinos
build.pins guarda o que precisa ser igual para um replay reproduzir o turno: prompts (nome e versão de cada prompt), corpus_digest (um digest dos arquivos que o agente consulta, calculado por você, nunca os arquivos), model (o modelo exato), assembler (a versão do seu montador de contexto) e tool_schemas (o digest do esquema de cada ferramenta). O SDK preenche sozinho os pinos da Niadra: a versão do compilador de contexto e o hash do pacote que o turno leu. O documento recording diz quais pinos são exigidos (prompts e model por padrão); um turno sem um deles é guardado, marcado como não reproduzível, e o SDK avisa uma vez.
Modos de conteúdo
O modo é configuração do espaço, por fonte, e o SDK o segue. Um blob é um valor grande do registro: os argumentos de uma ferramenta, um resultado, o texto de uma leitura, um documento que o turno escreveu.
Uma fonte pode sempre mandar um modo que guarda menos, nunca mais: um turno recusado com
content_mode_refused sai de novo só com digests. O digest é sha256: e o SHA-256 do JSON canônico do valor (RFC 8785), então o mesmo valor tem o mesmo digest em qualquer produtor, e um replay casa as chamadas pelo args_hash dos argumentos normalizados. Um turno grande demais é enviado com os blobs reduzidos a hashes, então um 413 turn_too_large nunca entra em laço. Um registro em pointer ou hash_only é aceito mesmo com o armazenamento da Niadra indisponível, porque o quadro é tudo o que ele tem. Veja Só metadado.
Fidelidade e completude
completeness diz quanto do turno está no registro: complete, partial (o SDK descartou blobs para proteger a fila; o quadro fica), incomplete (a gravação falhou durante o turno) ou unknown (um registro bronze).
A fila e o envio
Os turnos têm fila própria, separada da fila de eventos, limitada por bytes (64 MB por padrão) e por quantidade (2.000 turnos). Quando ela enche, o SDK descarta primeiro os blobs dos turnos sem marca, do mais antigo para o mais novo, marcando os registrospartial, e só depois os quadros mais antigos inteiros; os dois são contados. Um turno marcado fica com os blobs por mais tempo, porque é ele que alguém vai reproduzir. O envio vai em lotes de até 50 registros e 4 MB comprimidos, por POST /v1/turns, com o escopo track; a resposta é 200 quando todos entraram, 207 com um erro por registro recusado. Um turno que a Niadra já tem, pelo turn_id, é duplicata: o mesmo turno enviado duas vezes é um turno só. Um processo de escrita segura poucos corpos grandes (acima de 1 MB, enviados ou descomprimidos) ao mesmo tempo; passado esse limite, o lote volta com 429 e Retry-After, e o SDK o manda de novo.
O mesmo código está em examples/turn_records.py e, em TypeScript, em examples/claim-guard.ts, que abre o turno e passa a resposta pelo contrato de afirmação.
Camadas e promoção
Todo turno fica na camada curta. Um turno também é copiado para a camada guardada, a que a busca e o replay leem, por um de três motivos: uma marca posta na captura (error, guard_acted, handoff, assertion_failed, synthetic, incomplete ou negative_feedback), um pedido posterior, por POST /v1/turns/promote, nomeando uma conversa ou ids de turno com o motivo (complaint, bug_report, review ou other), porque a reclamação chega dias depois do turno, ou a amostra determinística de conversas inteiras. Nenhuma camada expira sozinha: um registro fica até um apagamento ou até a retenção que você definir em recording.kept_days (no mínimo 7 dias, sem máximo), que vale para as duas camadas; passado esse prazo, nada do turno resta além dos totais do dia, que não nomeiam ninguém. Os turnos de um cenário de replay seguem scenario_days, também sem prazo quando não definido. Uma retenção legal mantém os turnos de uma conversa fora do expurgo até ser liberada.
O webhook turn.flagged sai para cada turno guardado por uma marca, para os endpoints que o assinam: só ids e as marcas, nunca o que o turno disse ou leu.
O visualizador
No Console, a tela Turnos dos agentes lista os turnos guardados, do mais novo para o mais antigo, e abre cada um: o que leu, chamou, afirmou e disse, com as marcas, os pinos ereplay_blockers, por que o turno não pode ser reproduzido quando não pode (content_mode hash_only, fidelidade bronze ou silver, completude partial, incomplete ou unknown, ou um pino exigido que falta). Pela API, GET /v1/turns/{turn_id} e POST /v1/turns/search, com o id da conversa no corpo, pedem uma chave com o escopo replay ou uma pessoa com o papel integration ou security.
Replay
Um cenário guarda até 50 turnos com as asserções que eles devem continuar passando; o seu CI roda cada turno N vezes com a build fixada, dentro da sua empresa, e a Niadra decide o veredito estatístico. As ferramentas respondem do registro, os valores nunca saem, e o resultado nunca é enviado como turno. Veja Replay no seu CI.Custo e orçamento
Cada registro leva o custo do turno em dólares e os tokens de cada chamada de modelo. O blocobudget de uma leitura de contexto (include: ["budget"]) mostra o que o pacote custa em tokens estimados, por seção, e o que os turnos gravados deste agente já somaram na conversa ou no caso (turnos, chamadas de modelo e de ferramenta, tokens de entrada, do cache e de saída, custo); counted: false diz que os contadores não puderam ser lidos, e um número que falta nunca é zero. O bloco é mostrado, nunca imposto. O aproveitamento traz em cost chamadas, tokens e dinheiro por turno, por fonte e agente, contra o custo sem memória que a sua empresa mediu e declarou no documento measurement.
Privacidade
- O registro repete nenhum texto da conversa:
output.event_keysaponta para os eventos. - No modo
pointer, nenhum valor gravado chega à Niadra; nohash_only, nenhum valor é gravado. - A Niadra nunca põe um id de conversa numa URL nem numa chave de armazenamento em claro: os turnos ficam sob um hash com chave da conversa, e o apagamento de uma pessoa apaga os turnos dela por esse prefixo.
- Os registros servem à finalidade
quality, com a retenção da camada. Uma retenção legal os segura; apagado o titular,retainedno comprovante conta os turnos que uma retenção ainda mantém. - O índice da camada guardada entra na sua cadeia de auditoria: cada linha guardada tem uma entrada (id, fonte, agente, tipo, hora, modo, hash da build) com um digest SHA-256, as linhas de um dia UTC formam uma raiz de Merkle, e o evento diário
audit.roota leva comoturns.root, ao lado da raiz dos comprovantes.GET /v1/turns/index/{day}lista as linhas com os digests para a sua empresa recalcular a raiz; uma linha que vence ou é apagada depois deixa a raiz ancorada como estava.
Próximos passos
Replay no seu CI
cenários, asserções e o veredito estatístico.
Só metadado
o modo
pointer: os valores no seu bucket.Afirmações
os vereditos que cada turno carrega.
Registrar turnos
a referência de
POST /v1/turns.
