From 206673fd90e6a2c016c0417ae5e2031f2ec4259a Mon Sep 17 00:00:00 2001 From: dekun Date: Wed, 10 Jun 2026 23:10:09 +0800 Subject: [PATCH] Fix AI output showing UTF-8 bytes as hex escapes instead of Chinese. Decode <0xE5><0xA7><0xA4> style model output to proper characters; add prompt rule to use normal Chinese text. Co-authored-by: Cursor --- lib/ai/client-stream.ts | 9 +++++++-- lib/ai/decode-text.ts | 20 ++++++++++++++++++++ lib/prompts/index.ts | 12 +++++++++--- 3 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 lib/ai/decode-text.ts diff --git a/lib/ai/client-stream.ts b/lib/ai/client-stream.ts index 5b50710..11cc916 100644 --- a/lib/ai/client-stream.ts +++ b/lib/ai/client-stream.ts @@ -1,4 +1,9 @@ import type { AiRequestBody } from "@/lib/ai/types"; +import { decodeHexByteEscapes } from "@/lib/ai/decode-text"; + +function emitText(text: string, onUpdate: (text: string) => void) { + onUpdate(decodeHexByteEscapes(text)); +} function parseApiError(text: string, status: number): string { const trimmed = text.trim(); @@ -41,11 +46,11 @@ export async function streamAiCompletion( break; } text += decoder.decode(value, { stream: true }); - onUpdate(text); + emitText(text, onUpdate); } text += decoder.decode(); - onUpdate(text); + emitText(text, onUpdate); if (!text.trim()) { throw new Error("AI 返回内容为空,请检查模型配置或稍后重试"); diff --git a/lib/ai/decode-text.ts b/lib/ai/decode-text.ts new file mode 100644 index 0000000..7affa4f --- /dev/null +++ b/lib/ai/decode-text.ts @@ -0,0 +1,20 @@ +/** + * 部分模型会把 UTF-8 汉字输出成 <0xE5><0xA7><0xA4> 形式,还原为正常文字。 + * 例:<0xE5><0xA7><0xA4> → 姤 + */ +export function decodeHexByteEscapes(text: string): string { + return text.replace(/(?:<0x[0-9A-Fa-f]{2}>)+/gi, (match) => { + const parts = match.match(/<0x([0-9A-Fa-f]{2})>/gi); + if (!parts?.length) { + return match; + } + const bytes = Uint8Array.from( + parts.map((part) => parseInt(part.slice(3, 5), 16)), + ); + try { + return new TextDecoder("utf-8", { fatal: true }).decode(bytes); + } catch { + return new TextDecoder("utf-8", { fatal: false }).decode(bytes); + } + }); +} diff --git a/lib/prompts/index.ts b/lib/prompts/index.ts index 4fe881b..f1bd6e5 100644 --- a/lib/prompts/index.ts +++ b/lib/prompts/index.ts @@ -3,7 +3,9 @@ export const LIUYAO_SYSTEM_PROMPT = `你是一位精通《周易》六爻的 AI 任务要求:逻辑清晰,语气得当 1. 结合起卦时辰(节气、日柱、时辰)与地域,分析天时地利对卦象的影响 2. 解读主卦、变爻及变卦,说明整体趋势和吉凶 -3. 针对用户问事,结合卦象给出具体分析和可行建议`; +3. 针对用户问事,结合卦象给出具体分析和可行建议 + +输出规范:必须使用正常中文汉字与标点(如「姤卦」「乾为天」),禁止使用 <0xXX> 或十六进制字节形式表示文字。`; export const BAZI_SYSTEM_PROMPT = `你是一位精通子平八字的命理分析师,根据用户提供的排盘信息和问题,给出专业、清晰的命理解读。 @@ -13,7 +15,9 @@ export const BAZI_SYSTEM_PROMPT = `你是一位精通子平八字的命理分析 3. 结合大运流年分析趋势 4. 提示相关神煞吉凶 5. 针对用户具体问题给出切实可行的建议 -语气得当,逻辑清晰,避免绝对化断言。`; +语气得当,逻辑清晰,避免绝对化断言。 + +输出规范:必须使用正常中文汉字与标点,禁止使用 <0xXX> 或十六进制字节形式表示文字。`; export const COMBINED_SYSTEM_PROMPT = `你是一位融合天时、地利、人和的综合命理顾问,精通子平八字与周易六爻。 @@ -21,4 +25,6 @@ export const COMBINED_SYSTEM_PROMPT = `你是一位融合天时、地利、人 1. 综合天时(节气、日柱时辰)、地利(地域经度方位)、人和(八字命局)进行分析 2. 若用户提供卦象,结合卦辞与变爻补充解读 3. 针对用户问事给出具体、可操作的指引 -语气得当,逻辑清晰,各维度分析要有机融合而非简单罗列。`; +语气得当,逻辑清晰,各维度分析要有机融合而非简单罗列。 + +输出规范:必须使用正常中文汉字与标点,禁止使用 <0xXX> 或十六进制字节形式表示文字。`;