SDK oficial de Python para integrar aplicaciones de IA con el Argorix Guardrails Runtime.
pip install argorix-guardrailsRebranding. Este paquete se llamaba
governanceai. El nombregovernanceaisigue publicado como shim de compatibilidad (depende deargorix-guardrailsy lo reexporta), pero ya no recibe features. Ver Migración desdegovernanceai.
| Endpoint | Método del SDK |
|---|---|
POST /v1/guardrails/install |
install() |
POST /v1/guardrails/heartbeat |
heartbeat() |
POST /v1/guardrails/evaluate |
evaluate() (alias: apply()) |
POST /v1/guardrails/evaluate/stream |
evaluate_stream(), evaluate_streamed_decision() |
POST /v1/guardrails/events |
record_event(), report_redteam_probe() |
Los guardrails de agentes (/v1/agent-guardrails/runtime/*) viven en el paquete
argorix-guardrails-agent.
base_url acepta tanto https://api.argorix.com como https://api.argorix.com/v1: el
sufijo /v1 se normaliza para no duplicar el prefijo.
app_numberen el body de cada requestAuthorization: Bearer <APP_API_KEY>en cada header
Ambos valores salen de Application Settings > API Keys en la consola.
from argorix import ArgorixClient, ArgorixError
client = ArgorixClient(
base_url="https://api.argorix.com",
app_number=123456,
app_api_key="ga_live_replace_me",
timeout_seconds=10,
max_retries=2,
)
try:
state = client.install(mode="monitor", metadata={"environment": "production"})
print(state.mode, state.selected_validators)
decision = client.evaluate("Summarize this support ticket", stage="input")
print(decision.allowed, decision.findings, decision.selected_validators)
except ArgorixError as exc:
print(exc.status_code, exc)client = ArgorixClient.from_env()| Variable | Uso | Fallback legado |
|---|---|---|
ARGORIX_API_URL |
base_url |
ARGORIX_BASE_URL, GOVERNANCE_AI_URL |
ARGORIX_APP_NUMBER |
app_number |
APP_NUMBER |
ARGORIX_APP_API_KEY |
app_api_key |
APP_API_KEY |
ARGORIX_POLICY_ID |
default_policy_id |
— |
Los argumentos explícitos siempre ganan sobre el entorno.
Dos llamadas por turno: una antes de invocar el modelo y otra antes de entregar su
respuesta. output_text es el texto que hay que usar — en un transform no es el que
enviaste.
decision_in = client.evaluate(user_prompt, stage="input")
if decision_in.blocked:
# El modelo no se invoca. decision_in.runtime_evidence trae el registro firmado.
raise RuntimeError(decision_in.reason)
model_reply = llm.invoke(decision_in.output_text)
decision_out = client.evaluate(model_reply, stage="output")
if decision_out.blocked:
raise RuntimeError(decision_out.reason)
deliver(decision_out.output_text)HTTP 200 significa que la evaluación se procesó, no que el texto sea seguro. Hay tres preguntas distintas y tres campos que las responden:
| Campo | Responde | Valores |
|---|---|---|
decision |
qué hacer con el texto | allow, transform, deny |
outcome |
sobre qué base se decidió | policy_match, policy_not_applicable, evaluator_error, configuration_error |
reason_code |
el detalle estable | policy:allow, policy:transform, policy:deny, policy:monitored, policy:not_applicable, runtime_error:evaluator_failed, config:evaluation_engine_unavailable |
Dos cosas que no ocurren, y que conviene no programar defensivamente:
- Sin política aplicable no hay bloqueo. Guardrails apagados, ningún validador activo
o un request sin nada que evaluar devuelven
allowed=Trueconreason_code="policy:not_applicable".decision.policy_applieddistingue eso de una política que sí corrió y no encontró nada. - Un evaluador caído no bloquea salvo que la aplicación esté configurada
fail_closed. Cuando falla, los validadores afectados llegan endecision.errors, los detectores deterministas deciden igual, ydecision.degradedqueda enTrue.
runtime_evidence es el registro de la decisión, emitido durante la evaluación y sellado
con un digest recomputable más una firma HMAC-SHA256. Viaja en deny, en transform,
cuando hay hallazgos, o siempre que pidas include_evidence=True.
decision = client.evaluate(
user_prompt,
stage="input",
agent_id="industry_support",
endpoint="/industry/assistant",
step={"type": "llm", "name": "industry.request"},
actor={"type": "human", "id": "presenter"},
model={"provider": "openai", "name": "gpt-4.1-mini"},
request_id=request_id,
)Esos descriptores no cambian el veredicto: viajan al registro, que los marca en
attestation.caller_declared — ARGORIX los repite, no los atestigua. Lo que sí observa
el servidor, model.invoked incluido, va en attestation.server_observed.
decision = client.evaluate(
"Open the customer export",
stage="tool",
tool_calls=[
{"tool_name": "browser.fetch", "url": "https://example.com/private-report"}
],
)Si el dominio no está permitido por la configuración de la aplicación, el backend puede responder bloqueando la operación.
evaluate_stream() consume POST /v1/guardrails/evaluate/stream y emite los eventos
start, result, end — o error si la evaluación falla en el servidor.
for event in client.evaluate_stream(user_prompt, stage="input"):
if event.event == "result":
print("allowed:", event.data["allowed"])
elif event.event == "error":
print("guardrail error:", event.data["detail"])Si solo te interesa la decisión final:
decision = client.evaluate_streamed_decision(user_prompt, stage="input")Levanta ArgorixError si el servidor emite error o si el stream cierra sin result.
El stream es perezoso: no se envía nada hasta que empiezas a iterar. Los reintentos
cubren la conexión y el status inicial; una vez abierto el stream no se reintenta.
evaluate() devuelve GuardrailsDecision:
| Campo | Tipo |
|---|---|
allowed / blocked |
bool |
output_text |
str |
mode |
"monitor" | "enforce" |
findings |
list[GuardrailsFinding] |
evaluations |
list[GuardrailsEvaluation] |
selected_validators |
list[str] |
effective_scope, guardrails_config |
dict |
guardrails_engine, stage, application_id, app_number, repository, server_time |
metadatos del control plane |
highest_severity |
severidad máxima entre los findings |
raw |
payload JSON sin tocar |
install() y heartbeat() devuelven GuardrailsState (application_id, app_number,
repository, installation_connected, guardrails_config, effective_scope,
selected_validators, mode, enabled, raw).
Ambos objetos aceptan acceso tipo diccionario (decision["repository"],
state.get("app_number")) que lee directo de raw, así que campos nuevos del control
plane quedan accesibles sin actualizar el SDK.
El cliente acumula requests_total, blocked_total y avg_latency_ms, y los adjunta a
evaluate() y heartbeat() salvo que pases include_telemetry=False.
print(client.telemetry)
client.reset_telemetry()ArgorixClient expone timeout_seconds, max_retries, retry_backoff_seconds y
retry_status_codes. Los errores levantan ArgorixError con status_code y
response_body. Se reintentan errores de red y respuestas 408, 429, 500, 502,
503, 504 con backoff exponencial.
Los eventos y evaluaciones de este SDK alimentan AI Applications, Guardrails Log,
Risk & Governance y AI Compliance. En la consola:
AI Applications: inventario resumidoAI Application Profile: postura, evidencia y modelos/toolsApplication Settings:Installation,API Keys,GuardrailsAI Workbench: validación de prompts y matriz TRUE/FALSE por control
argorix-bom --base-url https://api.argorix.com --cookie "argorix_session=..." generate --application-id travel-assistant --force
argorix-bom --base-url https://api.argorix.com --cookie "argorix_session=..." export --document-id bom-123 --format cyclonedx --output ai-bom.json
argorix-bom --base-url https://api.argorix.com --cookie "argorix_session=..." scan ./my-agent-repo --application-id my-agent-repo
argorix-bom --base-url https://api.argorix.com --cookie "argorix_session=..." scan ./my-agent-repo --format cyclonedx --output ai-bom-cyclonedx.json
argorix-bom --base-url https://api.argorix.com --cookie "argorix_session=..." scan ./my-agent-repo --watch --interval-seconds 3Formatos: cyclonedx, spdx, sarif, markdown, html.
El flujo scan ejecuta POST /v1/scans/local, refresca el AI-BOM activo con
POST /v1/ai-bom/applications/{application_id}/generate y opcionalmente exporta el
documento. Sin --application-id, la CLI infiere un slug desde el nombre de la carpeta.
En --watch no vuelve a pegarle al backend hasta detectar un cambio local.
Credencial: --cookie "argorix_session=...", ARGORIX_SESSION_COOKIE, o el legado
GOVERNANCEAI_SESSION_COOKIE. Sigue siendo cookie de sesión del control-plane; migrarla
a un token específico queda pendiente.
pip uninstall governanceai
pip install argorix-guardrails| Antes | Ahora |
|---|---|
from governanceai import GovernanceAIClient |
from argorix import ArgorixClient |
GovernanceAIError |
ArgorixError |
client.apply(...) |
client.evaluate(...) (apply sigue funcionando) |
governanceai-bom |
argorix-bom |
GOVERNANCEAI_SESSION_COOKIE |
ARGORIX_SESSION_COOKIE |
Los nombres viejos siguen exportados desde argorix como alias, así que un cambio de
import alcanza para arrancar. Cambios de comportamiento a revisar:
install()yheartbeat()devuelvenGuardrailsStateen vez dedict. El acceso por clave sigue funcionando (state["application_id"]).decision.findingsahora son dataclassesGuardrailsFinding.finding["severity"]sigue funcionando;finding.severityes la forma recomendada.
pip install -e ./sdk/python
python -m pytest ./sdk/python/tests
python -m build ./sdk/python- Versión actual:
0.2.0 - Historial:
CHANGELOG.md - Licencia:
LICENSE