用华为云 CodeArts Agent 从零搭建 AI Chat Studio:一个 ChatGPT 风格的网页对话助手

举报
yd_217436577 发表于 2026/10/14 15:55:21 2026/10/14
【摘要】 AI对话工作室,支持多模型切换与流式输出

用华为云 CodeArts Agent 从零搭建 AI Chat Studio:一个 ChatGPT 风格的网页对话助手

本文记录了如何使用华为云 CodeArts Agent(码道 ACP)从零开始,在沙箱环境中搭建一个完整的 AI 对话 Web 应用——AI Chat Studio。项目已发布至华为云开发者作品展览馆,代码开源在 GitCode。

一、项目简介

AI Chat Studio 是一个网页版 AI 对话助手,连接 9router API,支持多模型切换与流式输出。界面采用 ChatGPT 风格布局,左侧会话列表 + 右侧对话区,简洁现代。

核心功能

功能 说明
多轮对话 完整上下文管理,支持连续对话
模型选择 下拉框切换不同 AI 模型,支持从 API 自动拉取模型列表
模型配置 可自定义 API 端点、API Key、模型列表管理(增删改查)
流式输出 SSE 流式传输,逐字打字效果
Markdown 渲染 代码语法高亮 + 一键复制按钮
历史会话 localStorage 持久化,左侧会话列表管理(新建/切换/删除)
主题切换 深色/浅色双主题,默认深色,偏好持久化

二、技术架构

技术栈选型

整个项目刻意保持了"轻量"的定位——不引入 React/Vue 等框架,用原生 HTML + CSS + JavaScript 实现前端,后端用 Node.js + Express 做一层 API 代理。

为什么这样选?

  • 无框架前端:对于一个对话界面,原生 JS 完全够用,省去了构建工具链的复杂度,CDN 加载 marked.js / highlight.js / DOMPurify 三个库即可。
  • Express 代理层:浏览器直接调用 AI API 会遇到跨域问题,且 API Key 不应暴露在前端。用 Express 做一层代理,既解决跨域,又保护密钥。
  • SSE 流式传输:AI 生成内容是逐 token 返回的,用 Server-Sent Events 实现流式转发,前端逐字渲染,用户体验远优于"等完再显示"。

架构图

┌─────────────────────────────────────────────┐
│                  浏览器                       │
│  ┌─────────┐  ┌──────────────────────────┐  │
│  │ 会话列表  │  │      对话区域             │  │
│  │ (左侧)   │  │  Markdown + 代码高亮      │  │
│  │          │  │  流式逐字渲染             │  │
│  └─────────┘  └──────────────────────────┘  │
│         │                    │               │
│    localStorage          SSE EventSource     │
└─────────┼────────────────────┼───────────────┘
          │                    │
          │            ┌───────┴───────┐
          │            │  Express 代理  │
          │            │  (Node.js)     │
          │            │  /api/chat     │
          │            │  /api/models   │
          │            └───────┬───────┘
          │                    │
          │            ┌───────┴───────┐
          │            │  9router API   │
          │            │  (上游 AI)     │
          │            └───────────────┘

项目结构

ai-chat-studio/
├── server.js          # Express 服务器 + API 代理
├── package.json       # 依赖配置
└── public/
    ├── index.html     # 主页面(CDN 加载第三方库)
    ├── style.css      # 样式(深色/浅色主题 CSS 变量)
    └── app.js         # 前端逻辑(对话管理 + 设置面板)

三、核心实现解析

3.1 SSE 流式代理(后端)

后端最核心的部分是 /api/chat 接口——它接收前端的 POST 请求,转发给上游 9router API,然后把上游的流式响应逐块转发回前端。

app.post('/api/chat', async (req, res) => {
  const upstream = await fetch(`${apiBaseUrl}/v1/chat/completions`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${apiKey}`
    },
    body: JSON.stringify(req.body)
  });

  // 设置 SSE 响应头
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');

  // 逐行读取上游响应并转发
  const reader = upstream.body.getReader();
  const decoder = new TextDecoder();
  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    res.write(decoder.decode(value));
  }
  res.end();
});

关键点:Express 代理层不做任何缓冲,上游返回一块就立即写一块到前端响应,保证"逐字打字"效果的真实性。

3.2 前端流式接收与渲染

前端用 fetch + ReadableStream 接收 SSE 数据(而非 EventSource,因为需要 POST 请求):

const response = await fetch('/api/chat', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ model, messages, stream: true })
});

const reader = response.body.getReader();
const decoder = new TextDecoder();

while (true) {
  const { done, value } = await reader.read();
  if (done) break;

  const chunk = decoder.decode(value);
  // 解析 SSE data: 行,提取 content
  const lines = chunk.split('\n');
  for (const line of lines) {
    if (line.startsWith('data: ')) {
      const data = line.slice(6);
      if (data === '[DONE]') return;
      const json = JSON.parse(data);
      const content = json.choices[0]?.delta?.content;
      if (content) {
        assistantMessage += content;
        renderMarkdown(assistantMessage); // 实时渲染
      }
    }
  }
}

3.3 Markdown 渲染与代码高亮

用 CDN 加载三个库,无需构建步骤:

<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/highlight.js@11/highlight.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/dompurify@3/dist/purify.min.js"></script>

渲染流程:marked.parse(text) → DOMPurify.sanitize(html) → 插入 DOM → hljs.highlightAll()。

代码块还加了"一键复制"按钮——监听 click 事件,navigator.clipboard.writeText() 写入剪贴板。

3.4 模型配置面板

设置数据存在 localStorage,结构如下:

{
  "apiBaseUrl": "https://api.9router.com",
  "apiKey": "sk-xxx",
  "defaultModel": "gpt-4o-mini",
  "models": [
    { "id": "gpt-4o", "name": "GPT-4o" },
    { "id": "gpt-4o-mini", "name": "GPT-4o Mini" }
  ]
}

支持从 API 自动拉取模型列表(调用 /api/models),也支持手动增删改查。设置面板用 overlay + modal 实现,点击设置按钮弹出,点击遮罩层关闭。

3.5 深色/浅色主题

用 CSS 变量实现主题切换,切换时只需修改 document.documentElement 的属性:

:root {
  --bg-primary: #1a1a2e;
  --text-primary: #e0e0e0;
  /* ... */
}
:root[data-theme="light"] {
  --bg-primary: #ffffff;
  --text-primary: #1a1a1a;
  /* ... */
}

主题偏好同样存在 localStorage,刷新页面后自动恢复。

四、开发过程:CodeArts Agent 实践

这个项目完全在华为云 CodeArts 的沙箱环境中开发,使用 ACP(Agent Coding Protocol)协议与 Agent 交互。

开发流程

  1. 创建项目:通过 CodeArts acpx 会话创建 ai-chat-studio 项目,初始化 package.json 和 Express 依赖。
  2. 编写后端:Agent 根据"ChatGPT 风格对话助手"的需求描述,生成 server.js,包含 SSE 代理和模型列表代理两个接口。
  3. 编写前端:依次生成 index.html(页面结构 + CDN 引入)、style.css(深色主题 + 响应式布局)、app.js(对话逻辑 + Markdown 渲染 + 历史管理)。
  4. 功能迭代:在初版基础上增加模型配置面板——设置弹窗、localStorage 持久化、模型列表管理。
  5. 调试运行:在沙箱内 node server.js 启动,通过 DevBridge 隧道从外部访问验证。

CodeArts Agent 的优势

  • 沙箱隔离:开发环境完全隔离,不污染本地系统,Node.js、npm 等工具链开箱即用。
  • Agent 协作:用自然语言描述需求,Agent 生成代码,人工审查后采纳。比纯手写快,比纯 AI 生成可靠(有沙箱即时验证)。
  • 隧道预览:DevBridge 隧道一键暴露沙箱端口,外部浏览器直接访问预览,无需部署。

五、快速开始

# 克隆仓库
git clone https://gitcode.com/sdf2342/ai-chat-studio.git
cd ai-chat-studio

# 安装依赖
npm install

# 配置环境变量(可选,也可在界面设置面板中配置)
export APIBASE_URL=https://api.9router.com
export API_KEY=your-api-key

# 启动服务
node server.js

默认运行在 http://localhost:8080。

也可以不设环境变量,启动后在界面右上角点击设置按钮,在弹出的配置面板中填写 API 地址和密钥。

六、项目发布

项目已发布至华为云开发者作品展览馆:

发布流程使用了 huawei-cloud-publish-work-to-gallery 技能,自动完成了封面截图、架构图生成、详情打包、门禁检查和上传发布全流程。

七、总结与展望

AI Chat Studio 是一个"麻雀虽小五脏俱全"的项目——用最简的技术栈实现了完整的 AI 对话体验。它的价值不在于功能多强大,而在于:

  1. 可读性:没有框架 abstraction,每一行代码都直接对应一个可见的行为,适合学习。
  2. 可部署性:一个 node server.js 就能跑,不需要 Docker、不需要构建工具。
  3. 可扩展性:加一个数据库就是多用户版,加一个 RAG 就是知识库问答版。

后续可以考虑:

  • 接入更多 AI 平台(华为云 ModelArts / MaaS)
  • 增加文件上传与对话
  • 用 RAG 实现知识库问答
  • 部署到华为云 CCE 或 FunctionGraph

相关链接:

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。