用 CodeBuddy + DeepSeek,从零搭一个 24 小时在线的社区 AI 情感陪伴数字人

📅 2026/7/23 10:45:15
用 CodeBuddy + DeepSeek,从零搭一个 24 小时在线的社区 AI 情感陪伴数字人
先搞清楚要解决什么问题社区里的情绪陪伴需求其实一直存在但很难被覆盖到独居老人半夜睡不着没有人说句话青少年在学校受了委屈不愿意跟家长开口上班族加班到深夜心里堵得慌但心理咨询要预约、要花钱社区不是没有资源——有社工、有心理咨询室。但社工要下班咨询室周末关门。人和时间的缺口才是真正的痛点。所以这个项目的核心目标很简单做一个不会下班的 AI 陪伴者在这个缺口上兜个底。最近做了一个0代码开发面向街道社区的小项目——一个 7×24 小时全天候在线社区情感陪伴具身交互智能体给辖区居民提供免费、零门槛的情绪疏导。这篇文章不写虚的就讲讲我是怎么从 0 到 1 把它搭出来的。整个方案不需要写后端、不需要配服务器核心就靠三个东西CodeBuddy 编辑器 Skill 技能 DeepSeek 大模型 魔珐星云具身交互智能数字人CodeBuddy 编辑器 https://www.codebuddy.cn/home/2.DeepSeek 大模型 https://www.deepseek.com/3.数字人具身智能官网地址https://xingyun3d.com?utm_campaigndailyutm_sourceCSDNwanfen3utm_mediumutm_termutm_content技术选型为什么是这三个CodeBuddy 编辑器它是一个可视化的 AI 应用搭建工具。重点不是它能写代码而是它内置了一个 Skill 技能调度系统。你可以把 Skill 理解成编辑器的技能插件引擎——它能帮你串联外部大模型、数字人 SDK、语音播报等不同模块通过配置面板统一调度不需要自己写业务代码。DeepSeek 大模型负责对话生成整个数字人的脑子。所有给居民的回复都由它实时生成不是预制的固定话术。魔珐星云 数字人 SDK提供全套多模态交互底层底座依托参数流、端侧渲染核心技术同步驱动语音、情绪微表情、肢体手势形成一个有表情、有动作、能说话的具身智能 3D 数字人形象。三者关系一句话讲清楚CodeBuddy 的 Skill 做总调度DeepSeek 做大脑魔珐星云补齐完整具身交互智能。0→1 搭建全流程下面是我实际搭建的六个步骤每一步都很具体。第一步新建 CodeBuddy 项目打开 AI编辑器 面板打开 CodeBuddy 编辑器新建一个项目。进入 Skill 技能配置面板这是整个项目的控制中心。Skill技能使用方式一全局导入Skill技能使用方式二AI对话时引入第二步AI对话进行我们的代码生成就很简单的告诉AI基于什么文件帮我们生成就好了。第三步AI生成结束后我们进行调试我们可以看到CodeBuddy 已经帮我们生成了一个html文件同时也将我们的核心功能都实现了。注意事项我们现在生成的是一个html文件会遇到一些跨域或者其他问题 现在我给大家一个真实可以用的运行步骤1.serve-p30002. 在浏览器打开 http://localhost:3000成功预览生成的html中这里有几个关键参数说明一下更多的参数说明也可以去阅读开发者文档https://xingyun3d.com/developers/52-183temperature 设 0.75兼顾回复的自然度和稳定性不会太飘也不会太机械max_tokens 设 2048给足长度能完整拆解居民复杂的生活矛盾context_keep_num 设 10保留最近 10 轮对话上下文数字人能记住居民上一轮说过什么system_prompt这是整个项目的灵魂。大模型的一切行为都由这段提示词约束——它被设定成一个社区公益心灵陪伴导师有固定的沟通逻辑先共情→再梳理→给建议语气温柔耐心不评判不说教还有一点就是我们的密钥从哪获取打开数字人官网官网地址https://xingyun3d.com?utm_campaigndailyutm_sourceCSDNwanfen3utm_mediumutm_termutm_content 应用管理-开始创建市面多数传统静态虚拟交互载体存在明显短板形象素材固定不可后台自定义无端侧参数流渲染架构实时语义表情联动、低延迟交互能力缺失。而魔珐星云具身交互智能平台内置海量多风格交互智能体素材支持后台自由切换形象、音色、表演风格依托原生实时渲染链路实现流畅拟人交互。这个爱因斯坦是我之前对接别家的体验比较一般形象不是很逼真还不能在后台配置只能第三方给什么用什么。今天我用CodeBuddy对接的是魔珐星云可以选择形象/场景/音色/表演大家可以体验一下。第三步代码讲解我们从项目0 - 1其实都是没有进行开发的两个md格式的文件结合我们的代码编辑器就帮我们实现了业务逻辑我们来看一下代码写的怎么样吧。数字人简单逻辑// 提供的SDK script srchttps://media.xingyun3d.com/xingyun3d/general/litesdk/xmovAvatarlatest.js/script // 数字人配置项 const sdk new XmovAvatar({ containerId: #sdk, // 数字人渲染的容器 appId: 你的 App ID, appSecret: 你的 App Secret, gatewayServer: https://nebula-agent.xingyun3d.com/user/v1/ttsa/session, onMessage: (msg) console.log(SDK Event:, msg) }); // 初始化加载数字人资源 await sdk.init({ onDownloadProgress: (progress) { console.log(数字人资源加载中${progress}%); } }); // text 就是我们拿到的数字人播报的文本 sdk.speak(text, true, true); 大模型简单逻辑 JavaScript const response await fetch(https://api.deepseek.com/v1/chat/completions, { method: POST, headers: { Content-Type: application/json, Authorization: Bearer ${apiKey} }, body: JSON.stringify({ model: deepseek-chat, messages: messages, temperature: 0.75, top_p: 0.9, max_tokens: 2048 }) }); const data await response.json(); const reply data.choices?.[0]?.message?.content || AI 未返回有效回复; // 拿到大模型返回的结果 传递给数字人 第四步通过 串联数字人的表情、动作、语音 我们的逻辑拿到 DeepSeek 返回的文本后除了展示在聊天框里还会同步调用数字人的能力 - TTS 语音播报把文字转成温柔舒缓的语音数字人说出来 - 表情联动根据回复内容数字人自动匹配表情——安慰时微笑、倾听时专注 - 字幕同步语音播报的同时显示字幕 TTS 语音合成、语义联动表情、配套肢体动作、场景素材均为具身交互智能配套原生能力由魔珐星云 SDK 一站式封装无需开发者单独开发多媒体、动画驱动逻辑大幅缩短场景落地迭代周期。 第五步配置分人群场景切换 为了让数字人面对不同居民有不同沟通风格我在系统中预设了四套人群标签 人群 重点话题 沟通风格 中老年 独居孤独、子女关系、退休适应 语速舒缓、用词浅显、称呼叔叔/阿姨 青少年 学业压力、社交矛盾、青春期情绪 平等尊重、不说教、多共情 中青年职场 加班焦虑、夫妻矛盾、育儿压力 理性温柔、既理解现实又引导调节 通用 日常情绪、心态科普 标准社工语气 切换标签时会在 system prompt 后面追加对应的人格描述DeepSeek 的回复风格就会跟着变。这个切换逻辑也是在 代码里面 里做条件分支实现的。 第六步部署上线 这里我提供了我通过CodeBuddy AI编辑器帮助我们生成的html格式的文件但是我们正式上线必须要将我们的APIKEY密钥等加密传递不能明文请求哦~ HTML !DOCTYPE html html langzh-CN head meta charsetUTF-8 / meta nameviewport contentwidthdevice-width, initial-scale1.0 / title社区24H公益情感陪伴数字人 - 家门口的心灵驿站/title style /* 全局变量 */ :root { --primary: #6366f1; --primary-soft: #e0e7ff; --primary-hover: #4f46e5; --warm: #f59e0b; --warm-soft: #fef3c7; --success: #10b981; --success-soft: #d1fae5; --danger: #ef4444; --danger-soft: #fee2e2; --bg: #f5f3ff; --card: #ffffff; --text: #1e293b; --text-sub: #64748b; --border: #e2e8f0; --radius: 16px; --shadow: 0 4px 24px rgba(0,0,0,0.06); --shadow-lg: 0 12px 40px rgba(0,0,0,0.1); --transition: 0.25s cubic-bezier(0.4,0,0.2,1); } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: -apple-system, BlinkMacSystemFont, Segoe UI, PingFang SC, Microsoft YaHei, Helvetica Neue, sans-serif; background: var(--bg); color: var(--text); min-height: 100vh; display: flex; flex-direction: column; } /* 顶部导航栏 */ .top-bar { background: var(--card); padding: 0 24px; height: 60px; display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid var(--border); box-shadow: 0 1px 8px rgba(0,0,0,0.04); z-index: 100; flex-shrink: 0; } .top-bar .logo { display: flex; align-items: center; gap: 10px; font-size: 18px; font-weight: 700; color: var(--primary); } .top-bar .logo .icon { font-size: 26px; } .top-bar .slogan { font-size: 13px; color: var(--text-sub); letter-spacing: 0.5px; } /* 主体布局 */ .main-layout { display: flex; flex: 1; overflow: hidden; } /* 左侧配置面板 */ .side-panel { width: 300px; background: var(--card); border-right: 1px solid var(--border); overflow-y: auto; padding: 20px; display: flex; flex-direction: column; gap: 16px; flex-shrink: 0; } .panel-section { background: #f8fafc; border-radius: 12px; padding: 16px; } .panel-section h3 { font-size: 13px; color: var(--text-sub); text-transform: uppercase; letter-spacing: 1px; margin-bottom: 12px; font-weight: 600; } .input-row { display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; } .input-row label { font-size: 12px; color: var(--text-sub); font-weight: 500; } .input-row input, .input-row select { padding: 8px 12px; border: 1px solid var(--border); border-radius: 8px; font-size: 13px; outline: none; background: #fff; transition: var(--transition); width: 100%; } .input-row input:focus, .input-row select:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(99,102,241,0.1); } .btn { padding: 10px 20px; border: none; border-radius: 10px; font-weight: 600; font-size: 14px; cursor: pointer; transition: var(--transition); display: inline-flex; align-items: center; justify-content: center; gap: 6px; } .btn:active { transform: scale(0.97); } .btn-primary { background: var(--primary); color: #fff; width: 100%; } .btn-primary:hover { background: var(--primary-hover); box-shadow: 0 4px 12px rgba(99,102,241,0.3); } .btn-danger { background: var(--danger); color: #fff; width: 100%; } .btn-danger:hover { background: #dc2626; } .btn-outline { background: #fff; border: 1.5px solid var(--border); color: var(--text); width: 100%; } .btn-outline:hover { border-color: var(--primary); color: var(--primary); } .btn-outline.active { border-color: var(--primary); background: var(--primary-soft); color: var(--primary); } /* 状态指示 */ .status-row { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text-sub); } .status-dot { width: 10px; height: 10px; border-radius: 50%; background: #d1d5db; flex-shrink: 0; } .status-dot.success { background: var(--success); box-shadow: 0 0 8px var(--success); } .status-dot.error { background: var(--danger); box-shadow: 0 0 8px var(--danger); } .status-dot.loading { background: var(--warm); animation: pulse 1s infinite; } keyframes pulse { 0%,100%{opacity:1} 50%{opacity:0.4} } /* 人群选择标签 */ .persona-tags { display: flex; flex-wrap: wrap; gap: 6px; } .persona-tag { padding: 6px 12px; border-radius: 20px; font-size: 12px; background: #fff; border: 1px solid var(--border); cursor: pointer; transition: var(--transition); white-space: nowrap; } .persona-tag:hover { border-color: var(--primary); } .persona-tag.selected { background: var(--primary-soft); border-color: var(--primary); color: var(--primary); font-weight: 600; } /* 中间舞台 */ .stage-area { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 20px; min-width: 0; } #sdk-wrapper { width: 100%; display: flex; justify-content: center; } #sdk { width: 800px; height: 450px; max-width: 100%; background: #0a0a1a; border-radius: var(--radius); box-shadow: var(--shadow-lg); position: relative; overflow: hidden; transition: all 0.4s ease; } #sdk::after { content: ; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: radial-gradient(ellipse at center, rgba(99,102,241,0.08) 0%, transparent 70%); pointer-events: none; z-index: 0; } #sdk-placeholder { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: rgba(255,255,255,0.2); font-size: 15px; z-index: 0; pointer-events: none; text-align: center; } /* 底部聊天区 */ .chat-section { background: var(--card); border-top: 1px solid var(--border); padding: 16px 24px; flex-shrink: 0; } .chat-messages { max-height: 180px; overflow-y: auto; margin-bottom: 12px; display: flex; flex-direction: column; gap: 8px; padding-right: 8px; } .chat-messages::-webkit-scrollbar { width: 4px; } .chat-messages::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; } .msg { display: flex; gap: 10px; animation: fadeInUp 0.3s ease; } keyframes fadeInUp { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } } .msg .avatar { width: 36px; height: 36px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 16px; flex-shrink: 0; } .msg.user .avatar { background: var(--primary-soft); } .msg.bot .avatar { background: var(--warm-soft); } .msg .bubble { max-width: 75%; padding: 10px 14px; border-radius: 14px; font-size: 14px; line-height: 1.6; word-break: break-word; } .msg.user { flex-direction: row-reverse; } .msg.user .bubble { background: var(--primary-soft); border-bottom-right-radius: 4px; } .msg.bot .bubble { background: #f1f5f9; border-bottom-left-radius: 4px; } .chat-input-row { display: flex; gap: 10px; } .chat-input-row input { flex: 1; padding: 12px 18px; border: 2px solid var(--border); border-radius: 30px; font-size: 15px; outline: none; transition: var(--transition); background: #f8fafc; } .chat-input-row input:focus { border-color: var(--primary); background: #fff; box-shadow: 0 0 0 4px rgba(99,102,241,0.08); } .chat-input-row .btn-send { padding: 12px 28px; border-radius: 30px; background: var(--primary); color: #fff; border: none; font-weight: 600; font-size: 15px; cursor: pointer; transition: var(--transition); } .chat-input-row .btn-send:hover { background: var(--primary-hover); } .chat-input-row .btn-send:disabled { opacity: 0.5; cursor: not-allowed; } /* 右侧工具面板 */ .tool-panel { width: 320px; background: var(--card); border-left: 1px solid var(--border); overflow-y: auto; padding: 20px; display: flex; flex-direction: column; gap: 14px; flex-shrink: 0; } .tool-card { background: #f8fafc; border-radius: 12px; padding: 16px; transition: var(--transition); } .tool-card h4 { font-size: 14px; font-weight: 600; margin-bottom: 8px; display: flex; align-items: center; gap: 6px; } .tool-card .card-icon { font-size: 18px; } /* 情绪自测 */ .mood-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; } .mood-btn { padding: 8px; border-radius: 10px; font-size: 13px; border: 1px solid var(--border); background: #fff; cursor: pointer; transition: var(--transition); text-align: center; } .mood-btn:hover { background: var(--primary-soft); border-color: var(--primary); } .mood-result { margin-top: 10px; padding: 10px; border-radius: 8px; font-size: 13px; display: none; } .mood-result.show { display: block; } .mood-result.calm { background: var(--success-soft); color: #065f46; } .mood-result.mild { background: var(--warm-soft); color: #92400e; } .mood-result.intense { background: var(--danger-soft); color: #991b1b; } /* 暖心语录 */ .quote-box { background: linear-gradient(135deg, #eef2ff, #faf5ff); border-radius: 10px; padding: 14px; font-size: 14px; line-height: 1.7; color: #4338ca; font-style: italic; min-height: 60px; } /* 正念引导 */ .mindfulness-timer { text-align: center; font-size: 36px; font-weight: 700; color: var(--primary); margin: 8px 0; } /* 响应式 */ media (max-width: 1400px) { .side-panel { width: 260px; } .tool-panel { width: 280px; } } media (max-width: 1100px) { .main-layout { flex-direction: column; } .side-panel { width: 100%; flex-direction: row; flex-wrap: wrap; max-height: 200px; } .tool-panel { width: 100%; flex-direction: row; flex-wrap: wrap; max-height: 200px; } .stage-area { min-height: 350px; } } /style /head body !-- 顶部导航 -- header classtop-bar div classlogo span classicon/span span社区心灵驿站/span /div div classslogan家门口的心灵驿站24小时在线守护辖区居民情绪/div div classstatus-row div classstatus-dot idstatus-light/div span idstatus-text未连接/span /div /header !-- 主体布局 -- div classmain-layout !-- 左侧配置面板 -- aside classside-panel idside-panel !-- Xmov 凭证 -- div classpanel-section h3 数字人配置 (Xmov)/h3 div classinput-row labelApp ID/label input typetext idinp-appid placeholder粘贴 App ID / /div div classinput-row labelApp Secret/label input typepassword idinp-secret placeholder粘贴 App Secret / /div button classbtn btn-primary onclickdoConnect() idbtn-conn连接数字人/button button classbtn btn-danger onclickdoDisconnect() idbtn-disconn styledisplay:none;断开连接/button /div !-- DeepSeek 配置 -- div classpanel-section h3 AI 对话引擎 (DeepSeek)/h3 div classinput-row labelAPI Key/label input typepassword idinp-ds-key placeholder粘贴 DeepSeek API Key / /div div classstatus-row stylemargin-bottom:8px; div classstatus-dot idds-light/div span idds-text未配置/span /div /div !-- 人群选择 -- div classpanel-section h3 服务人群/h3 div classpersona-tags idpersona-tags span classpersona-tag selected />实时具身驱动依托完整具身交互智能底层架构实现文本、语音、微表情、肢体、口型全域同步驱动端到端交互低至 500ms原生支持用户任意时段插话实时打断具身交互智能标志性交互能力,更多的能力我们可以查看文档进行调用。搭完之后实际跑起来是什么样我们内部模拟了几个典型场景深夜独居老人。 模拟一位阿姨晚上十一点发消息“一个人在家心里有点慌”。数字人先共情——“阿姨晚上一个人确实容易胡思乱想我能理解这种感觉”——然后温和地引导她做几个深呼吸再聊聊白天有没有什么让她开心的小事。整个过程节奏很慢不催促。青少年匿名倾诉。 模拟中学生说“考砸了不敢回家”。数字人没有说下次努力就好了而是说我懂那种感觉很怕让家人失望对不对但一次考试定义不了你先跟我说说哪科没发挥好——先接住情绪再慢慢展开话题。职场中青年深夜焦虑。 模拟上班族说“加班到十点回家跟老婆吵架心力交瘁”。数字人先承认处境——“工作和家庭两头拉扯确实很消耗人”——然后给一个很具体的小建议“今晚先不解决问题了给自己十五分钟放空明天情绪稳下来再跟老婆好好聊。”这些回复没有一条是预先写好的全都由 DeepSeek 实时生成。这是跟传统关键词匹配→调取预制话术的智能客服最根本的区别。几个设计上的考量为什么不做成纯文字聊天文字对话框没有温度。一个具象的数字人——会点头、会微笑、会用温和的语气说话——能让人感觉到对面有回应这对情感陪伴场景很重要。尤其是老年人看字费劲听语音更自然。数据隐私怎么处理所有居民对话数据本地隔离存储不对外上传。Ai里的上下文记忆只做临时缓存不会持久化到外部服务器。方案临时存储3. 社区工作人员能自己改吗可以。CodeBuddy 是可视化编辑器社区工作人员想改宣传文案、调整疏导话术方向、数字人形象不需要懂代码让AI帮我们来实现我们的想法。4. 一定要用 DeepSeek 吗不一定。DeepSeek 接口是标准 OpenAI 兼容格式把 llm_base_url 和 llm_api_key 换成其他大模型的地址和密钥就行。我们也可以选择其他,例如qwendoubao都是国内很好的大模型最后这个 Demo 目前还在社区展厅体验测试阶段不算什么大项目但思路我觉得值得分享用已有的成熟能力编辑器 大模型 数字人 SDK通过AI能力零代码把 idea 跑起来。如果你也在做类似的事情——不管是社区服务、校园心理、还是企业内部员工关怀——这套快速搭建路径都可以复用换个 prompt 提示词 和数字人形象就行。有想法可以一起交流。魔珐星云官网https://xingyun3d.com?utm_campaigndailyutm_sourceCSDNwanfen3utm_mediumutm_termutm_contentDeepSeek官网https://www.deepseek.com/Codebuddy官网: https://www.codebuddy.cn/home/