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

  1. 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).
  2. 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.
  3. If this occurs during testing, reconfigure the mock backend to return ActionEnum.NONE for benign test content.
  4. 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

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)