引言
本文将介绍如何利用大语言模型(LLM)与思维链(CoT)Prompt 设计 ,将传统塔罗小程序中生硬的"查表式解牌",重构为一个具备多轮对话能力、上下文理解力的智能咨询系统。
从技术视角看,塔罗咨询并不是预测未来,而是一个典型的:
符号语义提取(牌义) + 用户语境注入(问题) + 心理疏导话术(冷读术)的文本生成问题
本文将给出一个完整示例,演示如何实现一个 "看起来像神秘学大师,实际是基于符号逻辑的心理咨询文本生成系统"。
商务合作:18094708823
1. 项目背景
市面上的塔罗小程序多采用"数据库匹配"模式,逻辑如下:
-
用户抽到"愚人牌"。
-
后台查询
DB,返回"愚人牌"的固定描述字段。 -
缺陷: 无论用户问"恋爱"还是"事业",返回的解释都是同一段话,割裂感极强。
这类实现方式的问题在于:
-
无法结合语境: 忽略了用户具体的困惑。
-
交互性为零: 只能看,不能聊。
-
用户留存差: 测一次就没新鲜感了。
本文尝试使用 大语言模型 + 动态 Prompt ,实现一个: 根据用户具体问题,动态生成牌面解读的咨询系统 从而将"抽签"升级为一次深度的"心理疗愈对话"。
2. 产品示意图

3. 技术架构
为了规避微信小程序直接连接海外 API 的风险,建议采用中间层转发架构:
代码段
微信小程序 (前端)
|
| 1. 输入问题 + 抽牌动作
v
Node.js / Python 后端 (中间层)
|
| 2. 随机算法抽牌 + 组装 Prompt
v
大语言模型 API (如文心/通义/DeepSeek)
|
| 3. 生成解读文本
v
返回流式数据 (Stream)
该架构的核心在于: 前端只负责"仪式感"(洗牌动画),真正的"解牌逻辑"完全由后端 Prompt 驱动。
4. 小程序端:交互与数据传递
4.1 页面示例
用户输入问题,点击抽牌,展示结果。
HTML
<input placeholder="心中默念你的问题..." bindinput="inputQuestion" />
<button bindtap="drawCard">点击抽牌</button>
<view class="card-area" wx:if="{{cardName}}">
<image src="{{cardImage}}"></image>
<view class="card-name">{{cardName}} ({{position}})</view>
</view>
<text class="result-text">{{interpretation}}</text>
4.2 页面逻辑
JavaScript
// index.js
Page({
data: {
question: '',
cardName: '',
interpretation: ''
},
drawCard() {
if (!this.data.question) return wx.showToast({title: '请先输入问题'});
wx.showLoading({ title: '大师感应中...' });
wx.request({
url: 'https://your-server/api/tarot-read',
method: 'POST',
data: {
question: this.data.question
},
success: res => {
this.setData({
cardName: res.data.card, // 如:宝剑三
position: res.data.position, // 如:逆位
interpretation: res.data.text // AI生成的长文本
});
wx.hideLoading();
}
})
}
})
5. 后端:牌义映射与接口实现
5.1 塔罗牌基础数据结构
后端不需要存储长篇大论的解释,只需要存储核心符号含义(Keywords),具体的"造句"交给 LLM。
JavaScript
// tarot_data.js
const tarotDeck = {
"fool": {
name: "愚人",
keywords_up: ["新的开始", "冒险", "天真", "自由"], // 正位关键词
keywords_rev: ["鲁莽", "风险", "愚蠢", "混乱"] // 逆位关键词
},
"magician": {
name: "魔术师",
keywords_up: ["创造力", "能力", "专注", "显化"],
keywords_rev: ["欺骗", "能力不足", "犹豫", "操纵"]
}
// ... 共78张牌的数据
};
5.2 解读接口实现
JavaScript
// server.js (Express示例)
app.post('/api/tarot-read', async (req, res) => {
const userQuestion = req.body.question;
// 1. 简单的随机抽牌逻辑
const cardKeys = Object.keys(tarotDeck);
const randomKey = cardKeys[Math.floor(Math.random() * cardKeys.length)];
const isUpright = Math.random() > 0.5; // 50%概率正逆位
const cardInfo = tarotDeck[randomKey];
const positionStr = isUpright ? "正位" : "逆位";
const keywords = isUpright ? cardInfo.keywords_up : cardInfo.keywords_rev;
// 2. 构建 Prompt
const prompt = buildTarotPrompt(userQuestion, cardInfo.name, positionStr, keywords);
// 3. 调用 LLM
const aiResponse = await callLLM(prompt);
res.json({
card: cardInfo.name,
position: positionStr,
text: aiResponse
});
})
6. Prompt 设计思路
在塔罗场景中,Prompt 的设计目标是让 AI 扮演一位**"高情商的咨询师"**。它必须具备以下特征:
-
关联性: 必须强行将"牌面含义"与"用户问题"联系起来(即使逻辑很牵强,也要通过隐喻连接)。
-
治愈性: 语气要温柔、神秘,多用"可能"、"能量"、"指引"等词汇。
-
合规性: 严禁给出医疗、法律建议,严禁宣扬封建迷信,必须强调"心理投射"。
7. 推荐 Prompt(可直接使用)
角色设定
你是一位经验丰富的塔罗牌咨询师,擅长荣格心理学与共情倾听。你的语言风格神秘、优雅、充满治愈感,类似于文学小说中的智者。
任务说明
用户提出了一个问题,并抽取了一张塔罗牌。 请根据用户问题 、牌面名称 、正逆位状态 以及核心关键词,为用户进行解读。
输入信息
用户困惑: {user_question} 抽取卡牌: {card_name} ({position}) 牌面核心含义: {keywords}
输出要求
-
不要机械解释牌义: 不要说"这张牌代表...",而是说"这张牌的出现,暗示着你当下的心境..."。
-
结合具体问题: 如果问感情,就不要谈事业。
-
结构化输出:
- 【象限解析】: 简述牌面传达的能量。
- 【当下指引】: 针对用户问题的具体分析
- 【心灵建议】: 一句富有哲理的行动建议。
避坑指南: 结尾必须包含"塔罗仅为潜意识的镜子,命运掌握在自己手中"的免责声明。
输出风格示例
"宝剑三的逆位并不意味着痛苦的结束,而是提醒你,那些压抑的情绪正在寻求释放的出口。在感情中,你是否一直在逃避那个让你受伤的真相?..."
8. Prompt 构建函数示例
JavaScript
function buildTarotPrompt(question, cardName, position, keywords) {
return `
你是一位精通心理学的塔罗咨询师。
用户正在询问:"${question}"
他抽到的牌是:【${cardName}】处于【${position}】。
这张牌的核心关键词是:${keywords.join(', ')}。
请用大约 200 字,温柔且富有洞察力地解读这张牌对用户问题的启示。
请避免宿命论的断言,更多关注用户的心理状态和行动建议。
`;
}
9. 总结
从工程角度看,AI 塔罗咨询室本质上是一个:
随机数生成器(抽牌) + 知识图谱(牌义库) + 风格化文本生成(Prompt)
通过引入大语言模型,我们解决了传统算命软件"千人一面"的痛点。AI 能够利用其强大的联想能力,将看似不相关的"牌义"和"问题"通过逻辑和修辞"缝合"在一起,从而产生极具说服力的"巴纳姆效应"体验。