HagiCode 为什么选择 Hermes 作为综合 Agent 核心
为什么 HagiCode 需要 Hermes
在详细介绍 Hermes 之前,先说说 HagiCode 为什么会有这样的需求。这世上的事情啊,往往不是你想怎么样就能怎么样的,总得找个合适的由头。
作为一个 AI 代码助手,HagiCode 需要同时支持多种使用场景:
- 本地开发环境:开发者希望在自gu电脑上运行,数据不出本地——这年头,数据安全这事说大不大,说小也不小
- 团队协作环境:小团队可以共享部署在服务器上的 Agent——省钱嘛,大家都不容易
- 云端弹力扩展:处理复杂任务时,能自动扩展到 GPU 集群——有备无患
这种"既要又要"的需求,让我们把目光投向了 Hermes。这选择对不对我不知道,只是当时也没别的更好的办法了。
什么是 Hermes Agent
Hermes Agent 是由 Nous Research 创建的自主 AI Agent。可能有人对 Nous Research 不熟悉——他们就是开发了 Hermes、Nomos 和 Psyché 等开源大模型的实验室。说起来他们也挺不容易的,做了这么多好东西,知道的人却不多。
跟传统的 IDE 编程助手或者简单的 API 聊天包装器不同,Hermes 有一个特点:运行时间越长,能力越强。它不是一次性完成任务就完事,而是能在长时间运行中持续学习和积累经验。这点也挺像人的,是不是?
核心特性
Hermes 的几个核心特性,正好契合了 HagiCode 的需求。你说巧不巧?
这意味着 HagiCode 可以根据用户场景,选择最合适的部署方式。个人用户本地跑,团队用户服务器部署,复杂任务上 GPU——一套代码搞定。这世道,能省一事算一事罢。
多平台消息网关
Hermes 原生支持 Telegram、Discord、Slack、WhatsApp 等平台。对 HagiCode 来说,这意味着未来可以轻松支持这些渠道的 AI 助手。毕竟谁不想多几条路呢?
丰富的工具系统
40+ 内置工具,加上 MCP(Model Context Protocol)扩展能力。这对于代码助手来说太重要了——执行 shell 命令、操作文件系统、调用 Git,这些都需要工具支持。没有工具的 Agent,就像没有翅膀的鸟——想飞也飞不起来。
跨会话记忆
Hermes 有持久记忆系统,用 FTS5 全文检索召回历史对话。这让 Agent 能记住之前的上下文,不会每次都"失忆"。有时候我也想失忆一下,什么都不想,可就是做不到。
HagiCode 如何集成 Hermes
说完了"为什么",接下来看看"怎么做"。有些事情想明白了,就得动手,光想不做也不是个事儿。
Provider 层抽象
在 HagiCode 的架构中,所有 AI Provider 都实现统一的 IAIProvider 接口:
public sealed class HermesCliProvider : IAIProvider, IVersionedAIProvider |
|
{ |
|
public ProviderCapabilities Capabilities { get; } = new ProviderCapabilities |
|
{ |
|
SupportsStreaming = true, // 支持流式输出 |
|
SupportsTools = true, // 支持工具调用 |
|
SupportsSystemMessages = true, // 支持系统提示 |
|
SupportsArtifacts = false |
|
}; |
|
} |
这个抽象层让 HagiCode 可以无缝切换不同的 AI Provider,无论是 OpenAI、Claude 还是 Hermes,上层调用方式完全一致。说白了,就是省事儿。
ACP 通信协议
Hermes 使用 ACP (Agent Communication Protocol) 进行通信。这是一个专门为 Agent 通信设计的协议,主要方法包括:
| 方法 | 说明 |
|---|---|
initialize |
初始化连接,获取协议版本和客户端能力 |
authenticate |
处理认证,支持多种认证方法 |
session/new |
创建新会话,设置工作目录和 MCP 服务器 |
session/prompt |
发送提示并获取响应 |
HagiCode 通过 StdioAcpTransport 实现 ACP 传输层,启动 Hermes 子进程并通过标准输入输出进行通信。这事儿听起来复杂,做起来也还行——主要是要有耐心。
配置管理
通过 HermesPlatformConfiguration 类管理配置:
public sealed class HermesPlatformConfiguration : IAcpPlatformConfiguration |
|
{ |
|
public string ExecutablePath { get; set; } = "hermes"; |
|
public string Arguments { get; set; } = "acp"; |
|
public int StartupTimeoutMs { get; set; } = 5000; |
|
public string ClientName { get; set; } = "HagiCode"; |
|
public HermesAuthenticationConfiguration Authentication { get; set; } |
|
public HermesSessionDefaultsConfiguration SessionDefaults { get; set; } |
|
} |
在 appsettings.json 中配置 Hermes:
{ |
|
"Providers": { |
|
"HermesCli": { |
|
"ExecutablePath": "hermes", |
|
"Arguments": "acp", |
|
"StartupTimeoutMs": 10000, |
|
"ClientName": "HagiCode", |
|
"Authentication": { |
|
"PreferredMethodId": "api-key", |
|
"MethodInfo": { |
|
"api-key": "your-api-key-here" |
|
} |
|
}, |
|
"SessionDefaults": { |
|
"Model": "claude-sonnet-4-20250514", |
|
"ModeId": "default" |
|
} |
|
} |
|
} |
|
} |
配置这东西吧,看着简单,真要调对了也得费些功夫。
Orleans 分布式架构
HagiCode 使用 Orleans 构建分布式系统,Hermes 集成通过以下组件实现:
- HermesGrain:Orleans Grain 实现,处理会话执行
- HermesPlatformConfiguration:平台特定配置
- HermesAcpSessionAdapter:ACP 会话适配器
- HermesConsole:专用的验证控制台
Orleans 这名字起得挺好听的,传说中的阿里巴巴——虽然此 Orleans 非彼 Orleans,但名字好听总是加分的。
完整执行流程
以下是 Hermes Provider 的核心执行逻辑:
private async IAsyncEnumerable<AIStreamingChunk> StreamCoreAsync( |
|
AIRequest request, |
|
string? embeddedCommandPrompt, |
|
[EnumeratorCancellation] CancellationToken cancellationToken) |
|
{ |
|
// 1. 创建传输层,启动 Hermes 子进程 |
|
await using var transport = new StdioAcpTransport( |
|
platformConfiguration.GetExecutablePath(), |
|
platformConfiguration.GetArguments(), |
|
platformConfiguration.GetEnvironmentVariables(), |
|
platformConfiguration.GetStartupTimeout(), |
|
_loggerFactory.CreateLogger<StdioAcpTransport>()); |
|
await transport.ConnectAsync(cancellationToken); |
|
// 2. 初始化,获取协议版本和认证方法 |
|
var initializeResult = await SendHermesRequestAsync( |
|
transport, nextRequestId++, "initialize", |
|
BuildInitializeParameters(platformConfiguration), cancellationToken); |
|
// 3. 处理认证 |
|
var authMethods = ParseAuthMethods(initializeResult); |
|
if (!isAuthenticated) |
|
{ |
|
var methodId = platformConfiguration.Authentication.ResolveMethodId(authMethods); |
|
await SendHermesRequestAsync(transport, nextRequestId++, "authenticate", ...); |
|
} |
|
// 4. 创建会话 |
|
var newSessionResult = await SendHermesRequestAsync( |
|
transport, nextRequestId++, "session/new", |
|
BuildNewSessionParameters(platformConfiguration, workingDirectory, model), cancellationToken); |
|
var sessionId = ParseSessionId(newSessionResult); |
|
// 5. 执行提示并收集流式响应 |
|
await foreach (var payload in transport.ReceiveMessagesAsync(cancellationToken)) |
|
{ |
|
// 处理 session/update 通知,转换为流式块 |
|
if (TryParseSessionNotification(root, out var notification)) |
|
{ |
|
if (_responseMapper.TryConvertToStreamingChunk(notification, out var chunk)) |
|
{ |
|
yield return chunk; |
|
} |
|
} |
|
} |
|
} |
代码嘛,看多了也就那么回事。重要的是思路,对吧?
健康检查
为了保证 Hermes 服务的可用性,HagiCode 实现了健康检查机制:
public async Task<ProviderTestResult> PingAsync(CancellationToken cancellationToken = default) |
|
{ |
|
var response = await ExecuteAsync( |
|
new AIRequest |
|
{ |
|
Prompt = "Reply with exactly PONG.", |
|
CessionId = null, |
|
AllowedTools = Array.Empty<string>(), |
|
WorkingDirectory = ResolveWorkingDirectory(null) |
|
}, |
|
cancellationToken); |
|
var success = string.Equals(response.Content.Trim(), "PONG", StringComparison.OrdinalIgnoreCase); |
|
return new ProviderTestResult |
|
{ |
|
ProviderName = Name, |
|
Success = success, |
|
ResponseTimeMs = stopwatch.ElapsedMilliseconds, |
|
ErrorMessage = success ? null : $"Unexpected Hermes ping response: '{response.Content}'." |
|
}; |
|
} |
这大概就是所谓的"健康检查"了罢。其实人也一样,总要时不时检查一下自己——只是通常没人告诉我们应该检查什么。
实践中的注意事项
集成 Hermes 过程中,有一些坑值得提前了解。这年头,谁还没踩过几个坑呢?
认证方法配置
Hermes 支持多种认证方法(API Key、Token 等),需要根据实际部署情况选择。配置错误会导致连接失败,但错误信息可能不够直观。有时候报错信息跟实际原因差了十万八千里,得慢慢排查。
MCP 服务器配置
创建会话时可以配置 MCP 服务器列表,让 Hermes 调用外部工具。但要注意:
- MCP 服务器地址必须可访问
- 超时时间要合理设置
- 服务器不可用时的降级处理
这世道,防不胜防啊。
工作目录管理
每个会话都需要指定工作目录,确保 Hermes 能正确访问项目文件。对于多项目场景,需要动态切换工作目录。说起来简单,做起来要考虑的情况也挺多的。
响应聚合处理
Hermes 的响应可能分散在 session/update 通知和最终结果中,需要正确合并处理,否则会出现内容丢失。这事儿我也没少吃亏,慢慢就好了。
错误处理策略
运行时错误应该明确返回,而不是静默回退到其他 Provider。这样用户才知道是 Hermes 出了问题,而不是莫名其妙换了别的模型。毕竟糊弄事儿也不是这么个糊弄法。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)