AI 解卦助手的实现:后端代理与多轮对话管理
将大语言模型集成到六爻应用中的完整实践,包括 Prompt 工程、对话上下文管理和费用控制。
一、架构设计
AI 解读功能采用后端代理架构,前端不直接调用 AI API:
前端 App → POST /api/ai/analyze → 后端代理 → AI API → 返回结果
这样做的好处:
- 安全:API Key 只存在后端 .env 中,不暴露给客户端
- 可控:后端可以记录使用量、限流、统计费用
- 灵活:切换 AI 模型只需改后端配置
二、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>')
}