Files
pastor-online/.env.example
T
omp 816e6be159 feat: cota lexical na fusão, recusa off-topic no prompt, docs medidas
Fusão:
- fuse_rankings() extrai a fusão RRF e aplica MAX_KEYWORD_ONLY (padrão 2):
  quantas posições podem ser ocupadas por trechos que só o BM25 achou. O que os
  dois lados confirmam nunca conta contra a cota.
- O controle é por cota de posições, não por piso de nota. Medido: a razão da
  nota BM25 não separa acerto de ruído — para 'como posso perdoar quem me
  feriu?', Deuteronômio 28:27 pontua 1,000 do topo e o correto Lucas 7:47 fica
  em 0,716 (rank 12). Um piso cortaria o certo e manteria o errado.
- Ponderar o RRF também não resolve: com peso 0,5 no BM25 os achados só-lexicais
  caem abaixo do 6º vetorial (0,5/61 < 1/66) e somem, levando junto Jó 3:13 e
  Joel 3:14, os melhores resultados medidos.

Portão off-topic:
- MIN_SIMILARITY não consegue implementar 'sem evidência'. Medido no índice
  completo: 0/6 perguntas off-topic bloqueadas em qualquer limiar de 0,30 a
  0,50 ('bolo de chocolate' bate 0,544 em Lv 7:14; 'cotação do dólar' 0,494).
  A recusa passa a ser instruída no SYSTEM_PROMPT e o limiar fica documentado
  como filtro de ruído.
2026-11-02 13:04:14 -03:00

82 lines
3.4 KiB
Bash

# ---------------------------------------------------------------------------
# Pastor Online — configuração
# Copie este arquivo para `.env` e ajuste os valores:
# cp .env.example .env
# ---------------------------------------------------------------------------
# Porta do frontend no host (http://localhost:8080)
FRONTEND_PORT=8080
# ---------------------------------------------------------------------------
# Provedor de LLM: ollama | openai | groq | anthropic
# ---------------------------------------------------------------------------
LLM_PROVIDER=ollama
# --- Ollama (local, requer o profile "local": docker compose --profile local up) ---
OLLAMA_BASE_URL=http://ollama:11434
OLLAMA_MODEL=qwen2.5:1.5b
# --- OpenAI ---
OPENAI_BASE_URL=https://api.openai.com/v1
OPENAI_MODEL=gpt-4o-mini
OPENAI_API_KEY=
# --- Groq (compatível com a API da OpenAI) ---
GROQ_BASE_URL=https://api.groq.com/openai/v1
GROQ_MODEL=llama-3.3-70b-versatile
GROQ_API_KEY=
# --- Anthropic ---
ANTHROPIC_BASE_URL=https://api.anthropic.com
ANTHROPIC_MODEL=claude-sonnet-4-5
ANTHROPIC_API_KEY=
# ---------------------------------------------------------------------------
# Embeddings (CPU)
# paraphrase-multilingual-MiniLM-L12-v2: multilíngue, ~470 MB
# all-MiniLM-L6-v2: menor e mais rápido, ~90 MB, apenas inglês
# ---------------------------------------------------------------------------
EMBEDDING_MODEL=paraphrase-multilingual-MiniLM-L12-v2
# ---------------------------------------------------------------------------
# Busca
# A recuperação é híbrida: similaridade vetorial + BM25 (com stemming), fundidos
# por posição (RRF).
#
# MIN_SIMILARITY é filtro de ruído do lado vetorial, NÃO um detector de assunto
# fora do tema. Medido no corpus completo: nenhum valor entre 0,30 e 0,50
# bloqueou uma pergunta off-topic ("como fazer um bolo de chocolate" bate 0,544
# em Levítico 7:14). Num corpus de 31 mil versículos sempre há algum acima de
# qualquer limiar; a recusa off-topic é instruída ao modelo no SYSTEM_PROMPT.
#
# MAX_KEYWORD_ONLY: posições da resposta que podem ser ocupadas por trechos que
# só o BM25 achou. A nota BM25 não separa acerto de ruído (Deuteronômio 28:27
# pontua 1,000 do topo para "como posso perdoar", e o correto Lucas 7:47 fica em
# 0,716), então o controle é por cota de posições. 0 desliga o lado lexical.
# ---------------------------------------------------------------------------
TOP_K=6
MIN_SIMILARITY=0.35
MAX_KEYWORD_ONLY=2
# ---------------------------------------------------------------------------
# Ingestão do corpus
# Diretório com os arquivos USFX (*.xml), montado somente-leitura em /data/corpus.
# INDEX_BATCH_SIZE: versículos gravados no banco vetorial por lote.
# CONTEXT_WINDOW: vizinhos indexados junto com cada versículo. Um versículo
# isolado é curto demais para o embedding captar o tema; a referência exibida
# continua sendo a do versículo central.
# ---------------------------------------------------------------------------
# CORPUS_DIR=/data/corpus
INDEX_BATCH_SIZE=512
CONTEXT_WINDOW=2
# ---------------------------------------------------------------------------
# API
# CORS_ORIGINS=http://localhost:8080,http://127.0.0.1:8080
# REINDEX_TOKEN=troque-por-um-segredo
# AUTO_INDEX=true
# ---------------------------------------------------------------------------
CORS_ORIGINS=http://localhost:8080,http://127.0.0.1:8080
REINDEX_TOKEN=
AUTO_INDEX=true