ac_qual_code() classifica os textos de um ac_corpus de acordo com um
ac_codebook, usando um modelo de linguagem via ellmer. Retorna um tibble
com a classificação, grau de certeza (via self-consistency) e raciocinio
da LLM para cada documento.
E o motor de classificação do pipeline qualitativo do acR. Assume
que o codebook já foi construido com ac_qual_codebook() e (idealmente)
testado numa amostra piloto. A saida e sempre validada com
ac_qual_reliability() contra uma amostra codificada por humano –
nenhuma análise categorial publicável dispensa essa etapa.
Tres parametros determinam qualidade e custo:
k_consistency: número de rodadas de self-consistency (Wang et al., 2023). O mesmo texto e classificado k vezes com pequena variacao de temperatura, e a categoria final e a moda. Oconfidence_scoresai dessa concordância – 1,0 significa que todas as k rodadas concordaram. Padraok = 3custa 3x mais tokens que uma rodada única, e e a configuracao mínima para reportar confianca de forma defensavel.reasoning: pede raciocinio estruturado. Melhora a qualidade em casos ambiguos mas praticamente dobra o custo por documento. Use"short"como padrao e"detailed"so quando planeja auditar decisoes individuais.live: tira a classificação do modo "caixa-preta" mostrando cada documento em tempo real. Numa rodada de 500 discursos, você percebe nos primeiros 10 se o codebook esta funcionando – antes de gastar todo o orcamento de tokens.
Usage
ac_qual_code(
corpus,
codebook,
model = "anthropic/claude-sonnet-4-5",
chat = NULL,
confidence = c("total", "by_variable", "both", "none"),
k_consistency = 3L,
temperature = 0.3,
reasoning = TRUE,
reasoning_length = c("short", "medium", "detailed"),
main_temperature = 0,
reasoning_extras = FALSE,
live = c("off", "terminal", "progress", "shiny"),
max_retries = 2L,
checkpoint_dir = NULL,
...
)Arguments
- corpus
Objeto
ac_corpus.- codebook
Objeto
ac_codebook, saida deac_qual_codebook().- model
Modelo LLM a usar. Aceita string no formato
"provedor/modelo"(ex:"anthropic/claude-sonnet-4-5","openai/gpt-4.1"), objetoChatdo pacoteellmerpre-configurado, ou função fabricafunction(temperature, system_prompt) Chatpara controle total sobre a construcao do chat a cada rodada. Quandochate fornecido,modele ignorado.- chat
Objeto
Chatdo pacoteellmer(ex:chat_google_gemini(),chat_openai(),chat_ollama()). Quando fornecido, tem prioridade sobremodel. Permite usar qualquer provedor suportado peloellmer.- confidence
Como calcular certeza:
"total"(padrao): uma colunaconfidence_scorecom a proporção de rodadas de self-consistency que concordaram com a categoria vencedora (moda);"by_variable": uma coluna<categoria>_confidencepor categoria do codebook, com a proporção de rodadas que escolheram aquela categoria especificamente (não so a vencedora) – util para montar uma matriz de confianca por tema/categoria;"both": as colunas por categoria +confidence_score(a da vencedora);"none": não calcula certeza (mais rápido, menor custo).
- k_consistency
Número de rodadas para self-consistency. Padrao:
3. Ignorado seconfidence = "none".- temperature
Temperatura das rodadas de consistency. Padrao:
0.3.- reasoning
Lógico. Se
TRUE(padrao), inclui colunaraciociniocom justificativa da classificação.- reasoning_length
Tamanho do raciocinio:
"short"(1 frase, padrao),"medium"(3 frases),"detailed"(paragrafo).- main_temperature
Temperatura da rodada principal (a que gera
categoria,categoria_labeleraciociniono resultado final). Padrao0(deterministica). Separado detemperature(usado so nas rodadas extras de self-consistency) porque os dois cumprem papeis diferentes: a rodada principal deve ser reprodutível, as extras devem variar para medir concordância.- reasoning_extras
Lógico. Se
TRUE, pede raciocinio também nas rodadas extras de self-consistency (mais caro, não usado no resultado final). PadraoFALSE.- live
Visualizacao em tempo real da classificação:
"off"(padrao): sem live view;"terminal": barra de progresso com doc atual, categoria, confianca e inicio do raciocinio a cada iteracao;"progress": barra de progresso enxuta (doc atual e status), sem ecoar categoria/raciocinio – util para rodadas grandes onde o terminal ficaria poluido;"shiny": abre janela Shiny em background com tabela atualizando conforme documentos sao classificados (requershinyecallr).
- max_retries
Número máximo de novas tentativas por rodada quando a chamada ao LLM falha (erro de rede, timeout, resposta invalida). Padrao
2. Espera exponencial entre tentativas (até 30s). Quando o erro e"limite_taxa"(HTTP 429), a espera segue a dica do provedor ("try again in 12s"), até 90s: em planos gratuitos comk_consistencyalto, aumentemax_retries. Quando o erro e classificado como"estouro_contexto", não ha nova tentativa (repetir não resolve). Se mais da metade dos últimos 5+ documentos falhar, a execucao e abortada com sugestao de usarcheckpoint_dir.- checkpoint_dir
Diretório para salvar o resultado de cada documento assim que classificado. Se já existir um checkpoint valido para um
doc_id(mesmoscodebook,model,k_consistencyetemperature), o documento e pulado e o resultado salvo e reutilizado – permite retomar uma rodada interrompida sem reclassificar tudo.NULL(padrao): sem checkpoint.- ...
Argumentos adicionais passados a
ellmer::chat(). Permite uso de APIs OpenAI-compatible self-hosted viabase_url.
Value
Tibble com colunas:
doc_id: identificador do documento;Metadados originais do corpus;
categoria: slug interno da categoria (chave da listacategoriesno codebook). Emmultilabel = TRUE, string pipe-separada sem espaco ("técnica|politica").categoria_label: rotulo humano correspondente, vindo do campolabelde cada categoria (se ausente, repete o slug). Em multilabel, unidos por" | "(espaco dos dois lados).confidence_score: grau de certeza da categoria vencedora (0-1). Presente quandoconfidencee"total"ou"both".confidence_level:"alta"(>= 0,80),"média"(>= 0,61) ou"baixa"– faixas convencionadas pelo pacote para resumirconfidence_score. Não vêm da literatura de confiabilidade: as faixas de Landis & Koch (1977) são para kappa, não para proporção de rodadas concordantes. A ideia de usar a concordância entre amostras como sinal de incerteza vem de Wang et al. (2023) e Xiong et al. (2024), que mostram que ela se correlaciona com acerto, mas não propõem cortes universais. Comk_consistency = 3, os valores possíveis são só 1/3, 2/3 e 1. Acompanhaconfidence_score.<categoria>_confidence: uma coluna por categoria do codebook (ex.:positivo_confidence,negativo_confidence), com a proporção de rodadas de self-consistency que escolheram aquela categoria. Presentes quandoconfidencee"by_variable"ou"both".raciocinio: justificativa da classificação (sereasoning = TRUE).status: resultado da rodada principal:"ok","resposta_invalida"(JSON não parseavel),"estouro_contexto","limite_taxa"(limite de requisições ou de tokens por minuto/dia do provedor, HTTP 429),"timeout"ou"erro_servidor".n_tentativas: número de tentativas até obterstatus = "ok"(ou até esgotarmax_retries).tokens_entrada,tokens_saida: tokens de entrada/saida da rodada principal, viachat$get_tokens()(NAse o provedor não expoe).segundos: tempo total da rodada principal, incluindo novas tentativas.tokens_por_segundo:tokens_saida / segundos.
O resultado carrega também um atributo run_info (ver
attributes()) com metadados da execucao: versoes de acR e
ellmer, modelo, base_url, parametros efetivos aplicados ao
provedor, temperaturas pedidas, k_consistency, hash do codebook e
timestamps de inicio/fim.
References
Wang, X. et al. (2023). Self-Consistency Improves Chain of Thought Reasoning in Language Models. International Conference on Learning Representations (ICLR).
Xiong, M. et al. (2024). Can LLMs Express Their Uncertainty? An Empirical Evaluation of Confidence Elicitation in LLMs. International Conference on Learning Representations (ICLR).
Landis, J. R.; Koch, G. G. (1977). The Measurement of Observer Agreement for Categorical Data. Biometrics, 33(1), 159-174.
Gilardi, F.; Alizadeh, M.; Kubli, M. (2023). ChatGPT Outperforms Crowd Workers for Text-Annotation Tasks. PNAS, 120(30).
Examples
if (FALSE) { # \dontrun{
cb <- ac_qual_codebook(
name = "tom",
instructions = "Classifique o tom do discurso.",
categories = list(
positivo = list(definition = "Tom propositivo e colaborativo."),
negativo = list(definition = "Tom crítico e confrontacional.")
)
)
df <- data.frame(
id = c("d1", "d2"),
texto = c("Proponho cooperacao.", "Este governo e um fracasso.")
)
corpus <- ac_corpus(df, text = texto, docid = id)
# Usando string de modelo (comportamento padrao)
coded <- ac_qual_code(corpus, cb, model = "anthropic/claude-sonnet-4-5")
# Usando objeto Chat do ellmer (recomendado para controle fino)
chat_obj <- ellmer::chat_google_gemini(model = "gemini-2.5-flash", echo = "none")
coded <- ac_qual_code(corpus, cb, chat = chat_obj)
# Groq (inferência rápida, plano gratuito)
chat_groq <- ellmer::chat_groq(model = "openai/gpt-oss-120b", echo = "none")
coded <- ac_qual_code(corpus, cb, chat = chat_groq)
# Ollama (modelos locais, sem envio de dados externos)
chat_local <- ellmer::chat_ollama(model = "llama3.2", echo = "none")
coded <- ac_qual_code(corpus, cb, chat = chat_local)
# confidence = "both": além de confidence_score (categoria vencedora),
# ganha uma coluna <categoria>_confidence por categoria do codebook --
# util para montar uma matriz de confianca por tema entre documentos
# ou comparar modelos na mesma tarefa.
coded_both <- ac_qual_code(corpus, cb, model = "anthropic/claude-sonnet-4-5",
confidence = "both")
coded_both[, c("doc_id", "categoria", "confidence_score",
"positivo_confidence", "negativo_confidence")]
} # }
