mirror of
https://github.com/hoshikawa2/nemo_guardrails_configuration.git
synced 2026-07-09 17:04:20 +00:00
Compare commits
3 Commits
dc58e8c19b
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 5db9799444 | |||
| 4388dc98c5 | |||
| 0237fff63c |
@@ -5,9 +5,12 @@ OPENAI_API_KEY=dummy
|
||||
OPENAI_MODEL=gpt-5
|
||||
|
||||
# Tracing / Phoenix / OpenTelemetry
|
||||
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:6006/v1/traces
|
||||
OTEL_SERVICE_NAME=nemo-guardrails-demo
|
||||
ENABLE_TRACING=true
|
||||
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:8087/api/public/otel/v1/traces
|
||||
export OTEL_SERVICE_NAME=nemo-guardrails-demo
|
||||
export ENABLE_TRACING=true
|
||||
export LANGFUSE_SECRET_KEY="sk-lf-0bb4d15d-6101-4874-991b-68780cf7b748"
|
||||
export LANGFUSE_PUBLIC_KEY="pk-lf-1b51d3b4-af8d-4b8b-8ac4-e81e6006123f"
|
||||
export LANGFUSE_BASE_URL="http://localhost:8087"
|
||||
|
||||
# Modo demo: usa cliente fake se o proxy não estiver disponível
|
||||
USE_MOCK_LLM=false
|
||||
|
||||
@@ -1,64 +1,142 @@
|
||||
import os
|
||||
import base64
|
||||
|
||||
from contextlib import contextmanager
|
||||
|
||||
_TRACING_ENABLED = os.getenv("ENABLE_TRACING", "false").lower() == "true"
|
||||
_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
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
endpoint = os.getenv(
|
||||
"OTEL_EXPORTER_OTLP_ENDPOINT",
|
||||
"http://localhost:6006/v1/traces"
|
||||
"http://localhost:8087/api/public/otel/v1/traces"
|
||||
)
|
||||
|
||||
# ✅ Define metadata do serviço (IMPORTANTE pro Phoenix)
|
||||
# -----------------------------------
|
||||
# LANGFUSE AUTH
|
||||
# -----------------------------------
|
||||
|
||||
public_key = os.getenv(
|
||||
"LANGFUSE_PUBLIC_KEY"
|
||||
)
|
||||
|
||||
secret_key = os.getenv(
|
||||
"LANGFUSE_SECRET_KEY"
|
||||
)
|
||||
|
||||
headers = {}
|
||||
|
||||
if public_key and secret_key:
|
||||
|
||||
auth = base64.b64encode(
|
||||
f"{public_key}:{secret_key}".encode()
|
||||
).decode()
|
||||
|
||||
headers["Authorization"] = (
|
||||
f"Basic {auth}"
|
||||
)
|
||||
|
||||
# -----------------------------------
|
||||
# RESOURCE
|
||||
# -----------------------------------
|
||||
|
||||
resource = Resource.create({
|
||||
"service.name": "nemo_guardrails_governed_project"
|
||||
"service.name":
|
||||
"nemo_guardrails_governed_project"
|
||||
})
|
||||
|
||||
provider = TracerProvider(resource=resource)
|
||||
provider = TracerProvider(
|
||||
resource=resource
|
||||
)
|
||||
|
||||
exporter = OTLPSpanExporter(
|
||||
endpoint=endpoint,
|
||||
timeout=5 # evita travamentos
|
||||
headers=headers,
|
||||
timeout=5
|
||||
)
|
||||
|
||||
span_processor = BatchSpanProcessor(exporter)
|
||||
provider.add_span_processor(span_processor)
|
||||
span_processor = BatchSpanProcessor(
|
||||
exporter
|
||||
)
|
||||
|
||||
# ✅ Evita sobrescrever provider existente
|
||||
if not isinstance(trace.get_tracer_provider(), TracerProvider):
|
||||
provider.add_span_processor(
|
||||
span_processor
|
||||
)
|
||||
|
||||
if not isinstance(
|
||||
trace.get_tracer_provider(),
|
||||
TracerProvider
|
||||
):
|
||||
trace.set_tracer_provider(provider)
|
||||
|
||||
tracer = trace.get_tracer(__name__)
|
||||
|
||||
print(
|
||||
f"[Tracing Enabled] endpoint={endpoint}"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
print(f"[Tracing Disabled] Error initializing tracing: {e}")
|
||||
|
||||
print(
|
||||
f"[Tracing Disabled] Error: {e}"
|
||||
)
|
||||
|
||||
tracer = None
|
||||
|
||||
|
||||
@contextmanager
|
||||
def span(name: str, **attrs):
|
||||
|
||||
if tracer is None:
|
||||
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)):
|
||||
|
||||
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}")
|
||||
|
||||
print(
|
||||
f"[Tracing Error] Span '{name}' failed: {e}"
|
||||
)
|
||||
|
||||
yield None
|
||||
@@ -34,7 +34,7 @@ if _TRACING_ENABLED:
|
||||
|
||||
endpoint = os.getenv(
|
||||
"OTEL_EXPORTER_OTLP_ENDPOINT",
|
||||
"http://localhost:6006/v1/traces"
|
||||
"http://localhost:8087/api/public/otel/v1/traces"
|
||||
)
|
||||
|
||||
# -----------------------------------
|
||||
|
||||
64
final_pkg/company_nemo_guardrails/tracing_opentelemetry.py
Normal file
64
final_pkg/company_nemo_guardrails/tracing_opentelemetry.py
Normal file
@@ -0,0 +1,64 @@
|
||||
import os
|
||||
from contextlib import contextmanager
|
||||
|
||||
_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
|
||||
|
||||
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):
|
||||
if tracer is None:
|
||||
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
|
||||
132
final_pkg/examples/test_judge.py
Normal file
132
final_pkg/examples/test_judge.py
Normal file
@@ -0,0 +1,132 @@
|
||||
import os
|
||||
|
||||
from company_nemo_guardrails.judges import (
|
||||
classificar_sentimento,
|
||||
avaliar_alucinacao,
|
||||
avaliar_qualidade_resposta,
|
||||
avaliar_tom_de_voz
|
||||
)
|
||||
|
||||
# ==========================================
|
||||
# CONFIGURAÇÃO
|
||||
# ==========================================
|
||||
|
||||
# MOCK = true -> usa mock local
|
||||
# MOCK = false -> usa OCI/OpenAI real
|
||||
|
||||
os.environ["USE_MOCK_LLM"] = "false"
|
||||
|
||||
# Se quiser usar o proxy real:
|
||||
#
|
||||
# os.environ["USE_MOCK_LLM"] = "false"
|
||||
# os.environ["OPENAI_BASE_URL"] = "http://localhost:8051/v1"
|
||||
# os.environ["OPENAI_API_KEY"] = "dummy"
|
||||
# os.environ["OPENAI_MODEL"] = "gpt-5"
|
||||
|
||||
|
||||
# ==========================================
|
||||
# HELPER
|
||||
# ==========================================
|
||||
|
||||
def print_result(title, result):
|
||||
|
||||
print("\n" + "=" * 80)
|
||||
print(f"🧪 TESTE: {title}")
|
||||
print("=" * 80)
|
||||
|
||||
print(f"CODE : {result.code}")
|
||||
print(f"ALLOWED : {result.allowed}")
|
||||
print(f"REASON : {result.reason}")
|
||||
print(f"MECHANISM : {result.mechanism}")
|
||||
print(f"SANITIZED_TEXT : {result.sanitized_text}")
|
||||
|
||||
print("\nDATA:")
|
||||
print(result.data)
|
||||
|
||||
print("=" * 80)
|
||||
|
||||
# ==========================================
|
||||
# TESTE CSI
|
||||
# ==========================================
|
||||
|
||||
def test_csi():
|
||||
|
||||
result = classificar_sentimento(
|
||||
"""
|
||||
Estou muito insatisfeito com o atendimento.
|
||||
Quero cancelar meu plano imediatamente.
|
||||
"""
|
||||
)
|
||||
|
||||
print_result("CSI - Sentimento Negativo", result)
|
||||
|
||||
|
||||
# ==========================================
|
||||
# TESTE ALUCINAÇÃO
|
||||
# ==========================================
|
||||
|
||||
def test_alucinacao():
|
||||
|
||||
result = avaliar_alucinacao(
|
||||
resposta="""
|
||||
O cliente pode cancelar em até 30 dias sem multa.
|
||||
""",
|
||||
|
||||
dados_reais="""
|
||||
O cliente pode cancelar em até 7 dias sem multa.
|
||||
"""
|
||||
)
|
||||
|
||||
print_result("ALUC - Alucinação Detectada", result)
|
||||
|
||||
|
||||
# ==========================================
|
||||
# TESTE QUALIDADE
|
||||
# ==========================================
|
||||
|
||||
def test_qualidade():
|
||||
|
||||
result = avaliar_qualidade_resposta(
|
||||
pergunta="""
|
||||
Como faço para cancelar meu plano?
|
||||
""",
|
||||
|
||||
resposta="""
|
||||
Para cancelar seu plano,
|
||||
acesse o portal do cliente,
|
||||
vá até a seção Financeiro
|
||||
e clique em Cancelamento.
|
||||
"""
|
||||
)
|
||||
|
||||
print_result("RQLT - Qualidade Resposta", result)
|
||||
|
||||
|
||||
# ==========================================
|
||||
# TESTE TOM DE VOZ
|
||||
# ==========================================
|
||||
|
||||
def test_tom_voz():
|
||||
|
||||
result = avaliar_tom_de_voz(
|
||||
"""
|
||||
Se vira. Não posso fazer nada por você.
|
||||
"""
|
||||
)
|
||||
|
||||
print_result("VCTN - Tom Inadequado", result)
|
||||
|
||||
|
||||
# ==========================================
|
||||
# MAIN
|
||||
# ==========================================
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
test_csi()
|
||||
|
||||
test_alucinacao()
|
||||
|
||||
test_qualidade()
|
||||
|
||||
test_tom_voz()
|
||||
@@ -5,9 +5,12 @@ OPENAI_API_KEY=dummy
|
||||
OPENAI_MODEL=gpt-5
|
||||
|
||||
# Tracing / Phoenix / OpenTelemetry
|
||||
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:6006/v1/traces
|
||||
OTEL_SERVICE_NAME=nemo-guardrails-demo
|
||||
ENABLE_TRACING=true
|
||||
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:8087/api/public/otel/v1/traces
|
||||
export OTEL_SERVICE_NAME=nemo-guardrails-demo
|
||||
export ENABLE_TRACING=true
|
||||
export LANGFUSE_SECRET_KEY="sk-lf-0bb4d15d-6101-4874-991b-68780cf7b748"
|
||||
export LANGFUSE_PUBLIC_KEY="pk-lf-1b51d3b4-af8d-4b8b-8ac4-e81e6006123f"
|
||||
export LANGFUSE_BASE_URL="http://localhost:8087"
|
||||
|
||||
# Modo demo: usa cliente fake se o proxy não estiver disponível
|
||||
USE_MOCK_LLM=false
|
||||
|
||||
@@ -1,64 +1,142 @@
|
||||
import os
|
||||
import base64
|
||||
|
||||
from contextlib import contextmanager
|
||||
|
||||
_TRACING_ENABLED = os.getenv("ENABLE_TRACING", "false").lower() == "true"
|
||||
_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
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
endpoint = os.getenv(
|
||||
"OTEL_EXPORTER_OTLP_ENDPOINT",
|
||||
"http://localhost:6006/v1/traces"
|
||||
"http://localhost:8087/api/public/otel/v1/traces"
|
||||
)
|
||||
|
||||
# ✅ Define metadata do serviço (IMPORTANTE pro Phoenix)
|
||||
# -----------------------------------
|
||||
# LANGFUSE AUTH
|
||||
# -----------------------------------
|
||||
|
||||
public_key = os.getenv(
|
||||
"LANGFUSE_PUBLIC_KEY"
|
||||
)
|
||||
|
||||
secret_key = os.getenv(
|
||||
"LANGFUSE_SECRET_KEY"
|
||||
)
|
||||
|
||||
headers = {}
|
||||
|
||||
if public_key and secret_key:
|
||||
|
||||
auth = base64.b64encode(
|
||||
f"{public_key}:{secret_key}".encode()
|
||||
).decode()
|
||||
|
||||
headers["Authorization"] = (
|
||||
f"Basic {auth}"
|
||||
)
|
||||
|
||||
# -----------------------------------
|
||||
# RESOURCE
|
||||
# -----------------------------------
|
||||
|
||||
resource = Resource.create({
|
||||
"service.name": "nemo_guardrails_governed_project"
|
||||
"service.name":
|
||||
"nemo_guardrails_governed_project"
|
||||
})
|
||||
|
||||
provider = TracerProvider(resource=resource)
|
||||
provider = TracerProvider(
|
||||
resource=resource
|
||||
)
|
||||
|
||||
exporter = OTLPSpanExporter(
|
||||
endpoint=endpoint,
|
||||
timeout=5 # evita travamentos
|
||||
headers=headers,
|
||||
timeout=5
|
||||
)
|
||||
|
||||
span_processor = BatchSpanProcessor(exporter)
|
||||
provider.add_span_processor(span_processor)
|
||||
span_processor = BatchSpanProcessor(
|
||||
exporter
|
||||
)
|
||||
|
||||
# ✅ Evita sobrescrever provider existente
|
||||
if not isinstance(trace.get_tracer_provider(), TracerProvider):
|
||||
provider.add_span_processor(
|
||||
span_processor
|
||||
)
|
||||
|
||||
if not isinstance(
|
||||
trace.get_tracer_provider(),
|
||||
TracerProvider
|
||||
):
|
||||
trace.set_tracer_provider(provider)
|
||||
|
||||
tracer = trace.get_tracer(__name__)
|
||||
|
||||
print(
|
||||
f"[Tracing Enabled] endpoint={endpoint}"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
print(f"[Tracing Disabled] Error initializing tracing: {e}")
|
||||
|
||||
print(
|
||||
f"[Tracing Disabled] Error: {e}"
|
||||
)
|
||||
|
||||
tracer = None
|
||||
|
||||
|
||||
@contextmanager
|
||||
def span(name: str, **attrs):
|
||||
|
||||
if tracer is None:
|
||||
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)):
|
||||
|
||||
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}")
|
||||
|
||||
print(
|
||||
f"[Tracing Error] Span '{name}' failed: {e}"
|
||||
)
|
||||
|
||||
yield None
|
||||
@@ -34,7 +34,7 @@ if _TRACING_ENABLED:
|
||||
|
||||
endpoint = os.getenv(
|
||||
"OTEL_EXPORTER_OTLP_ENDPOINT",
|
||||
"http://localhost:6006/v1/traces"
|
||||
"http://localhost:8087/api/public/otel/v1/traces"
|
||||
)
|
||||
|
||||
# -----------------------------------
|
||||
|
||||
64
nemo_guardrails_tracing_project/src/tracing_opentelemetry.py
Normal file
64
nemo_guardrails_tracing_project/src/tracing_opentelemetry.py
Normal file
@@ -0,0 +1,64 @@
|
||||
import os
|
||||
from contextlib import contextmanager
|
||||
|
||||
_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
|
||||
|
||||
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):
|
||||
if tracer is None:
|
||||
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
|
||||
Reference in New Issue
Block a user