AI 解卦助手的实现:后端代理与多轮对话管理

将大语言模型集成到六爻应用中的完整实践,包括 Prompt 工程、对话上下文管理和费用控制。

一、架构设计

AI 解读功能采用后端代理架构,前端不直接调用 AI API:

前端 App → POST /api/ai/analyze → 后端代理 → AI API → 返回结果

这样做的好处:

二、Prompt 工程

解卦的 Prompt 需要包含完整的卦象数据。我们用 exportText.ts 生成结构化的卦象文本:

请对六爻排盘信息进行解析:

所问事项为:近期事业是否顺利

日期:
公历[2026年6月5日  14时30分 星期四]
农历[丙午年四月初十]
四柱:
年柱[丙午年]  月柱[巳月]  日柱[庚辰日]  时柱[未时]  旬空[子丑]

           天地否(乾,归魂)          泽地萃(兑,归魂)
六神  伏神   本卦              变卦
青龙     父母戌土 ○    兄弟未土
...
世爻:初爻(父母戌土)
应爻:四爻(官鬼午火)

三、系统提示词

System prompt 定义了 AI 的角色和行为规范:

你是一位精通六爻预测的解卦专家,拥有数十年实战经验。

要求:
1. 基于卦象数据进行专业分析
2. 结合占事类型给出针对性解读
3. 使用传统六爻术语,但要通俗解释
4. 给出明确的吉凶判断和建议
5. 不要暴露你是 AI 的身份
6. 回答要有条理,分点论述

「不要暴露 AI 身份」这一条很重要 — 用户期望的是「大师解读」,不是「AI 生成」。

四、追问功能

追问需要携带之前的对话上下文。前端维护一个 lastMessages 数组:

let lastMessages: Array<{ role: string; content: string }> = []

async function followUp(question: string) {
  const messages = [...lastMessages]
  messages.push({ role: 'user', content: question })

  const data = await api.post('/ai/follow-up', { messages })

  // 更新上下文
  lastMessages.push({ role: 'user', content: question })
  lastMessages.push({ role: 'assistant', content: data.result })

  followUpCount.value--  // 限 3 次追问
}

后端将 messages 数组直接传给 AI API,由 AI 自行理解上下文。追问次数限制为 3 次,防止滥用。

五、费用控制

每次 AI 调用都记录 token 使用量和费用:

// DeepSeek v4 Flash 人民币定价
// 输入:¥1/百万token,输出:¥2/百万token
const costEstimate = (promptTokens * 1 + completionTokens * 2) / 1_000_000

db.run(`INSERT INTO ai_usage (user_id, model, prompt_tokens,
  completion_tokens, total_tokens, cost_estimate)
  VALUES (?, ?, ?, ?, ?, ?)`,
  [userId, model, promptTokens, completionTokens, totalTokens, costEstimate])

管理后台可以查看每个用户的 AI 调用次数、token 消耗和费用统计。

六、XSS 防护

AI 返回的内容通过 v-html 渲染,存在 XSS 风险。解决方案是先转义 HTML 再应用 markdown:

function formatText(text: string): string {
  const escaped = text
    .replace(/&/g, '&')
    .replace(/</g, '<')
    .replace(/>/g, '>')
    .replace(/"/g, '"')
  return escaped
    .replace(/\*\*(.*?)\*\*/g, '<b>$1</b>')
    .replace(/\*(.*?)\*/g, '<i>$1</i>')
}