{"record":{"id":"1a6ae638e1f44cf5","repo":"iflytek/astron-agent","slug":"audit-output-error-result-abnormal-resp","errorCode":"AUDIT_OUTPUT_ERROR","errorMessage":"Audit result abnormal: {resp}","messagePattern":"Audit result abnormal: (.+?)","errorType":"error_code","errorClass":"CustomException","httpStatus":null,"severity":"error","filePath":"core/workflow/infra/audit_system/audit_api/mock/mock_audit_api.py","lineNumber":232,"sourceCode":"        :param chat_app_id: Application identifier for audit context\n        :param uid: User identifier for audit context\n        :param kwargs: Additional keyword arguments\n        :raises CustomException: If mock audit result indicates unsafe content\n        \"\"\"\n        payload = {\n            \"intention\": \"dialog\",\n            \"stage\": stage.value,\n            \"content\": content,\n            \"pindex\": pindex,\n            \"is_pending\": is_pending,\n            \"is_stage_end\": is_stage_end,\n            \"is_end\": is_end,\n            \"chat_sid\": chat_sid,\n        }\n        resp = await self._post(\"/audit/v3/aichat/output\", payload, chat_app_id, uid)\n        logging.info(f\"\\nMockAuditAPI.output_text resp: {resp}\")\n        if resp.get(\"data\", {}).get(\"action\") != ActionEnum.NONE:\n            raise CustomException(\n                CodeEnum.AUDIT_OUTPUT_ERROR,\n                cause_error=f\"Audit result abnormal: {resp}\",\n            )\n\n    async def input_media(self, text: str, **kwargs: Any) -> None:\n        \"\"\"\n        In LLM content security scenarios, filter, detect and identify user input text,\n        images, videos, documents, etc., and process and respond accordingly based on security policies.\n        :param text: Text content to be processed\n        :param kwargs: Additional keyword arguments\n        :return: None\n        \"\"\"\n        # path = f\"/audit/v3/aichat/inputMedia\"\n\n        # TODO: To be implemented\n        raise NotImplementedError(\"MockAuditAPI.input_media is not implemented yet\")\n\n    async def output_media(self, text: str, **kwargs: Any) -> None:","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/workflow/infra/audit_system/audit_api/mock/mock_audit_api.py#L214-L250","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nawait audit_api.output_text(Stage.ANSWER, chunk, pindex, span, 0, 0, is_end, chat_sid)\n\n# after\ntry:\n    await audit_api.output_text(Stage.ANSWER, chunk, pindex, span, 0, 0, is_end, chat_sid)\nexcept CustomException as e:\n    if e.code == CodeEnum.AUDIT_OUTPUT_ERROR:\n        await emit_blocked_response(e)\n        return\n    raise","handlingStrategy":"try-catch","validationCode":"if not content.strip():\n    logger.warning(\"Skipping output audit for empty fragment pindex=%s\", pindex)\n    return","typeGuard":"def output_audit_passed(resp: dict) -> bool:\n    return isinstance(resp, dict) and resp.get(\"data\", {}).get(\"action\") == ActionEnum.NONE","tryCatchPattern":"try:\n    await audit_api.output_text(stage, content, pindex, span, is_pending, is_stage_end, is_end, chat_sid)\nexcept CustomException as e:\n    if e.code == CodeEnum.AUDIT_OUTPUT_ERROR:\n        logger.warning(\"Output audit rejected at pindex=%s: %s\", pindex, e.cause_error)\n        await emit_blocked_response()\n        return\n    raise","preventionTips":["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"],"tags":["python","audit","content-moderation","streaming","custom-exception"],"backgroundTag":"api-error-response","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}