前情提要:从"精装修"到"智能豪宅"的AI对话系统进化史
在《基于DeepSeek的沉浸式对话网站开发实战》系列的前两篇中,我们完成了从"毛坯房"到"精装修"的华丽蜕变:
🔧 第一篇:极简三件套
- 用纯HTML+CSS+JavaScript搭建骨架
- 通过fetch直接调用DeepSeek API实现跨时空对话
- 提示词工程让AI秒变历史人物(如"你现在是李白,要狂放不羁")
- GitHub Pages一键部署的"丐版"解决方案
🎨 第二篇:视觉与记忆革命
- 聊天气泡动画+角色头像+背景图片,让文字对话变成"会动的画面"
- localStorage实现对话历史持久化,告别"七秒记忆鱼"式聊天
- 安全加固:API密钥不再裸奔(虽然具体方案卖了个关子)
而现在,我们要将这个系统升级成"智能豪宅"!
本期内容:
🏠 【主页实现】
- 动态角色广场:角色卡片(头像+简单介绍)
- 智能体分类:可选择不同类型以查找不同类型智能体
- API密钥输入功能:不再需要在前端写入API-KEY
🎵 【背景音乐功能实现】
- 情境化音效:匹配角色时代背景的BGM(如李白出现时播放古琴曲)
🧠 【多智能体隔离存储】
- 角色专属记忆:每个AI角色拥有独立的localStorage命名空间
🏠 主页功能实现
这段代码就像是一个"历史人物双面镜",让我们用有趣的方式来解读它:
-
威名显赫 vs 名匿青史
这组选项卡就像历史舞台的聚光灯切换键:- 点击"威名显赫":聚光灯打在曹操、霍去病这些自带光环的历史主角身上
- 点击"名匿青史":灯光照向锦衣卫这些幕后操盘手
-
卡片设计小心机
每个角色卡片都是精装的"历史手账":<div class="agent-card" onclick="location.href='...'"> <img src=".../caocaohead.png"> <!-- 曹老板的证件照 --> <div class="agent-desc">...</div> <!-- 微博式简介 --> </div>
点击卡片就像打开任意门,直接穿越到角色专属剧场
-
CSS魔法时刻
active
类像是给按钮贴"朕已阅"标记 -
历史梗埋点
选项卡命名暗藏玄机:- "威名显赫"组都是史书单独列传的大佬
- "名匿青史"组连名字都不配拥有(锦衣卫:我实名举报这个分类!)
<!-- 添加选项卡 -->
<div class="tab-container">
<div class="tab-header">
<button class="tab-btn active" onclick="switchTab('characters')">威名显赫</button>
<button class="tab-btn" onclick="switchTab('nameless')">名匿青史</button>
</div>
<div id="characters-tab" class="tab-content active">
<!-- 现有的人物卡片容器 -->
<div class="agents-container">
<div class="agent-card" onclick="location.href='characters/曹操/caocao.html'">
<img src="characters/曹操/caocaohead.png" class="agent-avatar" alt="曹操">
<div class="agent-name">曹操</div>
<div class="agent-desc">曹操,字孟德,小字阿瞒,沛国谯县人,东汉末年丞相、权臣、政治家、军事家、文学家、诗人、书法家,魏王,曹魏政权奠基者。</div>
</div>
<div class="agent-card" onclick="location.href='characters/霍去病/huoqubing.html'">
<img src="characters/霍去病/huoqubinghead.png" class="agent-avatar" alt="霍去病">
<div class="agent-name">霍去病</div>
<div class="agent-desc">霍去病,河东郡平阳县人,西汉时期名将、军事家、民族英雄。</div>
</div>
</div>
</div>
<div id="nameless-tab" class="tab-content">
<div class="agents-container">
<div class="agent-card" onclick="location.href='characters/锦衣卫/jinyiwei.html'">
<img src="characters/锦衣卫/jinyiweihead.png" class="agent-avatar" alt="锦衣卫">
<div class="nameless-name">锦衣卫</div>
<div class="nameless-desc">锦衣卫为明朝特务机构,直属皇帝,掌侍卫、缉捕、刑狱,权势大,对明朝政治影响深远。</div>
</div>
</div>
</div>
</div>
/* 修改背景遮罩层颜色 */
body::before {
background: rgba(0, 0, 0, 0.4);
/* 从0.2改为0.4增加黑色浓度 */
backdrop-filter: blur(8px);
}
.agent-card {
background: rgba(0, 0, 0, 0.3);
/* 新增深色卡片背景 */
color: white;
/* 文字改为白色 */
}
.agent-desc {
color: rgba(255, 255, 255, 0.8);
/* 描述文字改为浅灰色 */
}
/* 调整悬停效果透明度 */
.agent-card:hover {
background: rgba(255, 255, 255, 0.7);
/* 悬停时稍微减少透明度 */
color: black;
/* 悬停时文字变黑色 */
}
.agent-card:hover .agent-name,
.agent-card:hover .agent-desc {
color: black;
/* 确保名称和描述都变黑 */
}
🔑 API密钥安全输入:代码版"藏宝图"
你的API密钥就像古代虎符——丢了它,你的AI大军就会变成"无头苍蝇"。来看看这段代码如何用现代密码学+一点幽默保护你的密钥:
// 1. **"虎符"藏宝箱**(localStorage版)
this.API_KEY = localStorage.getItem('apiKey') || '';
// 如果没找到密钥,AI会变成"哑巴将军"(空字符串)
// 2. **锦衣卫密探输入法**(弹窗版)
document.getElementById('api-key-btn').addEventListener('click', () => {
const key = prompt("🗝️ 请输入DeepSeek API密钥:\n(别担心,我们会像保护传国玉玺一样藏好它)");
if (key) {
localStorage.setItem('apiKey', key); // 塞进"密室"
this.API_KEY = key; // 现在AI能说话了!
alert("密钥已加密存入凌烟阁地下室!");
} else {
alert("⚠️ 您取消了输入,AI将继续保持沉默...");
}
});
代码彩蛋解析 🥚
-
localStorage
= 大明宝库- 比直接写在代码里安全(至少不会被
Ctrl+F
搜到) - 但依然建议最终升级为后端代理API(相当于派锦衣卫24小时看守)
- 比直接写在代码里安全(至少不会被
-
Prompt弹窗 = 城门守卫
那个可爱的🗝️emoji是故意加的——黑客看到会愣0.3秒,给你争取关页面的时间(本人未采用) -
空白密钥 = 哑巴模式
如果用户没输入密钥,AI会优雅地闭嘴(而不是报错崩掉)就像锦衣卫发现假虎符时的沉默
进阶建议 🚀
// 3. **火漆封印"加强版**(Base64伪装)
const saveKey = (key) => {
const sealedKey = btoa(key + "|" + Date.now()); // 加时间戳混淆
localStorage.setItem('apiKey', sealedKey);
};
// 使用时解密
const loadKey = () => {
const sealedKey = localStorage.getItem('apiKey');
return sealedKey ? atob(sealedKey).split("|")[0] : ""; // 取出真正的密钥
};
这相当于给虎符裹了一层蜡封,虽然专业黑客还是能破,但能防住99%的脚本小子
🎵 背景音乐功能:AI版"宫廷乐师"
1. 角色BGM歌单 📜
const musicMap = {
'李白': 'guzheng', // 诗仙出场自带古筝solo
'霍去病': 'battle-drum', // 战神BGM必须是战场擂鼓
'牛顿': 'piano' // 科学家的优雅钢琴曲
};
- 彩蛋:如果角色没在歌单里(比如外星人👽),会默默播放
default.mp3
(可能是《新闻联播》片头曲)
2. 音乐开关の小心机 🔄
audio.loop = true; // 单曲循环,直到用户崩溃
- 像唐朝宫廷乐师一样执着:"陛下,这首《霓裳羽衣曲》臣能再弹500遍!"
- 但比乐师聪明:用
audio.paused ? play() : pause()
实现一键静音,避免被用户赐死(误)
3. 隐藏玩法预告 🎮
// 未来可以加入:
audio.volume = 0.3; // 默认音量调低,防止用户被霍去病的战鼓震聋
audio.addEventListener('play', () => {
console.log("🎼 正在播放:" + this.characterName + "主题曲");
// 偷偷在控制台打印彩蛋日志
});
相当于给BGM加了史官记录功能,连播了几次《广陵散》都给你记在小本本上!
代码示例:
// 根据角色匹配BGM
getMusicForCharacter() {
const musicMap = {
'李白': 'guzheng',
'霍去病': 'battle-drum',
'牛顿': 'piano'
};
return musicMap[this.characterName] || 'default';
}
// 音乐控制
initMusicControls() {
const audio = new Audio(`/musics/${this.getMusicForCharacter()}.mp3`);
audio.loop = true;
document.getElementById('music-toggle').addEventListener('click', () => {
audio.paused ? audio.play() : audio.pause();
});
}
🧠 多智能体隔离存储:AI版"平行宇宙档案馆"
就像给每个历史人物建了个专属记忆宫殿,让他们互不干扰,完美实现"霍去病不懂牛顿力学,牛顿不会背李白的诗"的史诗级隔离!
1. 角色专属命名空间 🏛️
localStorage.setItem(`chatHistory_${this.characterName}`, ...);
- 相当于:
- 给李白开个
chatHistory_李白
文件夹,存他的"醉后语录" - 给牛顿开个
chatHistory_牛顿
文件夹,放他的"苹果砸头日记"
- 给李白开个
- 防串戏机制:
- 就算你和李白聊到"举杯邀明月",霍去病也不会突然插话:"这月亮适合夜袭匈奴!"
2. 跨会话隔离 🚧
loadHistory() {
const savedHistory = localStorage.getItem(`chatHistory_${this.characterName}`);
if (savedHistory) this.messageHistory = JSON.parse(savedHistory);
}
- 相当于:
- 每次召唤霍去病,系统自动调取他的"作战记录",不会混进曹操的"篡位心得"
- 如果没存档(比如第一次聊),AI会乖巧地从欢迎语开始,而不是胡言乱语
3. 记忆清洗功能 🧹
localStorage.removeItem(`chatHistory_${this.characterName}`);
- 相当于:
- 点"清空历史" = 让AI喝下孟婆汤(仅限当前角色)
- 比如你和李白聊崩了,一键删除他的"黑历史",下次见面他还是那个"仰天大笑出门去"的诗仙
- 不会误伤:清空李白,牛顿的记忆依然完好无损(科学家的尊严保住了!)
4. 隐藏彩蛋 🥚
// 如果未来想搞事情,可以加:
localStorage.setItem(`chatHistory_穿越模式`, JSON.stringify([
{ role: "system", content: "霍去病和汉武帝在青楼相遇..." }
]));
- 恶趣味:偷偷建个
chatHistory_穿越模式
,让霍去病和汉武帝跨时空对线(但正经项目别这么玩😂)
这段代码用键值对+角色名后缀,实现了:
- 曹操的奸雄语录 ≠ 霍去病的战场报告
- 一键删除某个角色的记忆,不影响其他人
- 未来扩展:随时新增角色,自动分配独立记忆库
就像给每个AI角色发了专属U盘,存他们的"人生回忆",绝不混用! 🚀
🏁 结语:从代码到穿越,你只差一个回车键
在这趟AI历史穿越之旅中,我们:
-
造了时光机
- 用
localStorage
给每个古人建了记忆宫殿 - 靠
fetch
从数字长河捞出李白、霍去病们的灵魂碎片
- 用
-
发明了跨次元音响
- 让古琴声随诗人出场自动播放
- 战鼓声在将军说话时自动渐强(虽然代码没写,但你可以脑补)
-
制定了时空管理局条例
- 严禁牛顿偷看李白写诗(多智能体隔离存储)
- 允许用户一键清除黑历史(比《黑衣人》的记忆消除器还好用)
欢迎各位大神在评论区交流、讨论、指正、建议、批评