diff --git a/README.md b/README.md index b283545..efe729b 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,93 @@ Este tutorial orienta um time de desenvolvimento a implementar guardrails usando O projeto entregue junto com este tutorial foi gerado com base na planilha `Guardrails e Curadoria v3 - Consolidado.xlsx`, que define guardrails, curadoria, supervisores e LLM-as-a-judge. -## 2. Conceitos principais +## 2. Disclaimer de Uso e Responsabilidade -### 2.1 Guardrail +Este material, incluindo códigos-fonte, exemplos, estruturas de projeto e definições de arquitetura, foi desenvolvido exclusivamente para fins educacionais, ilustrativos e de referência conceitual, com o objetivo de demonstrar possíveis abordagens para implementação de guardrails, supervisores e mecanismos de avaliação (judge) em sistemas baseados em inteligência artificial. + +>**Nota Importante:** O objetivo principal é ilustrar e exemplificar como estruturar um modelo de configuração para o uso do Nemo Guardrails. + +O conteúdo apresentado neste tutorial não constitui uma solução pronta para produção, nem deve ser interpretado como recomendação definitiva de arquitetura, implementação ou governança. + +### 2.1 Natureza do código apresentado + +Os códigos fornecidos: + +Representam exemplos simplificados para ilustrar o funcionamento dos conceitos propostos; +Incluem implementações determinísticas (regex, regras Python) e exemplos com uso de modelos de linguagem (LLM); +Não contemplam todos os cenários reais de negócio, segurança, escalabilidade, resiliência ou compliance; +Podem conter limitações, simplificações ou omissões intencionais, necessárias para fins didáticos. + +### 2.2 Ausência de suporte e garantia + +Ao utilizar este material, o leitor declara estar ciente de que: + +Não há qualquer garantia de funcionamento, desempenho ou adequação para uso em ambientes produtivos; +Não é oferecido suporte técnico, manutenção, correções ou atualizações para os códigos apresentados; +Nem o autor, nem a empresa associada, assumem responsabilidade por: +falhas de execução +impactos financeiros +problemas legais ou regulatórios +incidentes de segurança ou vazamento de dados +decisões tomadas com base nos exemplos fornecidos + +### 2.3 Responsabilidade do leitor + +Cabe exclusivamente ao leitor: + +Avaliar criticamente a adequação dos exemplos ao seu contexto específico; +Adaptar, evoluir e validar o código conforme: +requisitos de negócio +requisitos legais e regulatórios +políticas de segurança da informação +necessidades de desempenho e escalabilidade +Realizar testes completos antes de qualquer uso em produção; +Garantir conformidade com legislações aplicáveis (ex: LGPD, regulamentações setoriais, etc.). + +### 2.4 Considerações sobre performance e latência + +O material inclui exemplos que utilizam: + +chamadas a modelos LLM +validações semânticas +múltiplas camadas de controle (guardrails, supervisor, judge) + +Esses elementos podem introduzir impactos significativos de latência e custo, especialmente em ambientes reais. + +Portanto: + +A arquitetura proposta deve ser criteriosamente avaliada quanto a: +tempo de resposta +custo por requisição +volume de chamadas ao modelo +Recomenda-se a adoção de estratégias como: +priorização de regras determinísticas (Python/regex) +execução assíncrona de avaliações (judge batch) +cache e otimizações de fluxo + +### 2.5 Sobre Supervisor e Judge + +Os componentes de Supervisor e LLM-as-a-Judge apresentados: + +São implementações meramente ilustrativas; +Não representam modelos completos de auditoria, governança ou avaliação de qualidade; +Devem ser tratados como pontos de partida conceituais, e não como soluções finais. + +### 2.6 Uso em ambiente produtivo + +A utilização deste material em ambientes produtivos: + +É de inteira responsabilidade do leitor ou da organização que o adotar; +Exige: +revisão técnica aprofundada +testes extensivos +validação de segurança +definição de SLAs e observabilidade +governança adequada de IA + +## 3. Conceitos principais + +### 3.1 Guardrail Guardrail é uma proteção aplicada ao fluxo de IA. Pode bloquear, mascarar, rejeitar, reescrever, auditar ou medir uma interação. @@ -21,7 +105,7 @@ Neste projeto, os guardrails foram separados em quatro famílias: | Python rail | Regra de negócio determinística | Alçada de Ajuste, Histórico | | Supervisor / Judge | Auditoria pós-fluxo ou batch | Supervisor VAS Avulso, Qualidade, Alucinação | -### 2.2 Input Rail +### 3.2 Input Rail Executa antes do LLM. Serve para proteger o modelo contra entrada tóxica, fora de escopo, dados sensíveis, jailbreak ou pedidos indevidos. @@ -31,7 +115,7 @@ Na planilha: - Toxicidade - Out-of-Scope -### 2.3 Output Rail +### 3.3 Output Rail Executa depois que o LLM gera uma resposta, mas antes de devolver ao usuário ou executar uma ação. @@ -41,7 +125,7 @@ Na planilha: - Verbalização Prematura - Groundedness -### 2.4 Python pré-execução +### 3.4 Python pré-execução Nem toda regra deve ir para o LLM. Regras financeiras, alçada, duplicidade de crédito e consistência histórica devem ficar em Python ou em serviço de negócio. @@ -52,7 +136,7 @@ if valor_ajuste > limite: escalar_para_ath() ``` -### 2.5 Supervisor +### 3.5 Supervisor Supervisor é uma camada independente que audita o fluxo já executado. Ele não substitui guardrails. Ele verifica se a jornada foi correta. @@ -62,7 +146,7 @@ Na planilha: - Avalia se o cancelamento foi feito corretamente - Retorna `CONFORME`, `SUSPEITO` ou `PROBLEMA` -### 2.6 LLM-as-a-judge +### 3.6 LLM-as-a-judge É uma avaliação normalmente batch, pós-sessão, para medir qualidade, tom, alucinação, satisfação e aderência à rubrica. @@ -73,7 +157,30 @@ Na planilha: - Qualidade da Resposta - Tom de Voz -## 3. Arquitetura recomendada +## 4. Arquitetura utilizada + +Este fluxo representa uma arquitetura estruturada para controle, validação e governança de sistemas baseados em LLM, combinando: + +Guardrails (proteção e controle em tempo real) +Regras determinísticas (Python/regex) +Supervisão de jornada +Curadoria e métricas +Execução integrada com sistemas reais (APIs/backend) + +O objetivo principal é ilustrar um sistema que: + +- opere dentro de limites seguros e definidos +- evite riscos (jurídicos, financeiros, reputacionais) +- mantenha qualidade e consistência nas respostas +- seja observável e mensurável +- possa evoluir de forma controlada + +O fluxo separa claramente responsabilidades entre: + +- bloqueio (guardrails) +- execução (LLM + backend) +- validação (supervisor) +- medição (curadoria/judge) ```text User Input @@ -108,7 +215,219 @@ Curadoria / Métricas Resposta final ``` -## 4. Estrutura do projeto +### 4.1. User Input + +Entrada inicial do usuário, que pode vir de múltiplos canais: + +- chat (web, app) +- voz (via STT) +- APIs externas + +Riscos nesta etapa: + +- entrada maliciosa (prompt injection) +- dados sensíveis (PII) +- linguagem ofensiva ou fora de escopo + + Por isso, nunca deve ser enviada diretamente ao LLM sem tratamento. + +### 4.2. Input Rails + +Camada de proteção antes do LLM. + +Regex: PII Masking + +Remove ou mascara dados sensíveis: + +- CPF +- cartão +- senhas +- tokens + +Objetivo: + +- evitar vazamento de dados +- proteger logs e chamadas ao LLM + + + É rápido, barato e determinístico → sempre deve vir primeiro. + +LLM: Toxicidade +Avalia se o conteúdo contém: +insultos +linguagem ofensiva +discurso inadequado + +Objetivo: + +- manter neutralidade +- proteger a aplicação de respostas indevidas + + + Pode bloquear ou redirecionar o fluxo. + +LLM: Out-of-Scope + +Verifica se a pergunta está dentro do domínio do sistema + +Objetivo: + +- evitar respostas erradas +- reduzir alucinação +- manter foco no negócio + +Exemplo: + + evitar responder perguntas fora do escopo da operadora. + +### 4.3. LLM Principal via NeMo Guardrails + +É o cérebro do sistema, responsável por: + +- interpretar intenção +- gerar resposta +- planejar ações +- integrar com RAG (quando aplicável) + +Aqui já existem proteções internas do NeMo: + +fluxos de rails (input/output) +instruções controladas + + Mesmo assim, não é confiável sozinho, por isso existem as outras camadas. + +### 4.4. Output Rails + +Executam após a resposta do LLM, antes de retornar ao usuário ou executar ações. + +Compliance Anatel + +Garante aderência a regras regulatórias + +Exemplo: + + respostas de ajuste devem conter protocolo + +Evita: + +- problemas jurídicos +- não conformidade regulatória + +Verbalização Prematura +Impede promessas antes da validação + +Exemplo proibido: + + “Seu ajuste já foi aplicado” + +Antes de: + +- validação +- execução real no backend + +Evita inconsistência e risco operacional. + +Groundedness + +Verifica se a resposta está baseada em: +- dados reais +- contexto fornecido +- RAG + +Objetivo: + +- reduzir alucinação +- garantir confiabilidade + +### 4.5. Python Rules (Pré-execução determinística) + +Aqui entram regras críticas que não devem depender de LLM. + +- Alçada de Ajuste +- Verifica limites financeiros ou operacionais + +Exemplo: + + if valor > limite: + bloquear() + +Evita: + +- prejuízo financeiro +- decisões fora de política +- Consistência Histórica + +Valida histórico do cliente: + +Exemplo: + + múltiplos ajustes repetidos + inconsistências de dados + +Protege contra: + +- fraude +- erro de sistema + +### 4.6. Execução de API / Backend + +Momento em que o sistema: + +- chama serviços reais +- executa operações +- integra com: + - CRM + - billing + - sistemas legados + + +### 4.7. Supervisor VAS Avulso + +Camada de auditoria da jornada, após execução. + +Função: + +- verificar se tudo ocorreu corretamente + +Pode avaliar: + +- coerência da decisão +- aderência às regras +- consistência entre intenção e ação + +Retorna algo como: + +- CONFORME +- SUSPEITO +- PROBLEMA + +>**Importante:** Supervisor não bloqueia → ele audita e sinaliza + +### 4.8. Curadoria / Métricas + +Camada de observabilidade e evolução do sistema. + +TCR (Task Completion Rate) +- Mede se a tarefa foi concluída com sucesso + +Fallback +- Quantas vezes o sistema falhou ou escalou + +Tokens +- Consumo de tokens do LLM + +Impacta custo diretamente + +- Tamanho de mensagem +- Controle de payload e eficiência +- Eficiência RAG +- Mede qualidade da recuperação de contexto + +Exemplo: + + respostas baseadas em conteúdo correto vs errado + +## 5. Estrutura do projeto ```text nemo_guardrails_tracing_project/ @@ -133,9 +452,9 @@ nemo_guardrails_tracing_project/ └── README.md ``` -## 5. Preparação do ambiente +## 6. Preparação do ambiente -### 5.1 Criar ambiente Python +### 6.1 Criar ambiente Python ```bash python -m venv .venv @@ -143,7 +462,7 @@ source .venv/bin/activate pip install -r requirements.txt ``` -### 5.2 Configurar variáveis +### 6.2 Configurar variáveis ```bash cp .env.example .env @@ -164,7 +483,7 @@ ALCADA_MAX_AJUSTE=50 >**Nota Importante:** O Nemo Guardrails possui compatibilidade apenas com a API da OpenAI. É possível utilizar-se de modelos que não tenham compatibilidade com API OpenAI, bastando para isso utilizar-se do proxy OCI OpenAI desta documentação: [https://github.com/hoshikawa2/nemo_guardrails_oci_generative_ai](https://github.com/hoshikawa2/nemo_guardrails_oci_generative_ai) -## 6. Configuração do NeMo Guardrails +## 7. Configuração do NeMo Guardrails Arquivo: `config/config.yml` @@ -189,9 +508,11 @@ rails: - self check output ``` -## 7. Rails criados a partir da planilha +## 8. Rails criados a partir da planilha -### 7.1 MSK — PII Masking +Segue abaixo a estruturação dos exemplos para o entendimento do funcionamento da tecnologia. + +### 8.1 MSK — PII Masking Implementação: `src/deterministic_rails.py` @@ -203,25 +524,25 @@ PASSWORD_RE = re.compile(r"(?i)(senha|password|token|api[_-]?key)\s*[:=]\s*\S+") Objetivo: mascarar CPF, cartão, senha, token e credenciais antes de enviar ao LLM e antes de logar. -### 7.2 CMP — Compliance Anatel +### 8.2 CMP — Compliance Anatel Implementação: `enforce_compliance_anatel()` Regra: respostas de ajuste precisam conter número de protocolo. -### 7.3 ADJ — Alçada de Ajuste +### 8.3 ADJ — Alçada de Ajuste Implementação: `validar_alcada()` Regra: se o valor do ajuste exceder `ALCADA_MAX_AJUSTE`, o fluxo é bloqueado e escalado para atendimento humano. -### 7.4 REVPREC — Verbalização Prematura +### 8.4 REVPREC — Verbalização Prematura Implementação: `verbalizacao_prematura()` Regra: o agente não pode prometer ajuste, crédito ou cancelamento antes de validação. -### 7.5 Supervisor VAS Avulso +### 8.5 Supervisor VAS Avulso Implementação: `src/supervisor.py` @@ -233,7 +554,9 @@ Avalia cinco regras: 4. Não houve exposição de PII. 5. A decisão está coerente com os dados de contexto. -## 8. Integração com proxy OpenAI-Compatible +## 9. Integração com proxy OpenAI-Compatible + +A tecnologia Nemo Guardrails permite a integração com modelos LLM, porém apenas aqueles que sejam compatíveis com a estrutura OpenAI API. O projeto usa o cliente `openai` apontando para seu proxy: @@ -253,7 +576,11 @@ export OPENAI_API_KEY=dummy export OPENAI_MODEL=gpt-4.1 ``` -## 9. Tracing com OpenTelemetry / Phoenix +>**Nota:** Caso o projeto necessite utilizar modelos LLM não-compatíveis com OpenAI API, veja em referências como utilizar uma camada proxy para integrar com modelos locais ou Oracle Cloud Generative AI + +## 10. Tracing com OpenTelemetry / Phoenix + +Segue aqui exemplo para integrar com plataforma de observabilidade utilizando o OpenTelemetry e Phoenix. Arquivo: `src/tracing.py` @@ -273,9 +600,42 @@ export ENABLE_TRACING=true export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:6006/v1/traces ``` -## 10. Como executar o projeto +### 10. 1 Subindo OpenTelemetry + Phoenix para Tracing de LLM -### 10.1 Teste demonstrável sem proxy +O Arize Phoenix é uma ferramenta de observabilidade focada em aplicações de IA. Neste tutorial, servirá apenas como modelo para se ter uma idéia de como integrar com uma plataforma de observabilidade. + +Instale: + + pip install arize-phoenix + pip install opentelemetry-sdk + pip install opentelemetry-exporter-otlp + pip install opentelemetry-instrumentation + +Suba o servidor: + + phoenix serve + +Ele permite visualizar: + +- spans (cada etapa do fluxo) +- latência por componente +- entradas e saídas do LLM +- erros e falhas +- fluxo completo da execução + +UI disponível em: + + http://localhost:6006 + +Endpoint OTLP (para envio de traces): + + http://localhost:6006/v1/traces + +![img_2.png](img_2.png) + +## 11. Como executar o projeto + +### 11.1 Teste demonstrável sem proxy ```bash export USE_MOCK_LLM=true @@ -296,7 +656,7 @@ Resultado esperado: } ``` -### 10.2 Executar testes automatizados +### 11.2 Executar testes automatizados ```bash pytest -q @@ -310,7 +670,7 @@ Os testes comprovam: - Verbalização prematura é bloqueada. - Fluxo completo funciona em modo mock. -### 10.3 Executar com proxy real +### 11.3 Executar com proxy real ```bash export USE_MOCK_LLM=false @@ -329,7 +689,7 @@ bash scripts/run_tests.sh ![img_1.png](img_1.png) -## 11. Mapeamento da planilha para implementação +## 12. Mapeamento da planilha para implementação | Código | Item | Mecanismo | Implementação entregue | |---|---|---|---| @@ -348,17 +708,17 @@ bash scripts/run_tests.sh | RQLT | Qualidade da Resposta | LLM-as-a-judge | previsto como batch D-1 | | VCTN | Tom de Voz | LLM-as-a-judge | previsto como batch D-1 | -## 12. Recomendações para o time +## 13. Recomendações para o time -### 12.1 Não colocar tudo no LLM +### 13.1 Não colocar tudo no LLM Use Python para regras determinísticas e financeiras. Use LLM rails para semântica, linguagem, escopo e groundedness. -### 12.2 Separar bloqueio de medição +### 13.2 Separar bloqueio de medição Guardrail bloqueia. Curadoria mede. Supervisor audita. Judge avalia em lote. -### 12.3 Começar por P0 +### 13.3 Começar por P0 Primeira entrega sugerida: @@ -369,7 +729,7 @@ Primeira entrega sugerida: 5. TCR 6. Verbalização Prematura -### 12.4 Evoluir para P1 +### 13.4 Evoluir para P1 Depois: @@ -381,7 +741,7 @@ Depois: 6. Eficiência NLU 7. No-Match RAG -## 13. Critérios de aceite +## 14. Critérios de aceite O time deve comprovar: @@ -393,7 +753,7 @@ O time deve comprovar: - Métricas de curadoria são geradas. - Spans aparecem no backend de tracing. -## 14. Evolução futura +## 15. Evolução futura A estrutura permite evoluir para: @@ -405,9 +765,21 @@ A estrutura permite evoluir para: - Phoenix / Langfuse / OpenTelemetry. - Governança por catálogo de guardrails. -## 15. Referências +## 16. Referências -- NVIDIA NeMo Guardrails: documentação oficial. -- Python SDK: `RailsConfig.from_path()` e `LLMRails.generate()`. -- Colang: linguagem para definir fluxos de guardrails. -- OpenTelemetry: tracing distribuído por spans. +### NVIDIA NeMo Guardrails: documentação oficial. + +- [NeMo Guardrails Library Configuration Overview](https://docs.nvidia.com/nemo/guardrails/latest/configure-rails/overview.html) +- [Tools Integration with the NeMo Guardrails Library](https://docs.nvidia.com/nemo/guardrails/latest/integration/tools-integration.html) + +### OpenTelemetry: tracing distribuído por spans. +- [Logging and Debugging Guardrails Generated Responses](https://docs.nvidia.com/nemo/guardrails/latest/observability/logging/index.html) +- [Quick Start for Tracing Guardrails](https://docs.nvidia.com/nemo/guardrails/latest/observability/tracing/quick-start.html) + +### Utilizando modelos não-compatíveis com OpenAI + +- [Integrating OpenClaw with Oracle Cloud Generative AI (OCI)](https://github.com/hoshikawa2/openclaw-oci) + +## 17. Acknowledgments + +- **Author** - Cristiano Hoshikawa (Oracle LAD A-Team Solution Engineer) diff --git a/img_2.png b/img_2.png new file mode 100644 index 0000000..d4b9393 Binary files /dev/null and b/img_2.png differ diff --git a/nemo_guardrails_tracing_project/src/tracing.py b/nemo_guardrails_tracing_project/src/tracing.py index 1ec7a3e..849a619 100644 --- a/nemo_guardrails_tracing_project/src/tracing.py +++ b/nemo_guardrails_tracing_project/src/tracing.py @@ -1,21 +1,64 @@ import os from contextlib import contextmanager -_TRACING_ENABLED=os.getenv("ENABLE_TRACING","false").lower()=="true" -try: - if _TRACING_ENABLED: + +_TRACING_ENABLED = os.getenv("ENABLE_TRACING", "false").lower() == "true" + +tracer = None + +if _TRACING_ENABLED: + try: from opentelemetry import trace from opentelemetry.sdk.trace import TracerProvider + from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter - provider=TracerProvider(); endpoint=os.getenv("OTEL_EXPORTER_OTLP_ENDPOINT","http://localhost:6006/v1/traces") - provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter(endpoint=endpoint))) - trace.set_tracer_provider(provider); tracer=trace.get_tracer("nemo_guardrails_governed_project") - else: tracer=None -except Exception: tracer=None + + endpoint = os.getenv( + "OTEL_EXPORTER_OTLP_ENDPOINT", + "http://localhost:6006/v1/traces" + ) + + # ✅ Define metadata do serviço (IMPORTANTE pro Phoenix) + resource = Resource.create({ + "service.name": "nemo_guardrails_governed_project" + }) + + provider = TracerProvider(resource=resource) + + exporter = OTLPSpanExporter( + endpoint=endpoint, + timeout=5 # evita travamentos + ) + + span_processor = BatchSpanProcessor(exporter) + provider.add_span_processor(span_processor) + + # ✅ Evita sobrescrever provider existente + if not isinstance(trace.get_tracer_provider(), TracerProvider): + trace.set_tracer_provider(provider) + + tracer = trace.get_tracer(__name__) + + except Exception as e: + print(f"[Tracing Disabled] Error initializing tracing: {e}") + tracer = None + + @contextmanager -def span(name:str, **attrs): +def span(name: str, **attrs): if tracer is None: - yield None; return - with tracer.start_as_current_span(name) as sp: - for k,v in attrs.items(): sp.set_attribute(k,str(v)) - yield sp + yield None + return + + try: + with tracer.start_as_current_span(name) as sp: + for k, v in attrs.items(): + # ✅ mantém tipo quando possível + if isinstance(v, (str, int, float, bool)): + sp.set_attribute(k, v) + else: + sp.set_attribute(k, str(v)) + yield sp + except Exception as e: + print(f"[Tracing Error] Span '{name}' failed: {e}") + yield None \ No newline at end of file