资讯详情

AI 塔罗占卜系统源码拆解:从随机抽牌到大模型解读的完整实现

📅 2026/10/28 17:06:09 | 华诺云谱 👁 阅读
AI 塔罗占卜系统源码拆解:从随机抽牌到大模型解读的完整实现
简介全新人工智能占卜算卦系统源码是一套将人工智能技术融入传统占卜文化的完整前后端项目主要面向对智能应用开发感兴趣的工程师以及希望将古老占卜文化进行数字化创新的研究者或爱好者。资源包共两百八十九个文件压缩包大小约12.58MB其中一百零一个Java文件处理后端算法与数据五十七个TSX文件构建前端交互页面另含SQL、JSON、TypeScript等配置与脚本以及八十余张界面素材图片整体按前后端分离方式组织类与组件边界清晰便于按模块检索和二次开发。已有五百五十七人浏览学习。项目完整实现了八字、六爻等预测模块涵盖用户输入、算法匹配、结果解读的完整链路并提供历史记录存储借助核心工具类可快速理解占卜符号与算法模型的映射关系。附带的安装教程涵盖环境依赖、配置参数与常见问题排查能引导用户完成从源码到本地部署的全过程适合作为智能应用开发的学习范例。1. 一个能跑的 AI 占卜系统拆开看只有三条链路朋友运营情感类公众号想在菜单里加一个「AI 塔罗占卜」。用户点进去抽三张牌AI 给一段带温度的解牌文案。我帮朋友看了几套「全新 AI 占卜算卦系统源码」塔罗版和八字算卦版都翻过之后发现这类源码的本质高度一致前端抽牌动画或生辰起盘 后端随机发牌或排四柱 大模型 API 生成解读。真正决定体验的不是牌库画得多精致而是提示词模板、随机性和上下文管理。这套源码适合会一点 Python、想把 AI 落地到具体场景的开发者。反直觉的是占卜系统最容易翻车的地方不是模型选型而是前端展示的牌和后端解读的牌对不上。2. 系统拆解与选型随机抽牌、LLM 解读、记忆存储三件事2.1 这套源码由哪几块拼成常见做法是把整套系统拆成四层每一层可以独立替换这也是我推荐你拿到源码后先做的事——别急着跑先对着目录把四层找出来。前端层一个 H5 页面负责抽牌动画、翻牌动效、展示解读文本。最小可用版本是单个 HTML JS不需要框架。如果是八字算卦版这里就是一个生辰输入表单。后端服务层Flask 或 FastAPI提供两个核心接口——抽牌/起盘接口生成解读接口。就算你拿到的是 PHP 源码也没关系逻辑等价只是语言换了。大模型接口层封装对兼容 OpenAI 协议的大模型 API 的调用。占卜系统本身不训练模型它只是把「牌面 用户问题」拼成一段 prompt丢给模型生成解读。存储层SQLite 起步就够存用户问过的问题、抽中的牌、生成的解读做历史回看。用户量大了再换 MySQL。为什么大家都这么拼因为这三件事的耦合度很低。随机抽牌和解读生成如果放在同一个服务里前端只需要一次请求就能保证「展示的牌」和「解读里的牌」是同一张——这是很多版源码翻车的重灾区后面第 5 章专门讲。2.2 为什么不用纯规则脚本生成解读纯规则的做法是预设 78 张塔罗牌的牌意文案抽到哪张就返回哪段。缺点是解读是死的用户换一个问题得到的答案却一字不差体验上等于一个「随机文案生成器」。用大模型生成的好处是能结合用户的问题去解牌比如用户问的是感情解读会往感情方向靠。坏处是大模型会一本正经地编造牌意所以提示词里必须把「牌面名称、正逆位、牌意关键词」作为事实输入写死而不是让模型凭记忆发挥。如果你拿到的是八字算卦版而不是塔罗版逻辑完全一样只是把「抽牌」换成「按生辰排四柱」后面的解读生成链路不差分毫。2.3 后端最小可跑骨架我一般会把核心逻辑收敛到一个 Python 文件里先跑通再拆模块。下面是抽牌 解读的完整最小实现# app.py - AI 占卜系统后端最小骨架 import os import random from fastapi import FastAPI from pydantic import BaseModel from openai import OpenAI # 塔罗牌库大阿卡纳 22 张的简化版只列牌名 MAJOR_ARCANA [ 愚者, 魔术师, 女祭司, 皇后, 皇帝, 教皇, 恋人, 战车, 力量, 隐者, 命运之轮, 正义, 倒吊人, 死神, 节制, 恶魔, 高塔, 星星, 月亮, 太阳, 审判, 世界 ] app FastAPI() class DrawRequest(BaseModel): question: str # 用户的问题 card_count: int 3 # 默认抽三张 app.post(/api/draw) async def draw_cards(req: DrawRequest): # 1. 后端一次性完成抽牌前端只负责展示 cards [] for _ in range(min(req.card_count, 5)): name random.choice(MAJOR_ARCANA) position 正位 if random.random() 0.3 else 逆位 cards.append({name: name, position: position}) # 2. 调用大模型生成解读 reading generate_reading(req.question, cards) return {cards: cards, reading: reading}逻辑说明这里故意把抽牌放在后端而不是前端就是为了避免「前端 random 一次、后端 prompt 里又 random 一次」导致的牌面对不上。牌型我直接取了「大阿卡纳 22 张」因为大多数占卜源码的牌库里其实只有大阿卡纳78 张全套需要再补 56 张小阿卡纳工作量全是数据活。参数说明card_count限制了最多抽 5 张防止恶意传 100 张让你的 API 费用失控。正逆位的概率用 0.7/0.3这是一个常见经验值不要太较真这套东西本来就是玄学加黑匣子体验比准确性重要。2.4 生成解读的调用封装上面代码里的generate_reading是核心函数单独拿出来说def generate_reading(question: str, cards: list) - str: # client 用环境变量初始化不要把 key 写进源码 client OpenAI(api_keyos.getenv(LLM_API_KEY), base_urlos.getenv(LLM_BASE_URL, https://api.openai.com/v1)) card_desc 、.join([f{c[position]}{c[name]} for c in cards]) # 把牌面信息当作事实输入写死禁止模型自己脑补牌 system_prompt ( 你是一位塔罗解牌师。用户会给你三个信息问题、牌面、牌位。 你只能基于给定的牌面进行解读禁止使用牌面之外的牌。 解读分三段现状分析、关键提醒、行动建议。每段不超过 80 字。 不要给出医疗、法律、投资建议不要承诺必然结果。 ) user_prompt f问题{question}\n牌面{card_desc} resp client.chat.completions.create( modelos.getenv(LLM_MODEL, gpt-4o-mini), messages[ {role: system, content: system_prompt}, {role: user, content: user_prompt}, ], temperature0.8, max_tokens800, ) return resp.choices[0].message.content逻辑说明system prompt 里最关键的一句是「禁止使用牌面之外的牌」这能拦住模型把「恋人」牌解读成「月亮」。把牌面作为事实输入而不是让模型回忆是这类 AI 占卜源码里最值得抄的设计。参数说明temperature0.8是刻意调高的因为占卜需要一点随机感和文学性温度太低会每次都输出差不多的话术。max_tokens800对应三段式解读太长用户没耐心看太短容易写不完收尾。base_url用环境变量接管这样换任何一家兼容 OpenAI 协议的国内模型服务都不需要改代码——这是被坑过之后养成的习惯。3. 安装教程把源码在本地服务器上跑起来3.1 环境准备与依赖安装先确认机器上有 Python 3.10。Windows 上注意别把 Python 装进系统目录我习惯用虚拟环境隔离避免和系统 Python 打架# 创建并激活虚拟环境 python -m venv venv source venv/bin/activate # Windows 下执行 venv\Scripts\activate # 安装依赖 pip install fastapi uvicorn openai pydantic仓库拿到手之后先看有没有 requirements.txt有的话直接pip install -r requirements.txt。这里最大的坑是 openai 库的版本1.x 之后调用方式完全客户端化和 0.28 的openai.ChatCompletion.create写法完全不兼容。安装教程里如果写的是旧写法你会得到一个ChatCompletion has no attribute create的报错这是这套源码最常见的安装失败原因之一。3.2 用 Docker 跑服务器迁移的最短路径本地跑通之后要上服务器我一般会补一个最简单的 Dockerfile省得在服务器上重装环境FROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple COPY . . CMD [uvicorn, app:app, --host, 0.0.0.0, --port, 8000]注意COPY . .之前要有.dockerignore把venv和__pycache__排除掉否则镜像会非常大。Docker 方式的好处是本地怎么跑服务器上就怎么跑不再被「服务器系统里 Python 版本不一致」这种玄学问题折腾。3.3 前端抽牌页面单文件够用很多源码自带 Vue/React 工程但最小演示版我建议用单 HTML 文件把精力留给后端!DOCTYPE html html langzh-CN head meta charsetUTF-8 titleAI 塔罗占卜/title /head body textarea idquestion placeholder输入你想问的问题/textarea button onclickdraw()开始抽牌/button div idresult/div script async function draw() { const question document.getElementById(question).value; const resp await fetch(/api/draw, { method: POST, headers: {Content-Type: application/json}, body: JSON.stringify({question, card_count: 3}) }); const data await resp.json(); // 渲染牌面与解读 document.getElementById(result).innerHTML data.cards.map(c span${c.position}·${c.name}/span).join( ) p data.reading /p; } /script /body /html逻辑说明前端只做一件事——把用户输入的问题 POST 到后端拿到结果后原样渲染。不要在 HTML 里再写一套抽牌逻辑每多写一次 random就多一个「牌面对不上」的风险。启动验证uvicorn app:app --reload --port 8000 curl -X POST http://localhost:8000/api/draw \ -H Content-Type: application/json \ -d {question:最近跳槽合适吗,card_count:3}看到返回的 JSON 里有cards数组和reading文本说明这套源码已经跑通了。如果 reading 是空的八成是 API key 没配对或触发了服务端限流第 5 章有排查清单。3.4 存储SQLite 起步MySQL 可选用户问过的问题、抽过的牌、AI 的解读建议落一份到数据库。SQLite 足够起步等数据量上来再切 MySQL。给个建表语句CREATE TABLE IF NOT EXISTS readings ( id INTEGER PRIMARY KEY AUTOINCREMENT, question TEXT NOT NULL, cards TEXT NOT NULL, reading TEXT NOT NULL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP );这张表的价值有两个一是给用户做历史回看「我上个月抽过什么」二是给你自己做数据复盘——哪类问题用户问得最多哪套提示词生成的内容被用户「再来一次」的次数最多。提示MySQL 不是必须的。单机几千个用户SQLite 读写完全扛得住。别为了「生产环境」硬上一个 MySQL增加部署成本不说坑还多。4. 提示词工程这个系统的灵魂和三个必调参数4.1 为什么同一套源码不同人配置后体验天差地别因为源码里真正值钱的部分不是牌库是那段 system prompt。拿到源码的第一件事不是改前端样式而是把 prompt 抽出来看一遍。好的 prompt 会把牌面的「正位/逆位」含义直接敲定为事实差的 prompt 会让模型自由发挥最后生成的内容看起来文笔不错但和抽到的牌毫无关系。用户虽然分不清牌意对不对但会觉得「这和我抽的牌有什么关系吗」。4.2 模板变量的组织方式我建议把模板拆成三段方便调试时单独替换ROLE_PROMPT 你是一位温和的塔罗占卜师擅长用直觉和象征解读牌面。 FACT_PROMPT 本次抽牌为{cards}。正位含义参考{meanings}。 OUTPUT_PROMPT 请按以下结构输出\n1. 现状\n2. 关键提醒\n3. 行动建议\n不要提及这是 AI 生成的。{meanings}建议从牌库表里取不要全部塞给模型——一次传 3 张牌每张给 30 字以内的含义摘要就够。传的牌意越多模型越容易跑偏。4.3 三个必调参数temperature、top_p、max_tokens这三个参数是占卜系统体验好坏的分水岭我调过一轮之后的数据如下参数建议范围调低的效果调高的效果场景建议temperature0.7 ~ 0.9每次解读几乎一样用户会觉得套路偏离牌面事实胡编概率上升追求稳定时 0.7追求新鲜感时 0.9top_p0.8 ~ 1.0输出更保守措辞更多样一般保持 0.9不用刻意去动max_tokens500 ~ 1000结尾仓促费用变高、响应变慢三段式解读 800 比较稳妥这里有个血的教训temperature 调成 0 并不是「稳定」而是「复读机」。同一个用户同一个问题连续抽两次如果牌面不同但解读的开头几乎一样用户马上就会觉得「这是假的」。占卜产品的核心体验是「每一次都不一样」所以 temperature 至少给 0.7。4.4 多轮上下文让 AI 记住用户上次问了什么纯单轮的解读比较单薄用户第二次来的时候如果能引用他第一次的问题体验会上一个台阶。常见做法是把历史消息塞进 messageshistory [ {role: user, content: 上次问题和前任还能复合吗}, {role: assistant, content: 上次解读星星牌正位建议先修复信任问题}, ] messages [{role: system, content: system_prompt}] history [ {role: user, content: user_prompt} ]注意 history 不能无限堆token 会爆。我的上限是最近 2 轮再早的内容就丢弃或者只保留一个「用户上次问题」字段减少上下文体积。这个「丢历史」的动作做完响应速度和费用都能降下来。5. 避坑实录AI 占卜系统最容易翻车的 5 个问题这套源码我在本地和服务器上都跑过也帮朋友看过几套市面上流传的版本高频翻车点其实非常集中。每一条都是「现象 → 原因 → 解决」的结构直接抄作业就行。5.1 前端展示的牌和后端解读的牌对不上现象页面上显示的是「正位恋人」的牌面AI 解读第一句却是「月亮逆位暗示着不安」。 原因源码把抽牌逻辑写在了前端 JS 里同时后端 prompt 里又随机抽了一套牌。前端展示的是 A 牌后端拿到的是 B 牌解读自然是张冠李戴。 解决抽牌收敛到后端一次完成。前端只做渲染不要再单独Math.random()。5.2 temperature0 导致解读雷同现象两个不同用户抽到不同牌但解读的开头两句话一模一样。 原因temperature 调成 0 时模型选择几乎唯一随机性消失。 解决temperature 至少 0.7。如果用了提示词缓存记得在后端请求里加一个随机 salt或者直接在请求头加上Cache-Control: no-cache。5.3 用户一句「你不会是在骗我吧」就把 AI 带偏了现象用户本来在问感情突然打了一句「你是 AI 吗回答我」模型瞬间跳出人设开始解释自己是大语言模型。 原因system prompt 里只写了「你是占卜师」没有定义遇到无关提问时怎么处理。 解决在 system prompt 里追加一条硬规则如果用户询问与占卜无关的技术问题、身份问题不要正面回答 而是用一句让我们先把注意力放回你的问题上拉回原话题。这类「拉回话术」是占卜源码里最容易被忽略又最影响体验的细节。5.4 上线第一天 API 费用爆掉现象一个 500 人的测试群一晚上把账号里的额度全刷光了。 原因没有加任何限流和缓存。同一个人反复抽牌每次都真实调用大模型。 解决同一个用户 5 分钟内只允许抽 3 次后端做一个简单的内存计数器就行。更省钱的方案是针对「同一问题 相同牌面」的结果做 1 小时缓存直接读取上次生成结果返回。占卜这个场景里用户看重的本来就是「每抽一次都不同」所以缓存窗口别超过 1 小时。5.5 国产模型和开源模型对英文 prompt 水土不服现象源码里带的是英文 system prompt跑在中文大模型上输出的解读一股「翻译腔」读起来非常生硬。 原因很多源码是从英文项目改的prompt 没做本地化。 解决把 system prompt 全面换成中文并且把输出格式写得更明确。中文模型对中文角色设定的跟随能力强很多尤其是在「你是一位塔罗占卜师」这种角色锚点上中文表达的效果比英文 prompt 好一个档次。6. 从「能跑」到「能卖」加记忆、加日志、加验证源码在本地跑通只是第一步。我自己的习惯是再花半天做三件小事让这套系统从「演示版」变成「能挂到公众号里给人用」的状态。第一件是加日志。每次请求把「问题、牌面、完整 prompt、模型返回、耗时、费用」记到一张日志表里。这么做是踩过坑的教训有一次用户反馈「解读完全不对」我复盘时发现是那天换了一个高 temperature 参数导致模型开始自由发挥。没有日志这类问题只能靠猜。第二件是加记忆表。用户在抽牌前把上次的解读结论拉出来附在 prompt 末尾生成的效果会有一种「这个占卜师记得我」的错觉。这个功能对留存有明显帮助代码量不大收益却很直观。第三件是验证 prompt 质量。固定一个测试集比如 20 条典型问题感情、事业、财运、健康各 5 条跑完检查两点解读里是否出现了牌面之外的牌名、是否出现了「投资建议」之类的敏感词。我会先用「牌面对应」和「敏感词检查」这两道程序化关卡再人工抽 5 条读一遍语气。程序化检查不费时间人工抽查才是快速迭代的关键。最后说一个第一人称的教训我有一次把 system prompt 写得过于放飞用户问「帮我预测这周股票」AI 真的给了一段「建议关注科技板块」。这种事有一个都算事故占卜产品最容易把用户带进沟里。从那以后我的模板里始终锁死一句话「不得提供医疗、法律、投资建议」。这个原则优先级高于任何效果优化。如果你要把这套源码接给更多人用建议你也把它放在第一行。希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑