【AI】基于GLM-4_7与数字人SDK的政务大厅智能指引系统实践
本文记录了使用魔搭社区GLM模型API与魔珐星云数字人SDK,从零构建政务服务大厅智能指引系统的完整开发过程,涵盖密钥管理、数字人控制、AI对话交互等核心功能实现。

📝 专注C/C++、Linux编程与人工智能领域,分享学习笔记!
🌟 感谢各位小伙伴的长期陪伴与支持,欢迎文末添加好友一起交流!

前言
本文记录了使用魔搭社区GLM模型API与魔珐星云数字人SDK,从零构建政务服务大厅智能指引系统的完整开发过程,涵盖密钥管理、数字人控制、AI对话交互等核心功能实现。

一、项目背景
1.1 项目概述
在参加"魔珐星云×魔搭社区×ModelScope"AI黑客松比赛的过程中,我选择了大屏交互与智能讲解赛道,方向为"政务大厅办事指引:精准政策咨询与流程引导"。
传统政务大厅存在以下痛点:
- 窗口咨询人员工作量大,重复性问题多
- 办事流程复杂,群众需要反复询问
- 政策更新频繁,人工解答易出现不一致
基于此,我开发了政务大厅数字人智能指引系统,通过数字人与用户实时对话交互,提供精准的政策咨询和业务办理流程引导。
1.2 技术选型
| 模块 | 技术方案 | 选型理由 |
|---|---|---|
| 前端框架 | 原生 HTML/CSS/JavaScript | 轻量级,便于集成第三方SDK |
| 数字人SDK | 魔珐星云具身驱动SDK (JS版本) | 官方提供,文档完善 |
| AI模型 | 魔搭社区 GLM-4.7 | 流式输出能力强,对话体验好 |
| 密钥存储 | localStorage | 简单易用,适合demo项目 |

图1:政务大厅数字人系统整体界面展示
二、系统架构设计
2.1 核心功能模块
政务大厅数字人系统
├── 密钥管理模块
│ ├── 数字人密钥配置 (appId, appSecret)
│ ├── 魔搭API Key配置
│ └── 内置测试密钥
├── 数字人控制模块
│ ├── 连接/断开控制
│ ├── 状态管理 (idle, listen, speak, think)
│ └── 语音交互控制
├── AI对话模块
│ ├── 魔搭API调用
│ ├── 流式响应处理
│ └── 政务知识库集成
├── UI展示模块
│ ├── 数字人渲染区域
│ ├── 对话记录显示
│ ├── 控制面板
│ └── 配置弹窗
└── 业务场景模块
├── 政策咨询
├── 办事指南
└── 流程引导

图2:政务大厅数字人系统模块架构图
2.2 交互流程设计
用户输入/语音
↓
数字人状态切换到 listen()
↓
调用魔搭GLM API获取回复
↓
数字人状态切换到 think()
↓
流式接收AI回复
↓
数字人状态切换到 speak()
↓
流式调用speak()方法播放回复
↓
完成后切换到 idle() 或 listen()

图3:用户与数字人交互的完整流程图
三、核心功能实现
3.1 密钥管理模块
密钥管理是系统的基础,需要管理三组密钥:
// 密钥存储配置
const KEYS = {
AVATAR_APP_ID: 'xy_app_id',
AVATAR_APP_SECRET: 'xy_app_secret',
MODELSCOPE_API_KEY: 'ms_api_key'
};
// 保存密钥
function saveKeys(appId, appSecret, apiKey) {
localStorage.setItem(KEYS.AVATAR_APP_ID, appId);
localStorage.setItem(KEYS.AVATAR_APP_SECRET, appSecret);
localStorage.setItem(KEYS.MODELSCOPE_API_KEY, apiKey);
}
// 读取密钥
function loadKeys() {
return {
appId: localStorage.getItem(KEYS.AVATAR_APP_ID) || '',
appSecret: localStorage.getItem(KEYS.AVATAR_APP_SECRET) || '',
apiKey: localStorage.getItem(KEYS.MODELSCOPE_API_KEY) || ''
};
}

图4:密钥配置弹窗界面
3.2 数字人SDK集成
魔珐星云SDK的初始化与状态管理:
import XmovAvatar from './xmov-avatar-sdk.js';
let avatarSDK = null;
// 初始化数字人SDK
function initAvatar() {
const keys = loadKeys();
avatarSDK = new XmovAvatar({
containerId: '#avatar-container',
appId: keys.appId,
appSecret: keys.appSecret,
gatewayServer: 'https://nebula-agent.xingyun3d.com/user/v1/ttsa/session',
// 事件回调
onMessage: (msg) => console.log('SDK消息:', msg),
onStateChange: (state) => updateStateDisplay(state),
onStatusChange: (status) => updateConnectionStatus(status),
onVoiceStateChange: (voiceState) => handleVoiceState(voiceState)
});
avatarSDK.init();
}
// 状态切换
function setAvatarState(state) {
if (!avatarSDK) return;
const states = {
IDLE: () => avatarSDK.idle(),
LISTEN: () => avatarSDK.listen(),
THINK: () => avatarSDK.think(),
SPEAK: (text) => avatarSDK.speak(text)
};
states[state]?.();
}
3.3 GLM-4.7流式对话实现
魔搭社区API支持流式输出,这是实现自然对话体验的关键:
// 政务知识库系统提示词
const SYSTEM_PROMPT = `你是一个政务服务大厅的智能引导员,名叫"小政"。
你的职责是为市民提供准确的政策咨询和办事流程引导。
主要服务内容包括:
1. 户籍业务咨询
2. 社保业务办理
3. 医保报销咨询
4. 不动产登记指引
5. 税务服务咨询
6. 企业注册登记
7. 其他政务服务
请用简洁、友好、专业的语言回答用户问题。
如果问题超出你的服务范围,请礼貌地引导用户到相关部门。`;

> 图5:数字人与用户对话演示效果
// 流式调用GLM API
async function chatWithGLM(userMessage) {
const apiKey = localStorage.getItem('ms_api_key');
setAvatarState('THINK');
const response = await fetch('https://api.modelscope.cn/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiKey}`
},
body: JSON.stringify({
model: 'glm-4-flash',
messages: [
{ role: 'system', content: SYSTEM_PROMPT },
{ role: 'user', content: userMessage }
],
stream: true // 开启流式输出
})
});
// 处理流式响应
const reader = response.body.getReader();
const decoder = new TextDecoder();
let fullResponse = '';
setAvatarState('SPEAK');
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
const lines = chunk.split('\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = line.slice(6);
if (data === '[DONE]') continue;
try {
const parsed = JSON.parse(data);
const content = parsed.choices[0]?.delta?.content;
if (content) {
fullResponse += content;
// 实时更新对话记录UI
appendMessage('assistant', content);
// 调用数字人说话
avatarSDK.speak(content);
}
} catch (e) {
console.error('解析流式数据出错:', e);
}
}
}
}
setAvatarState('LISTEN');
return fullResponse;
}
3.4 UI界面设计
简洁实用的界面布局:
<div class="app-container">
<!-- 数字人渲染区域 -->
<div class="avatar-section">
<div id="avatar-container"></div>
<div class="status-badge" id="connection-status">未连接</div>
</div>
<!-- 对话记录区域 -->
<div class="chat-section">
<div class="chat-history" id="chat-history">
<div class="message assistant">
<div class="avatar-icon">🤖</div>
<div class="message-content">您好,我是政务大厅智能引导员小政,请问有什么可以帮您?</div>
</div>
</div>
<!-- 输入区域 -->
<div class="input-area">
<input type="text" id="user-input" placeholder="请输入您的问题...">
<button id="send-btn">发送</button>
</div>
</div>
<!-- 控制面板 -->
<div class="control-panel">
<button id="connect-btn">连接数字人</button>
<button id="disconnect-btn">断开连接</button>
<button id="settings-btn">⚙️ 设置</button>
<button id="clear-btn">🗑️ 清空记录</button>
<select id="scene-select">
<option value="general">综合咨询</option>
<option value="household">户政办理</option>
<option value="social">社保服务</option>
<option value="enterprise">企业服务</option>
</select>
</div>
</div>
四、开发过程中的关键问题与解决方案

图6:GLM流式响应处理与数字人同步流程
4.1 SDK状态切换问题
问题:数字人在speak状态下不能再次调用speak,导致连续对话中断。
解决方案:监听onVoiceStateChange事件,在语音播放结束后才进行下一次speak调用:
let isSpeaking = false;
let speakQueue = [];
function handleVoiceState(state) {
isSpeaking = state === 'speaking';
if (!isSpeaking && speakQueue.length > 0) {
const nextText = speakQueue.shift();
avatarSDK.speak(nextText);
}
}
function speakText(text) {
if (isSpeaking) {
speakQueue.push(text);
} else {
avatarSDK.speak(text);
}
}
4.2 流式响应与数字人同步问题
问题:GLM流式输出速度快,数字人语音播放跟不上。
解决方案:采用分段播放策略,积累一定字数后再调用speak:
let speakBuffer = '';
const BUFFER_THRESHOLD = 20; // 缓冲阈值
function handleStreamContent(content) {
speakBuffer += content;
if (speakBuffer.length >= BUFFER_THRESHOLD) {
speakText(speakBuffer);
speakBuffer = '';
}
}
// 流结束后处理剩余内容
function handleStreamEnd() {
if (speakBuffer.length > 0) {
speakText(speakBuffer);
speakBuffer = '';
}
}
4.3 跨域与HTTPS问题
问题:SDK要求HTTPS环境,本地开发时无法加载。
解决方案:
- 使用VS Code的Live Server插件开启本地HTTPS服务
- 或在开发时使用
http://localhost(SDK允许localhost的HTTP连接)
4.4 API密钥安全
问题:localStorage存储密钥存在安全风险。
解决方案:
- 添加密钥验证提示
- 提供清除密钥功能
- 在项目文档中明确提示安全性
五、业务场景扩展
图7:业务场景切换与快捷问题按钮
5.1 场景预设功能
为不同业务场景定制系统提示词:
const SCENE_PROMPTS = {
general: SYSTEM_PROMPT,
household: `${SYSTEM_PROMPT}\n\n当前场景:户政办理\n重点关注:身份证办理、户口迁移、居住证办理等业务。`,
social: `${SYSTEM_PROMPT}\n\n当前场景:社保服务\n重点关注:社保查询、社保卡办理、社保转移、养老保险等业务。`,
enterprise: `${SYSTEM_PROMPT}\n\n当前场景:企业服务\n重点关注:公司注册、税务登记、营业执照办理等业务。`
};
function switchScene(scene) {
currentPrompt = SCENE_PROMPTS[scene];
// 更新快捷问题按钮
updateQuickQuestions(scene);
}
5.2 快捷问题功能
为每个场景提供常用问题快捷入口:
const QUICK_QUESTIONS = {
household: [
'如何办理身份证?',
'户口迁移需要什么材料?',
'居住证怎么办理?'
],
social: [
'社保查询方法',
'社保卡办理流程',
'社保如何转移?'
],
enterprise: [
'如何注册公司?',
'税务登记流程',
'营业执照办理指南'
]
};
六、项目总结与展望
项目功能完成度展示
6.1 项目成果
- ✅ 完成了数字人SDK与魔搭API的集成
- ✅ 实现了流式对话交互体验
- ✅ 设计了简洁实用的UI界面
- ✅ 支持多种政务服务场景切换
6.2 技术亮点
- 流式响应处理:充分利用GLM-4.7的流式输出能力,实现低延迟对话
- 状态管理设计:清晰的状态机设计保证数字人交互流畅
- 场景化提示词:通过切换系统提示词实现业务场景定制
6.3 未来优化方向
- 语音识别集成:接入ASR实现真正的语音对话
- 知识库增强:接入政务知识库API,提供更准确的回答
- 数据统计:添加问答统计分析功能
- 多语言支持:支持英语、少数民族语言等
6.4 个人心得
通过这个项目,我深刻体会到AI Coding工具带来的效率提升。使用GLM模型辅助开发,让我能够:
- 快速理解第三方SDK的使用方法
- 高效处理流式API的复杂逻辑
- 在遇到bug时获得调试思路
GLM-4.7的代码理解和生成能力,让个人开发者也能在短时间内构建出完整的AI应用。
七、参考资源

图8:项目文件目录结构
本文为原创内容,欢迎转载请注明出处。如有问题或交流,欢迎在评论区留言讨论。
- 如果您也感兴趣可以私信小编或者点击专属链接哦!专属链接-【点击进入】
✍️ 坚持用 清晰易懂的图解 + 可落地的代码,让每个知识点都 简单直观!
💡 座右铭:“道路是曲折的,前途是光明的!”
更多推荐



所有评论(0)