From 6ed75089838ba23d4a75465526f408a6ab035155 Mon Sep 17 00:00:00 2001 From: TalexDreamSoul Date: Sun, 5 Jul 2026 02:33:26 -0700 Subject: [PATCH] fix: degrade elder analysis when knowledge retrieval fails --- modules/ai/server/analysis.ts | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/modules/ai/server/analysis.ts b/modules/ai/server/analysis.ts index fde1086..385ee62 100644 --- a/modules/ai/server/analysis.ts +++ b/modules/ai/server/analysis.ts @@ -208,20 +208,23 @@ export async function generateElderAiAnalysis( : { success: true as const, data: { results: [] } }; if (!knowledgeResults.success) { - await saveFailedAnalysis({ - context, + await recordAuditLog({ + actor: context.account, organizationId: residentContext.context.organizationId, - elderId, - dataScopes: residentContext.context.dataScopes, - category: "retrieval_failed", + action: "ai.knowledge.retrieve", + targetType: "elder", + targetId: elderId, + result: "failure", + reason: getBriefErrorReason("retrieval_failed"), }); - return { success: false, reason: knowledgeResults.reason, status: knowledgeResults.status }; } - const dataScopes = knowledgeResults.data.results.length > 0 + const knowledgeItems = knowledgeResults.success ? knowledgeResults.data.results : []; + const knowledgeUnavailableReason = knowledgeResults.success ? "" : getBriefErrorReason("retrieval_failed"); + const dataScopes = knowledgeItems.length > 0 ? [...residentContext.context.dataScopes, "knowledge" as const] : residentContext.context.dataScopes; - const knowledgeCitations: AiCitation[] = knowledgeResults.data.results.map((item, index) => ({ + const knowledgeCitations: AiCitation[] = knowledgeItems.map((item, index) => ({ id: `kb-${index + 1}`, sourceType: "knowledge", sourceId: item.chunkId, @@ -238,10 +241,11 @@ export async function generateElderAiAnalysis( "输出 JSON 字段:overallRiskLevel(low|medium|high|critical|unknown), summary, keyFindings, recommendations, dataGaps, citations, confidence, modelSummary。", "keyFindings[] 字段:category, severity(info|warning|critical), evidence, citationIds。", "recommendations[] 字段:title, priority(low|normal|high|urgent), rationale, suggestedNextStep, citationIds。", + knowledgeUnavailableReason ? `知识库检索不可用:${knowledgeUnavailableReason}。请在 dataGaps 中包含“知识库检索不可用,分析未使用内部知识库”。` : "", `modelSummary 固定为 {"provider":"openai-compatible","chatModel":"${runtimeConfig.config.chatModel}","embeddingModel":"${runtimeConfig.config.embeddingModel}"}。`, `可用 citations:${JSON.stringify(citations)}`, `住民上下文:\n${residentContext.context.promptContext}`, - `知识库片段:\n${knowledgeResults.data.results.map((item, index) => `[kb-${index + 1}] ${item.title}\n${item.content}`).join("\n\n") || "无"}`, + `知识库片段:\n${knowledgeItems.map((item, index) => `[kb-${index + 1}] ${item.title}\n${item.content}`).join("\n\n") || "无"}`, ].join("\n\n"); let rawOutput: unknown; @@ -275,7 +279,15 @@ export async function generateElderAiAnalysis( return { success: false, reason: getBriefErrorReason("schema_validation_failed"), status: 502 }; } - const normalizedOutput = normalizeCitations(output, citations); + const normalizedOutput = normalizeCitations( + knowledgeUnavailableReason + ? { + ...output, + dataGaps: [...output.dataGaps, "知识库检索不可用,分析未使用内部知识库"], + } + : output, + citations, + ); const database = getDatabase(); const rows = await database .insert(elderAiAnalyses)