iflytek/astron-agent · error · CustomException
AUDIT_OUTPUT_ERROR
AUDIT_OUTPUT_ERROR
Error message
Audit result abnormal: {resp} What it means
MockAuditAPI.output_text raises CustomException(CodeEnum.AUDIT_OUTPUT_ERROR, 'Audit result abnormal: {resp}') when the audit response for LLM output text (/audit/v3/aichat/output) has data.action != ActionEnum.NONE. Action NONE means the model output passed moderation; any other action means the generated content was flagged (blocked/needs review), and the exception carries the full response payload. This is the output-side counterpart of AUDIT_INPUT_ERROR.
Solutions
- Read the logged 'MockAuditAPI.output_text resp' line and the resp embedded in the error to identify data.action and the flagged fragment (pindex, is_end).
- Adjust the model/system prompt or output filtering so generated content complies with the active audit policy, or relax the audit template if it is over-blocking legitimate output.
- If this occurs during testing, reconfigure the mock backend to return ActionEnum.NONE for benign test content.
- Catch CustomException with code AUDIT_OUTPUT_ERROR in the streaming path and emit a policy-violation event to the client instead of breaking the SSE stream.
Example fix
# before
await audit_api.output_text(Stage.ANSWER, chunk, pindex, span, 0, 0, is_end, chat_sid)
# after
try:
await audit_api.output_text(Stage.ANSWER, chunk, pindex, span, 0, 0, is_end, chat_sid)
except CustomException as e:
if e.code == CodeEnum.AUDIT_OUTPUT_ERROR:
await emit_blocked_response(e)
return
raise Defensive patterns
Strategy: try-catch
Validate before calling
if not content.strip():
logger.warning("Skipping output audit for empty fragment pindex=%s", pindex)
return Type guard
def output_audit_passed(resp: dict) -> bool:
return isinstance(resp, dict) and resp.get("data", {}).get("action") == ActionEnum.NONE Try / catch
try:
await audit_api.output_text(stage, content, pindex, span, is_pending, is_stage_end, is_end, chat_sid)
except CustomException as e:
if e.code == CodeEnum.AUDIT_OUTPUT_ERROR:
logger.warning("Output audit rejected at pindex=%s: %s", pindex, e.cause_error)
await emit_blocked_response()
return
raise Prevention
- Handle AUDIT_OUTPUT_ERROR per-fragment in streaming paths so one flagged chunk does not kill the SSE stream
- Correlate pindex/is_end from the error payload to locate the offending fragment
- Tune the audit template_id to the risk profile of your model output
- Keep the audit response logging enabled to debug flagged content quickly
When it happens
Trigger: Calling MockAuditAPI.output_text(stage, content, pindex, span, is_pending, is_stage_end, is_end, chat_sid, ...) where the streamed or final LLM content is judged unsafe by the audit backend, so the returned data.action differs from NONE.
Common situations: The LLM hallucinates or echoes sensitive content that trips the moderation policy mid-stream, aborting the response; a strict audit template_id flags borderline output; the mock/simulated backend is configured to return non-NONE actions for testing, which then surfaces in every generation.
Related errors
AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12).
Data as JSON: /api/errors/1a6ae638e1f44cf5.
Report an issue: GitHub.
Appendix: source
Thrown at core/workflow/infra/audit_system/audit_api/mock/mock_audit_api.py:232
:param chat_app_id: Application identifier for audit context
:param uid: User identifier for audit context
:param kwargs: Additional keyword arguments
:raises CustomException: If mock audit result indicates unsafe content
"""
payload = {
"intention": "dialog",
"stage": stage.value,
"content": content,
"pindex": pindex,
"is_pending": is_pending,
"is_stage_end": is_stage_end,
"is_end": is_end,
"chat_sid": chat_sid,
}
resp = await self._post("/audit/v3/aichat/output", payload, chat_app_id, uid)
logging.info(f"\nMockAuditAPI.output_text resp: {resp}")
if resp.get("data", {}).get("action") != ActionEnum.NONE:
raise CustomException(
CodeEnum.AUDIT_OUTPUT_ERROR,
cause_error=f"Audit result abnormal: {resp}",
)
async def input_media(self, text: str, **kwargs: Any) -> None:
"""
In LLM content security scenarios, filter, detect and identify user input text,
images, videos, documents, etc., and process and respond accordingly based on security policies.
:param text: Text content to be processed
:param kwargs: Additional keyword arguments
:return: None
"""
# path = f"/audit/v3/aichat/inputMedia"
# TODO: To be implemented
raise NotImplementedError("MockAuditAPI.input_media is not implemented yet")
async def output_media(self, text: str, **kwargs: Any) -> None:View on GitHub (pinned to 5e758547a8)