From f4de598d9657cbd8e4406e49ab59efcff477b2c4 Mon Sep 17 00:00:00 2001 From: wangdl Date: Sat, 6 Jun 2026 14:30:53 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20rag-chat=20=E4=BC=A0=E5=85=A5=20outputSc?= =?UTF-8?q?hema=3D=20RagChatOutputSchema=EF=BC=8C=E4=BF=AE=E5=A4=8D=20pars?= =?UTF-8?q?ed=20=E4=B8=BA=E7=A9=BA=E5=AF=B9=E8=B1=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit parseJson 无 schema 时直接返回 {},导致 resp.parsed?.answer 始终为 null。 Co-Authored-By: Claude Opus 4.7 --- src/modules/ai/prompts/schemas/rag-chat.schema.ts | 11 +++++++---- src/modules/rag-chat/rag-chat.service.ts | 2 ++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/modules/ai/prompts/schemas/rag-chat.schema.ts b/src/modules/ai/prompts/schemas/rag-chat.schema.ts index 3756b6e..1009cbf 100644 --- a/src/modules/ai/prompts/schemas/rag-chat.schema.ts +++ b/src/modules/ai/prompts/schemas/rag-chat.schema.ts @@ -1,6 +1,9 @@ +import { z } from 'zod'; + +export const RagChatOutputSchema = z.object({ + answer: z.string().min(1).max(5000), +}); + export const RAG_CHAT_OUTPUT_SCHEMA_DESC = `{ - "answer": "你的回答内容", - "citations": [ - { "title": "引用的知识点标题", "snippet": "引用的原文片段" } - ] + "answer": "你的回答内容" }`; diff --git a/src/modules/rag-chat/rag-chat.service.ts b/src/modules/rag-chat/rag-chat.service.ts index 7adf096..9b5e0fc 100644 --- a/src/modules/rag-chat/rag-chat.service.ts +++ b/src/modules/rag-chat/rag-chat.service.ts @@ -2,6 +2,7 @@ import { Injectable, NotFoundException, Logger, Optional } from '@nestjs/common' import { PrismaService } from '../../infrastructure/database/prisma.service'; import { ContentSafetyService } from '../content-safety/content-safety.service'; import { AiGatewayService } from '../ai/gateway/ai-gateway.service'; +import { RagChatOutputSchema } from '../ai/prompts/schemas/rag-chat.schema'; const MAX_CONTEXT_CHARS = 4000; @@ -75,6 +76,7 @@ export class RagChatService { promptVersion: 'v1', messages, maxTokens: 2048, + outputSchema: RagChatOutputSchema, }); this.logger.log(`AI Gateway response: parsed=${!!resp.parsed}, keys=${resp.parsed ? Object.keys(resp.parsed).join(',') : 'null'}, raw=${JSON.stringify(resp.parsed).substring(0, 300)}`); reply = resp.parsed?.answer ?? String(resp.parsed?.content ?? '抱歉,AI 暂时无法生成回答。');