用代码杀掉LLM:一个塔罗占卜游戏的程序化解读引擎

举报
哦啦啦啦啦 发表于 2026/08/20 18:38:23 2026/08/20
【摘要】 起因我有一个塔罗占卜的小程序,靠 LLM 驱动解读——用户抽牌,把牌面信息发给 LLM,LLM 返回一段解读文字。能用,但有几个问题:要花钱:每次解读都调 API要等:API 响应要 2-5 秒要联网:没网就用不了不稳定:LLM 有时候太诗意,有时候太敷衍,风格飘忽今天我决定把它改掉:完全脱离 LLM,纯程序逻辑解读。 思路:三层架构替代 LLMLLM 在塔罗解读里干三件事:提供塔罗知识、...

起因

我有一个塔罗占卜的小程序,靠 LLM 驱动解读——用户抽牌,把牌面信息发给 LLM,LLM 返回一段解读文字。

能用,但有几个问题:

  • 要花钱:每次解读都调 API
  • 要等:API 响应要 2-5 秒
  • 要联网:没网就用不了
  • 不稳定:LLM 有时候太诗意,有时候太敷衍,风格飘忽

今天我决定把它改掉:完全脱离 LLM,纯程序逻辑解读

思路:三层架构替代 LLM

LLM 在塔罗解读里干三件事:提供塔罗知识、生成解读语言、做牌面推理。我用三层程序化架构分别替代:

LLM 的知识  →  牌数据库(结构化含义查表)
LLM 的生成  →  模板引擎(位置类型选模板填数据)
LLM 的推理  →  规则逻辑(统计/扫描/分析/提取)

第一层:牌数据库替代 LLM 的"知识"

cards-data.js,415 行,包含完整 78 张塔罗牌的数据。每张牌都有正位和逆位的含义、关键词、建议:

{
  id: 0, nameCn: "愚者", nameEn: "The Fool", element: "风",
  upright: {
    keywords: ["新开始", "天真", "自由", "冒险"],
    meaning: "代表全新的开始与无限可能,带着天真无畏的心态踏上旅程。",
    advice: "保持开放心态,勇敢迈出第一步,不必过度计划。"
  },
  reversed: {
    keywords: ["鲁莽", "轻率", "风险", "未准备"],
    meaning: "因鲁莽轻率而陷入风险,缺乏准备就贸然行动。",
    advice: "行动前先评估风险,做好基础准备再出发。"
  }
}

78 张牌 × 2 种状态 = 156 条结构化含义,全部预置在代码里。LLM 原本"知道"的塔罗知识,现在变成了查表。

第二层:模板引擎替代 LLM 的"语言生成"

interpret-engine.js,334 行,这是替代 LLM 的核心。

解读引擎根据牌阵中每个位置的类型(过去/现在/未来/挑战/建议等),选择不同的句式模板,填入牌的数据:

位置类型 模板句式
过去 “过去因为【牌名】的影响,【含义】”
现在 “目前呈现【牌名】的状态,【含义】”
未来 “接下来可能会向【牌名】所示的方向发展”
挑战 “主要挑战来自【牌名】,意味着【含义】”
建议 “建议你【牌的 advice 字段】”

拼接成完整的因果分析段落。不需要 LLM 生成自然语言,模板填充就够了。

第三层:规则逻辑替代 LLM 的"推理"

解读引擎用规则逻辑完成 LLM 原本的"推理"工作:

  • 整体基调:统计逆位牌数量 → 0 张积极 / 1-2 张需注意 / 3+ 张挑战多
  • 问题识别:扫描逆位牌和传统负面牌(死神、高塔、恶魔),列出实际问题
  • 牌面互动:分析相邻牌的元素(火水风土)关系 → 同元素增强、相克冲突
  • 建议生成:优先取"建议"位置的牌的 advice,结合逆位牌的应对建议,生成编号列表

8 种牌阵

支持 8 种预定义牌阵,位置含义全部固定,不允许自行发明新位置:

  1. 单张牌阵(1 张)— 当前最核心的信息
  2. 三张经典牌阵(3 张)— 过去、现在、未来
  3. 五张牌阵(5 张)— 当前状况、挑战、过去影响、未来潜力、行动建议
  4. 凯尔特十字牌阵(10 张)— 经典全分析
  5. 马蹄牌阵(7 张)— 过去到结果的完整路径
  6. 关系与情感牌阵(7 张)— 双方感受与关系发展
  7. 事业与人生方向牌阵(6 张)— 当前阶段到长期指引
  8. 决策二选一牌阵(8 张)— 两个选项的对比决策

开发过程

整个项目在华为云 CodeArts 沙盒里完成,用 AI 编码助手生成代码,全程约 15 分钟。

项目结构

tarot-game/
├── index.html          (66)   主页面
├── style.css           (391)  深色神秘风格样式
├── cards-data.js       (415)  78 张牌完整数据库
├── spreads-data.js     (132)  8 种牌阵定义
├── interpret-engine.js (334)  解读引擎核心
└── app.js              (250)  主逻辑(牌阵选择/抽牌/动画/渲染)

总计约 1588 行代码,纯 HTML + CSS + JavaScript,无后端,无依赖,无构建工具。

解读风格

解读风格有严格要求:简单直接,像日常对话,用"因为…所以…“的因果逻辑,不用"能量流动”“高维指引”"灵魂觉醒"等抽象表达。重点说发生了什么、为什么、该怎么做。忠于牌面,不讨好,负面牌就直说问题。

输出格式固定为四段:

  1. 【牌阵总览】 — 一句话概括核心信息
  2. 【深度解析】 — 抽牌过程 + 因果分析 + 问题阻碍 + 牌面互动
  3. 【神谕指引】 — 3-4 条可执行建议
  4. 【结语】 — 固定免责声明

效果对比

LLM 方案 纯程序方案
解读质量 更灵活自然 结构化、一致性好
运行成本 每次调 API 零成本
响应速度 2-5 秒 瞬间
可离线
风格一致 可能跑偏 严格遵循规则
代码量 prompt + API 调用 1588 行纯前端

纯程序方案的解读质量确实不如 LLM 灵活——没有那些出人意料的联想和隐喻。但它赢在确定性:每次同样的牌面出同样的解读,不会今天诗意明天敷衍。对于塔罗这种有固定含义体系的场景,结构化解读反而更靠谱。

总结

这次开发最有趣的部分不是写代码,而是设计解读引擎的架构——把 LLM 的三个能力(知识、生成、推理)拆开,分别用程序化方案替代。

核心洞察是:塔罗牌的解读体系本身就是高度结构化的。每张牌有固定含义,每个位置有固定作用,解读遵循因果逻辑。这种结构化场景,恰恰是程序化方案比 LLM 更合适的地方。LLM 的优势在于开放性创作,而塔罗解读不需要开放性——它需要的是准确性和一致性。

用 1588 行代码,换掉了一个持续消耗 API 费用的 LLM 调用链。值。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。