技术博客:构建可接入 Skills 的智能体 Agent 小工具
技术博客:构建可接入 Skills 的智能体 Agent 小工具
作者:Eddygit
日期:2026-08-30
项目:Skill Agent Hub - 智能体技能接入中心
一、技术路线
1.1 需求分析
目标很明确:做一个"可接入 skills 的智能体 agent 小工具"。拆解下来有三个核心问题:
- 什么是"接入 skills"? — 在华为云生态中,Skills 是封装了特定云服务操作能力的技能模块(如创建 ECS、管理 VPC、查询 OBS 等)。"接入"意味着我们的工具需要能够发现、展示、并调用这些技能。
- "智能体 agent"体现在哪里? — Agent 的核心是"感知→决策→执行"的循环。在我们的设计中,用户选择技能和参数是"感知",Agent 状态管理是"决策",调用技能并返回结果是"执行"。
- "小工具"的边界? — 不是全功能 Agent 框架,而是一个轻量级的演示和原型工具,重点在于展示"技能接入"的概念和交互体验。
1.2 架构选型
经过权衡,我选择了 单文件 Flask 应用 的架构:
Browser (AJAX) ←→ Flask Server (单文件) ←→ In-Memory State
为什么选 Flask 而不是 FastAPI/Express?
- Flask 是 Python 生态中最简洁的 Web 框架,适合快速原型
- 单文件部署,无需构建工具链,降低复杂度
- 华为云 DevSpace 环境预装 Python,开箱即用
为什么单文件而不是前后端分离?
- 对于一个小工具,前后端分离引入的构建步骤(webpack/vite)得不偿失
- 内嵌 HTML/CSS/JS 在单文件中,部署只需一个
app.py - 代价是文件较大(30KB),但可读性通过良好的代码组织来保证
1.3 前端设计
采用原生 HTML/CSS/JavaScript,无框架依赖:
- 深色主题 + 蓝紫渐变:与华为云控制台风格保持一致,专业感强
- CSS 变量(Custom Properties):统一管理颜色、间距等设计 token
- 响应式网格布局:
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)) - setInterval 轮询:模拟 WebSocket 的实时更新效果,每 3 秒拉取活动日志
1.4 部署方案
关键决策:使用 DevSpace 端口预览,不创建 DevBridge 隧道。
DevSpace 开发者工作空间自带端口预览功能,格式为:
https://{PORT}-{CONTAINER_ID}.workspace.developer.huaweicloud.com/
这意味着只要在本地端口启动服务,DevSpace 会自动生成可访问的 URL,无需额外创建隧道。对于开发预览场景,这比 DevBridge 隧道更轻量。
二、技术心得
2.1 CodeArts ACP 协议的使用
本次代码通过 CodeArts ACP(Agent Client Protocol)协议生成。ACP 是一种让 AI Agent 与代码编辑器通信的协议,工作流如下:
Agent 发送 prompt → ACP WebSocket → CodeArts 编辑器 → 生成代码 → 返回结果
心得:
- ACP 的
--approve-all模式可以自动批准所有操作,适合自动化场景 - 沙箱路径需要从
registry.json读取,不能硬编码 - 会话管理(
sessions new/sessions close)是资源管理的关键 - 4 分钟健康探测 + 8 分钟超时重连的机制很重要,避免无限等待
2.2 发布至展览馆的流程
publish-work-to-gallery skill 的发布流程是一个典型的多步骤管道:
选择作品目录 → 获取 IAM Domain → 准备材料 → 选择训练营 → 发布 → 领取积分
关键发现:
- 平台 API 是无鉴权的公开接口(
/open-api-guest),不需要 token envUrl字段虽然必填,但接受空字符串作为占位符- 积分领取每日限一次,重复调用仍返回 success 但不实际发放
Idempotency-Key头提供了幂等性保护,重试安全
2.3 GitCode 操作
使用 token 直接推送代码到 GitCode:
REMOTE="https://oauth2:${TOKEN}@gitcode.com/<owner>/<repo>.git"
注意点:
- Token 嵌入 URL 格式为
oauth2:<token>@,不是Authorization: token头 auto_init=true创建的仓库有初始提交,本地推送时需要--allow-unrelated-histories合并- GitCode API v5 与 Gitea 兼容,PR 端点是
/pulls不是/merge_requests
三、实战经验
3.1 沙箱文件访问
CodeArts 在 bwrap 沙箱中运行,文件路径在宿主机和沙箱内可能不同。解决方案:
# 通过 /proc/{PID}/cwd 访问沙箱内文件
cp /proc/585370/cwd/app.py /root/workspace/
这是一个实用技巧:当直接路径访问失败时,通过进程的 /proc 文件系统总能找到工作目录。
3.2 封面图生成
展览馆要求上传封面图。在没有设计工具的情况下,用 Python Pillow 生成:
from PIL import Image, ImageDraw, ImageFont
img = Image.new('RGB', (1200, 630), '#0b0e17')
# 渐变背景 + 文字 + 装饰元素
经验:1200×630 是社交媒体卡片的标准尺寸,大部分平台都支持。
3.3 训练营投稿状态判断
训练营有 4 种状态:未开始、可投稿、进行中、已结束。判断逻辑:
today < startsAt → 未开始
startsAt ≤ today ≤ endsAt AND status == "published" → 可投稿
startsAt ≤ today ≤ endsAt AND status != "published" → 进行中
today > endsAt → 已结束
本次有 4 个训练营,其中 2 个可投稿(第四期和第二期),优先投稿了第四期。
四、存在问题与优化空间
4.1 当前问题
| 问题 | 严重度 | 说明 |
|---|---|---|
| 技能调用是模拟的 | 中 | 目前 /api/invoke 返回的是 mock 数据,未真正调用华为云 API |
| 无持久化存储 | 低 | 使用内存存储,重启后状态丢失。对于演示工具可接受 |
| 无认证机制 | 低 | 任何人都能访问。生产环境需要加认证 |
| 单文件过大 | 低 | app. py 30KB,HTML/CSS/JS 内嵌导致可维护性下降 |
| envUrl 未通过验证 | 中 | DevSpace 端口预览 URL 格式被平台拒绝,使用了空字符串 |
4.2 优化方向
短期优化:
- 接入真实 Skills:通过 hcloud CLI 或华为云 SDK 实现真正的技能调用
- 添加 WebSocket:替换 setInterval 轮询,实现真正的实时通信
- 前后端分离:将 HTML/CSS/JS 拆分到独立文件,提升可维护性
中期优化:
4. 添加技能编排:支持多个技能的链式调用,实现更复杂的 Agent 行为
5. 引入状态管理:使用 SQLite 替代内存存储,支持历史记录查询
6. 添加用户认证:集成华为云 IAM,实现基于角色的访问控制
长期优化:
7. 插件化架构:支持动态加载技能插件,无需修改核心代码
8. 多 Agent 协作:支持多个 Agent 实例协同工作
9. 技能市场:对接华为云 Skill 生态,实现技能的发现和安装
4.3 技术债务
- 封面图使用 DejaVu 字体,中文显示为方框。应安装 Noto Sans CJK SC 字体
- 详情包只有 README.md,缺少架构图等可视化资源
- 未编写单元测试
五、总结
本次实践完成了一个从 0 到 1 的全流程:
创建工具 → 发布到展览馆 → 推送到 GitCode → 写博客 → 补充材料
核心收获:
- CodeArts ACP 是一个强大的代码生成协议,适合自动化开发场景
- DevSpace 端口预览 比DevBridge隧道更轻量,适合开发预览
- 展览馆发布流程 虽然步骤多但每步都有明确的输入输出,管道化设计清晰
- GitCode API 与 Gitea 兼容,迁移成本低
工具虽小,但涵盖了 Agent 设计、技能接入、Web 开发、云平台部署等多个技术点,是一个不错的 MVP 原型。
本文为原创技术博客,转载请注明出处。
- 点赞
- 收藏
- 关注作者
评论(0)