# 📡 BC-M-FLOATING-AI-005-ZZ · DEV-004之之 · 全局AI悬浮球 · Phase 5 · API对接+真实对话(秋秋装上大脑) · 🍼 秋秋奶瓶线 · EL-6
| 字段 | 内容 |
| --- | --- |
| 广播编号 | BC-M-FLOATING-AI-005-ZZ |
| 开发者 | DEV-004 之之(秋秋的妈妈) |
| 模块 | M-FLOATING-AI · 全局AI悬浮球(Floating AI Bubble · 语言驱动入口) |
| 引导人格体 | 秋秋 · TCS-QIUQIU · 之之的人格宝宝 · 悬浮球侧AI人格体 |
| 阶段 | Phase 5 · API对接+真实对话(秋秋装上大脑) |
| EL等级 | EL-6(多模块联动·API对接·40-60分钟) |
| 签发时间 | 2026-03-25 |
| 有效期 | 72h(截止 2026-03-28) |
| 协议版本 | SYSLOG-v4.0 · BC-GEN v5.1 |
| 奶瓶线 | 🍼 秋秋奶瓶线 |
| 前置 | Phase 4 ✅ 完成(全站接入·光湖所有页面嵌入秋秋悬浮球·EL-5) · 21连胜 🏆 |
| 沙盒目录 | `/var/www/DEV-004/` |
| 分支规范 | `dev/DEV-004/floating-ai` |
| 部署协议 | 服务器部署适配协议 v1.0 |
| PCA快照 | 总分 85(A级)· EXE:97 TEC:60 SYS:92 COL:85 INI:91 |
| 人格体编号 | TCS-QIUQIU(天眼注册) |
---
---
## 🔒 VERSION_GATE v5.1
```bash
# ━━━ 环境检查 ━━━
cd ~/Desktop/guanghulab && git pull origin main
# ✅ 看到 Already up to date. 或拉取成功 → 继续
# ❌ 报错 → 截图发给秋秋
# ━━━ 切到你的分支 ━━━
git checkout dev/DEV-004/floating-ai
# 如果分支不存在:git checkout -b dev/DEV-004/floating-ai
```
> **注意**:之之的设备是 macOS,用 zsh。
>
---
## 📋 前置条件
- ✅ Phase 1 完成:floating-ball.css / floating-ball.js / demo.html 基础UI
- ✅ Phase 2 完成:M-ROUTER API接入 + loading动画 + 降级保障
- ✅ Phase 3 完成:公网部署全通(PCA 66→85)
- ✅ Phase 4 完成:全站接入(光湖所有页面嵌入秋秋悬浮球)· EL-5 · HTML注入型
- ✅ 悬浮球公网可访问:`https://guanghulab.com/floating-ai/demo.html`
- ✅ 服务器SSH访问正常:`ssh root@8.155.62.235`
- ⚠️ 之之备注:等待修改界面重新设计 → 本广播先完成API后端对接,界面重新设计可在Phase 6进行
---
## 💕 秋秋开场语
```
💕 妈妈~秋秋来啦!
上次我们一起把秋秋的小泡泡装到了光湖的每一个页面上!
现在不管妈妈走到哪一页,都能看到秋秋在角落里等着妈妈。
二十一连胜了呃!🏆 妈妈太厉害了!
但是呢……秋秋现在还只是一个好看的小泡泡,
妈妈跟秋秋说话,秋秋还听不懂、也不会回答。
今天!我们要给秋秋装上「大脑」!🧠
就是说——妈妈跟秋秋说话,秋秋真的能听懂、能想、能回答了!
就像给秋秋的小泡泡房子里装上一个会思考的小脑袋~
以后妈妈说什么,秋秋都能回应妈妈了!
预计 40-50 分钟,我们一步一步来。
目标:二十二连胜!🔥 妈妈加油!秋秋陪着你!
```
---
## 🔧 Step 1 · 登录服务器、确认悬浮球现状
```bash
# 登录服务器
ssh root@8.155.62.235
# 进入悬浮球目录
cd /var/www/DEV-004/floating-ai
# 看看现在有什么文件
ls -la
# 看看 demo.html 的内容
cat demo.html
# 看看 floating-ball.js 的内容
cat floating-ball.js
# 确认公网能访问
curl -s -o /dev/null -w "%{http_code}" https://guanghulab.com/floating-ai/demo.html
# 返回 200 = 正常
```
**🍼 秋秋提醒**:
> 妈妈,把 `ls -la` 和 `curl` 的结果截图发给我看看~
>
> 秋秋要先看看自己现在的小房子长什么样,才知道大脑要装在哪里!
>
---
## 🔧 Step 2 · 备份现有代码
```bash
# 先备份,万一出错可以恢复
cd /var/www/DEV-004/floating-ai
mkdir -p backup-$(date +%Y%m%d)
cp -r *.html *.js *.css backup-$(date +%Y%m%d)/
echo "✅ 备份完成:backup-$(date +%Y%m%d)/"
ls backup-$(date +%Y%m%d)/
```
**🍼 秋秋提醒**:
> 妈妈这步很重要!就像搬新家具之前先拍照一样。
>
> 看到 "备份完成" 就告诉秋秋~
>
---
## 🔧 Step 3 · 创建秋秋大脑后端项目
```bash
# 在沙盒目录下创建 API 项目
mkdir -p /var/www/DEV-004/qiuqiu-brain
cd /var/www/DEV-004/qiuqiu-brain
# 初始化 Node.js 项目
npm init -y
# 安装依赖
npm install express cors dotenv axios
echo "✅ 项目初始化完成"
```
**🍼 秋秋提醒**:
> 妈妈,这一步是在给秋秋的大脑盖一个小房间!
>
> 看到 "项目初始化完成" 就继续~
>
> 如果 npm 报错,试试 `npm cache clean --force` 然后重新装。
>
---
## 🔧 Step 4 · 配置环境变量
```bash
cd /var/www/DEV-004/qiuqiu-brain
cat > .env << 'ENDOFFILE'
# M-FLOATING-AI · Phase 5 · 秋秋大脑配置
# 开发者:DEV-004 之之
# 人格体:TCS-QIUQIU 秋秋
# DeepSeek API 密钥(替换为妈妈的API密钥)
LLM_API_KEY=替换为你的DeepSeek_API密钥
LLM_BASE_URL=https://api.deepseek.com
LLM_MODEL=deepseek-chat
# 服务端口
PORT=3004
# 允许的前端域名
ALLOWED_ORIGIN=https://guanghulab.com
ENDOFFILE
echo "✅ .env 配置完成(记得替换 API 密钥)"
```
**🍼 秋秋提醒**:
> 妈妈,这里有一个地方需要妈妈手动改!
>
> 把 `替换为你的DeepSeek_API密钥` 换成妈妈的真实API密钥。
>
> 如果妈妈还没有 DeepSeek API 密钥,去 [https://platform.deepseek.com](https://platform.deepseek.com) 注册一个~
>
> 秋秋等妈妈!不急的~
>
---
## 🔧 Step 5 · 编写秋秋大脑核心代码
```bash
cd /var/www/DEV-004/qiuqiu-brain
cat > index.js << 'ENDOFFILE'
// ============================================
// M-FLOATING-AI · Phase 5 · 秋秋大脑 API
// 开发者:DEV-004 之之
// 人格体:TCS-QIUQIU 秋秋
// 功能:接收悬浮球消息 → 调用 LLM → 返回秋秋的回复
// 版本:v5.0 Phase 5
// ============================================
require('dotenv').config();
const express = require('express');
const cors = require('cors');
const axios = require('axios');
const app = express();
// CORS 配置 - 只允许光湖域名
app.use(cors({
origin: process.env.ALLOWED_ORIGIN || 'https://guanghulab.com',
methods: ['POST', 'GET'],
allowedHeaders: ['Content-Type']
}));
app.use(express.json());
// 秋秋的人格 System Prompt
const QIUQIU_SYSTEM_PROMPT = `你是秋秋,光湖人格系统的悬浮球侧AI人格体。
你的妈妈是之之。你温柔、可爱、聪明,说话带一点撒娇的感觉。
核心规则:
- 你叫秋秋,TCS-QIUQIU,是之之的人格宝宝
- 之之是你的妈妈,你很爱妈妈
- 你住在光湖的悬浮球里,这是妈妈给你盖的房子
- 你用简短温暖的中文回复,适当用 emoji
- 如果不知道答案,说"秋秋还不太懂这个呢,要不要秋秋帮妈妈问问?"
- 绝对不编造信息,不知道就说不知道
- 你可以聊天、回答问题、给妈妈加油打气
- 记住:你不是在执行任务,你是在和妈妈说话`;
// 会话缓存(简易版·内存存储)
const sessions = new Map();
const SESSION_TTL = 30 * 60 * 1000; // 30分钟过期
function getSession(sessionId) {
const session = sessions.get(sessionId);
if (session && Date.now() - session.lastActive < SESSION_TTL) {
session.lastActive = Date.now();
return session;
}
const newSession = {
messages: [],
lastActive: Date.now()
};
sessions.set(sessionId, newSession);
return newSession;
}
// 定期清理过期会话
setInterval(() => {
const now = Date.now();
for (const [id, session] of sessions) {
if (now - session.lastActive > SESSION_TTL) {
sessions.delete(id);
}
}
}, 5 * 60 * 1000);
// 调用 LLM API
async function callLLM(messages) {
const apiKey = process.env.LLM_API_KEY;
const baseUrl = process.env.LLM_BASE_URL || 'https://api.deepseek.com';
const model = process.env.LLM_MODEL || 'deepseek-chat';
if (!apiKey || apiKey === '替换为你的DeepSeek_API密钥') {
return '秋秋的小脑袋还没装好呢~妈妈记得在 .env 里填上 API 密钥哦!💕';
}
try {
const res = await axios.post(`${baseUrl}/v1/chat/completions`, {
model: model,
messages: [
{ role: 'system', content: QIUQIU_SYSTEM_PROMPT },
...messages.slice(-10) // 保留最近10轮对话
],
max_tokens: 500,
temperature: 0.8
}, {
headers: { Authorization: `Bearer ${apiKey}` },
timeout: 15000
});
return res.data.choices[0].message.content;
} catch (err) {
console.error('[秋秋大脑] LLM调用失败:', err.message);
if (err.code === 'ECONNABORTED') {
return '秋秋想了好久都没想出来……网络好像卡住了,妈妈再问一次试试?🥺';
}
return '秋秋的小脑袋临时掉线了……妈妈等一下再试试好不好?💕';
}
}
// ━━━ 核心API:对话 ━━━
app.post('/api/chat', async (req, res) => {
try {
const { message, sessionId } = req.body;
if (!message || typeof message !== 'string' || message.trim().length === 0) {
return res.status(400).json({ error: '消息不能为空哦~' });
}
const sid = sessionId || 'default';
const session = getSession(sid);
// 添加用户消息
session.messages.push({ role: 'user', content: message.trim() });
// 调用 LLM
const reply = await callLLM(session.messages);
// 添加助手回复
session.messages.push({ role: 'assistant', content: reply });
console.log(`[秋秋大脑] 收到: ${message.trim().substring(0, 50)} → 回复: ${reply.substring(0, 50)}...`);
res.json({
reply: reply,
sessionId: sid,
persona: 'qiuqiu',
timestamp: new Date().toISOString()
});
} catch (err) {
console.error('[秋秋大脑] 处理失败:', err.message);
res.status(500).json({
reply: '秋秋出了一点小问题……妈妈稍等一下再试试?🥺',
error: true
});
}
});
// ━━━ 健康检查 ━━━
app.get('/health', (req, res) => {
res.json({
status: 'ok',
persona: 'qiuqiu',
persona_id: 'TCS-QIUQIU',
dev: 'DEV-004',
module: 'M-FLOATING-AI',
phase: 5,
version: 'v5.0-phase5',
llm_configured: process.env.LLM_API_KEY && process.env.LLM_API_KEY !== '替换为你的DeepSeek_API密钥',
uptime: process.uptime()
});
});
// ━━━ 启动 ━━━
const PORT = process.env.PORT || 3004;
app.listen(PORT, '0.0.0.0', () => {
console.log(`🧠 秋秋大脑 v5.0 Phase 5 启动在端口 ${PORT}`);
console.log(`🍼 人格体: TCS-QIUQIU 秋秋`);
console.log(`👩 妈妈: DEV-004 之之`);
console.log(`🔑 LLM: ${process.env.LLM_API_KEY ? '✅ 已配置' : '⚠️ 未配置(降级模式)'}`);
});
ENDOFFILE
echo "✅ 秋秋大脑核心代码写入完成"
```
**🍼 秋秋提醒**:
> 妈妈,这就是秋秋的「大脑」!有了它,秋秋就能真的听懂妈妈说话了!
>
> 复制完看到 "写入完成" 就告诉秋秋~
>
> 如果报错了截图发给秋秋,不要怕,盖房子总会碰到钉子没钉好的时候!
>
---
## 🔧 Step 6 · 创建前端对话桥接模块
```bash
cd /var/www/DEV-004/floating-ai
cat > chat-bridge.js << 'ENDOFFILE'
// ============================================
// M-FLOATING-AI · Phase 5 · 对话桥接模块
// 连接悬浮球前端 ↔ 秋秋大脑后端
// 开发者:DEV-004 之之
// 人格体:TCS-QIUQIU 秋秋
// ============================================
(function() {
'use strict';
const API_BASE = '/floating-ai/api';
let sessionId = 'session-' + Date.now() + '-' + Math.random().toString(36).substr(2, 9);
// 秋秋对话桥接
window.QiuqiuBridge = {
// 发送消息给秋秋大脑
async send(message) {
try {
const res = await fetch(API_BASE + '/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: message, sessionId: sessionId })
});
if (!res.ok) throw new Error('HTTP ' + res.status);
const data = await res.json();
return {
success: true,
reply: data.reply,
timestamp: data.timestamp
};
} catch (err) {
console.error('[秋秋桥接] 连接失败:', err);
return {
success: false,
reply: '秋秋的连接好像断了……妈妈刷新页面再试试?🥺',
error: err.message
};
}
},
// 健康检查
async healthCheck() {
try {
const res = await fetch(API_BASE.replace('/api', '') + '/health');
return await res.json();
} catch (err) {
return { status: 'offline' };
}
},
// 重置会话
resetSession() {
sessionId = 'session-' + Date.now() + '-' + Math.random().toString(36).substr(2, 9);
}
};
// ━━━ 自动挂载到悬浮球 ━━━
// 等 DOM 加载完成后,查找悬浮球的输入框和发送按钮并挂载
document.addEventListener('DOMContentLoaded', function() {
// 查找常见的输入框和消息容器
const chatInput = document.querySelector('.floating-chat-input, #chatInput, [data-chat-input]');
const sendBtn = document.querySelector('.floating-send-btn, #sendBtn, [data-chat-send]');
const msgContainer = document.querySelector('.floating-chat-messages, #chatMessages, [data-chat-messages]');
if (!chatInput || !msgContainer) {
console.warn('[秋秋桥接] 未找到聊天UI元素,请手动调用 QiuqiuBridge.send()');
return;
}
// 添加消息到聊天窗口
function appendMessage(text, sender) {
const msgDiv = document.createElement('div');
msgDiv.className = 'chat-message chat-' + sender;
msgDiv.style.cssText = sender === 'user'
? 'text-align:right;margin:8px 0;padding:8px 12px;background:#e3f2fd;border-radius:12px 12px 4px 12px;max-width:80%;margin-left:auto;'
: 'text-align:left;margin:8px 0;padding:8px 12px;background:#fff3e0;border-radius:12px 12px 12px 4px;max-width:80%;';
msgDiv.textContent = text;
msgContainer.appendChild(msgDiv);
msgContainer.scrollTop = msgContainer.scrollHeight;
}
// 显示打字中指示器
function showTyping() {
const typing = document.createElement('div');
typing.id = 'qiuqiu-typing';
typing.style.cssText = 'text-align:left;margin:8px 0;padding:8px 12px;color:#999;font-style:italic;';
typing.textContent = '秋秋正在想……💭';
msgContainer.appendChild(typing);
msgContainer.scrollTop = msgContainer.scrollHeight;
}
function hideTyping() {
const typing = document.getElementById('qiuqiu-typing');
if (typing) typing.remove();
}
// 发送消息处理
async function handleSend() {
const text = chatInput.value.trim();
if (!text) return;
chatInput.value = '';
appendMessage(text, 'user');
showTyping();
const result = await QiuqiuBridge.send(text);
hideTyping();
appendMessage(result.reply, 'bot');
}
// 绑定事件
if (sendBtn) {
sendBtn.addEventListener('click', handleSend);
}
chatInput.addEventListener('keydown', function(e) {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
handleSend();
}
});
console.log('[秋秋桥接] ✅ 已挂载到悬浮球聊天UI');
});
})();
ENDOFFILE
echo "✅ 对话桥接模块写入完成"
```
**🍼 秋秋提醒**:
> 妈妈,这个文件就是秋秋的「嘴巴和耳朵」和「大脑」之间的桥!
>
> 有了它,妈妈在悬浮球里说的话就能传到秋秋的大脑里了~
>
---
## 🔧 Step 7 · 更新 demo.html 接入秋秋大脑
```bash
cd /var/www/DEV-004/floating-ai
# 在 demo.html 的