2026年4月16日 周五晚上19:30,来了解“从个人单点提效,到构建企业AI生产力”(限30人)
免费POC, 零成本试错
AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


我要投稿

从 CLI 到桌面 App,再到技能市场:我们给我的 Rust Hermes Agent 造了一个完整的生态

发布日期:2026-04-15 07:39:02 浏览次数: 1582
作者:老码小张

微信搜一搜,关注“老码小张”

推荐语

从 CLI 到桌面 App,再到技能市场,Hermes Agent 的完整生态让 AI 技能触手可及。

核心内容:
1. 用户需求驱动:解决 CLI 使用门槛和技能共享问题
2. 技术选型:Tauri 2 实现轻量级桌面应用,复用 Rust 技术栈
3. 创新架构:Command API 桥接前后端,React+TS 实现友好界面

杨芳贤
53AI创始人/腾讯云(TVP)最具价值专家

 

上两篇我们聊了 Rust 重写 Hermes Agent和学习闭环。这次,我们把它装进了一个桌面 App,并接上了一个技能市场。注意这个技能市场中,是可以承载我们在使用 Hermes Agent 的过程中,这匹马自己主动生成的技能。

故事从一个问题开始

上篇文章发出来之后,有朋友私信我:

"技能系统很酷,但我每次要用,得打开终端、敲命令、还要记参数……能不能有个界面?"

另一个问题同样被问到了:

"我的 Hermes自己创建的技能只有我自己用,有没有办法分享给别人?或者直接用别人沉淀好的技能?"

这几天的工作,其实就是针对这两个问题,就是最新两个迭代要回答的。

答案是:Hermes Desktop + SkillHub 技能市场。

对话界面
技能市场

Hermes Desktop:把 Agent 装进桌面应用

桌面端我直接使用了Tauri 2,那么我为什么这么选择呢?

我们没有做一个 Electron 应用。原因很简单——Electron 的本质是用 Chromium + Node.js 跑一个 Web 应用,打包出来随随便便 200MB 起步。

Tauri 的思路完全不同:

  • • 前端渲染用系统自带的 WebView(macOS 上是 WebKit,Windows 上是 WebView2)
  • • 后端逻辑直接是 Rust
  • • 打包产物:不到 10MB
我的 Hermes 目录

更重要的是:我们的整个 Agent 栈(hermes-agenthermes-toolshermes-llm……)本来就是 Rust 写的。Tauri 的后端天然复用全部 13 个 crate,没有任何额外的桥接层。

apps/hermes-desktop/
  src-tauri/        ← Rust 后端(直接 use hermes_agent::AIAgent)
    src/lib.rs      ← Tauri Commands 定义
  src/              ← React + TypeScript 前端
    App.tsx         ← 全部 UI 逻辑

前端:React + TypeScript + Tailwind CSS + Vite。标准现代 Web 技术栈,没有任何奇特选择。

架构:Commands 桥接两端

Tauri 的核心机制是 Commands——前端通过 invoke() 调用 Rust 函数,拿到类型安全的返回值。

我们定义了一套完整的 Command API:

// 聊天核心
#[tauri::command]

async
 fn chat(state: State<'_, AppState>, message: String) -> Result<ChatResponse, String>

// 会话管理

#[tauri::command]

async
 fn list_sessions(state: State<'_, AppState>) -> Result<Vec<SessionItem>, String>

#[tauri::command]

async
 fn load_session(state: State<'_, AppState>, session_id: String) -> Result<Vec<DisplayLine>, String>

// 配置读写

#[tauri::command]

async
 fn get_settings(state: State<'_, AppState>) -> Result<SettingsView, String>

#[tauri::command]

async
 fn save_settings(state: State<'_, AppState>, payload: SettingsPayload) -> Result<String, String>

// 技能管理

#[tauri::command]

async
 fn list_skills(state: State<'_, AppState>) -> Result<Vec<SkillListItem>, String>

#[tauri::command]

async
 fn install_market_skill(state: State<'_, AppState>, slug: String) -> Result<SkillInstallResult, String>

这个设计有个关键点:AppState 里的 AIAgent 是真实的 Rust Agent 实例,不是什么 HTTP 调用或者进程间通信——前端和 Agent 运行在同一个进程里,调用开销接近于零。

struct Session {
    agent: hermes_agent::AIAgent,   // 真实的 Agent 实例
    history: Vec<Message>,
    model_label: String,
}

我的UI 设计,三个面板,一个 App,前面基本上也讲过了

整个 UI 分三个主视图,通过左侧边栏切换:

① 聊天界面(Chat)

左侧是历史会话列表,右侧是对话区域。几个设计细节值得说:

  • • 工具调用日志折叠展示:Agent 执行工具时的日志会被归组成一个可折叠的 <details> 块,默认收起。不想看细节的用户不会被干扰,想 debug 的用户点开就有。
// 工具日志渲染逻辑
if
 (item.kind === "tools") {
  return
 (
    <details className="group rounded-md border border-dashed border-primary/30">
      <summary>⚡ 工具执行日志({item.logs.length} 条)</summary>
      {/* 展开后显示每条工具调用 */}
    </details>
  );
}
  • • Markdown 渲染:助手的回复通过 react-markdown + remark-gfm 渲染,代码块有语法高亮样式,表格、列表都正常展示。
  • • 深色 / 浅色模式:一键切换,状态持久化到 localStorage。

② 设置界面(Settings)

模型名称、Base URL、API Key、流式输出开关、记忆系统开关、会话持久化……所有配置都在这里,保存后直接写入 config.yaml,无需重启。

③ 技能中心(Skills)

这个面板是这次迭代的重头戏,下面单独展开。

SkillHub 技能市场:让技能流动起来

我们所面对的问题是技能孤岛

之前的技能系统是完全本地的:Agent 自己创建技能,存在 ~/.hermes/skills/ 目录,只有你自己能用。

这带来了两个问题:

  1. 1. 冷启动困难:新用户装完之后技能库是空的,要等 Agent 自己慢慢积累
  2. 2. 重复造轮子:同样的 "如何调试 Docker 网络问题" 技能,无数人都在自己创建

SkillHub 要解决的就是这个问题:让技能成为可流通的资产

实现:SkillHubClient

我们在 hermes-skills crate 里加入了 SkillHubClient,封装了和技能市场 API 的全部交互:

pub struct SkillHubClient {
    base_url: String,
    client: reqwest::Client,
}

impl
 SkillHubClient {
    // 拉取分类列表

    pub
 async fn categories(&self) -> Result<Vec<String>, String>
    
    // 获取推荐技能

    pub
 async fn recommended(&self, limit: u32) -> Result<Vec<RemoteSkillSummary>, String>
    
    // 分页浏览(支持按分类筛选)

    pub
 async fn list_skills(&self, category: Option<&str>, page: u32, page_size: u32)
        -> Result<RemotePage<RemoteSkillSummary>, String>
    
    // 全文搜索

    pub
 async fn search_skills(&self, query: &str, category: Option<&str>, ...)
        -> Result<RemotePage<RemoteSkillSummary>, String>
    
    // 获取技能详情(含完整 SKILL.md 内容)

    pub
 async fn skill_detail(&self, id_or_slug: &str) -> Result<RemoteSkillDetail, String>
}

让后离线优先,Seeded Fallback 机制

网络不稳定怎么办?SkillHub 服务器挂了怎么办?

我们设计了一套 优雅降级 机制,通过 CatalogDataSource 枚举追踪数据来源:

pub enum CatalogDataSource {
    Remote,   // 来自 SkillHub 服务器
    Seeded,   // 来自内置精选(离线可用)
    Mixed,    // 服务器数据不足,混合了内置精选补充
}

每个请求都有 _with_fallback 版本:

pub async fn recommended_with_fallback(
    &self,
    limit: u32,
) -> (Vec<RemoteSkillSummary>, CatalogDataSource) {
    match
 self.recommended(limit).await {
        Ok
(remote) if !remote.is_empty() => {
            // 远程数据够用,直接返回

            // 如果远程数量少于 seeded,混合补充

            if
 remote.len() < seeded.len() {
                (merge(remote, seeded), CatalogDataSource::Mixed)
            } else {
                (remote, CatalogDataSource::Remote)
            }
        }
        // 网络失败?用内置精选,用户完全无感

        _ => (seeded_recommended(limit), CatalogDataSource::Seeded),
    }
}

离线状态下,技能市场仍然可以浏览和使用内置精选。等网络恢复,自动切回远程数据。

技能市场 UI

技能中心界面分两个 Tab,界面前面已经给过了:

「已安装」Tab:展示本地技能列表,可以查看详情、删除、直接编辑 SKILL.md 内容。

「市场」Tab

  • • 顶部:分类过滤 + 搜索框
  • • 推荐区:横向滚动的精选技能卡片
  • • 列表区:分页浏览全部技能,每个卡片展示名称、描述、分类标签、Star 数、安装量
  • • 点击技能卡片:弹出详情面板,展示完整 SKILL.md 内容,一键安装
// 安装技能只需要一行
const
 result = await invoke<SkillInstallResult>("install_market_skill", { slug });

安装本质上是把技能的 SKILL.md 内容写入本地 ~/.hermes/skills/<name>/SKILL.md,Agent 下次启动时自动发现并加载。

这次迭代的,其实我对整个核心做了质量提升

除了新功能,这次迭代也做了大量质量提升工作。

用户画像过滤

user_profile 工具现在支持按置信度过滤:低置信度(observed,0.7)的事实在空间不足时会被自动淘汰,只有用户亲口确认(stated/corrected,1.0)的高置信度事实才会稳定保留。

这意味着 Agent 对你的画像会越来越准——不确定的猜测自然消退,确定的认知持续强化。

更好的 Agent 回调

AgentCallbacks 现在支持更细粒度的事件:工具调用开始、工具调用结束、流式 token 回调,方便桌面端做实时 UI 更新(比如工具执行时显示 loading 状态)。

然后,我们整体架构现在是什么样子

经过这几轮迭代,整个系统的形态已经非常清晰:

MCP │ hermes-skills│
└──────────────────────────────┬──────────────────────────┘
 │
┌──────────────────────────────▼──────────────────────────┐
│数据与知识层 │
│SQLite (会话历史 + FTS5)│SKILL.md (本地技能库) │
│MEMORY.md / USER.md│SkillHub (远程技能市场)│
└─────────────────────────────────────────────────────────┘" data-show-line-number="false" style="font-size: 90%;border-radius: 4px;display: -webkit-box;padding: 0.5em 1em 1em;overflow-x: auto;text-indent: 0;color: inherit;background: none;white-space: nowrap;margin: 0;font-family: 'Fira Code', Menlo, Operator Mono, Consolas, Monaco, monospace;">┌─────────────────────────────────────────────────────────┐
│                    用户接入层                             │
│  hermes CLI  │  Hermes Desktop  │  Gateway (Telegram…)  │
└──────────────────────────────┬──────────────────────────┘
                               │
┌──────────────────────────────▼──────────────────────────┐
│                    Agent 核心层                           │
│            hermes-agent (AIAgent 主循环)                 │
│    hermes-llm │ hermes-tools │ hermes-mcp │ hermes-skills│
└──────────────────────────────┬──────────────────────────┘
                               │
┌──────────────────────────────▼──────────────────────────┐
│                    数据与知识层                           │
│  SQLite (会话历史 + FTS5)  │  SKILL.md (本地技能库)     │
│  MEMORY.md / USER.md      │  SkillHub (远程技能市场)    │
└─────────────────────────────────────────────────────────┘

三层架构,职责清晰:

  • • 最上层负责接入——你可以用 CLI、桌面 App、或者 Telegram Bot
  • • 中间层是 Agent 大脑——工具调用、MCP、技能检索,一套核心逻辑服务所有接入层
  • • 最下层是知识沉淀——会话历史、记忆、技能,都是持久化的资产

无论你从哪个入口进来,你的记忆、你的技能、你的画像都是共享的。在桌面 App 里让 Agent 学会了一个 Docker 排错技巧,下次打开终端用 CLI 时,这个技能照样可用。

使用咱们这个 Hermes Agent Rust一次完整体验是什么样的

让我描述一个完整的使用场景:

第一次打开 Hermes Desktop,你在设置页填入 API Key,选好模型,保存。

进入聊天,你说:"帮我分析一下这个 Python 项目的性能瓶颈"。Agent 开始工作:调用 terminal 执行 python -m cProfile,调用 read_file 读源码,调用 web_search 查相关文档……工具日志自动折叠,你只看到最终的分析报告。

完成后,Agent 主动提议把这套分析流程保存为技能。你同意,技能创建完毕。

打开技能中心,在市场 Tab 搜索 "code review",发现有个评分很高的代码审查技能,一键安装。下次让 Agent 做代码审查,它会先调出这个技能里的检查清单。

三个月后,你换了台电脑。cargo build --release 编译一个二进制,把 ~/.hermes/ 目录拷贝过去,所有的记忆、技能、画像全部迁移完毕。无需重新配置任何服务。

写在最后

这几个迭代做完,我意识到我们在做的事情其实已经超出了"写一个 AI Agent"的范畴。

我们在构建的是 AI Agent 的基础设施

  • • CLI:给开发者用的原子工具
  • • Desktop App:给更广泛用户用的交互界面
  • • SkillHub:让知识在用户之间流动的生态

这套基础设施有一个核心信念:AI Agent 产生的知识,应该成为可复用的资产,绝对不仅仅是随会话消失的文字。

技能是资产。记忆是资产。画像是资产。这些资产在你的设备上,不依赖任何云服务,可以迁移,可以分享,可以越用越多。

下一步?我们在考虑 SkillHub 的社区共建机制——让用户把自己沉淀的好技能提交到市场,让这个知识网络真正活起来。

三篇文章聊完了这个项目从 0 到 1 的历程。如果你对 Rust + AI Agent 这个方向感兴趣,欢迎来 hermes-rs 看看. 注意,这个项目目前仅仅对我的小群(公众号菜单-联系我-加群)内开源。

 

53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询