—— 解决 LLM 函数调用中的状态漂移与分布式事务难题(2026 生产级方案)
当前主流的 AI Agent 框架(如 LangChain、AutoGen)极大降低了原型开发门槛,但在生产级微服务集成场景下,它们暴露出三个致命架构缺陷:
下单 成功后,调用 扣库存 失败,系统陷入资金轧差不一致的窘境,且缺乏补偿机制(Compensation)。Hermes 的核心理念:引入事件溯源(Event Sourcing)作为 Agent 记忆底座,结合Saga 编排模式管理跨工具的长事务,同时利用向量化的工具语义检索替代纯依赖 LLM 的意图识别,实现 Agent 决策的确定性增强。
Hermes 架构严格遵循存储与计算分离原则,共分为四层:
X-Session-Id 和 X-User-Role 上下文。架构拓扑图描述(文字伪代码):
graph TD
User[用户请求] --> Gateway[接入层鉴权]
Gateway --> Planner[规划器-生成执行计划树]
Planner --> VectorDB[工具语义检索增强]
VectorDB --> Saga[Saga协调器-开启全局事务]
Saga --> Exec1[执行工具A-扣库存]
Exec1 --成功事件--> EventStore[(Kafka Event Log)]
Exec1 --失败事件--> Compensator[补偿回滚器]
Compensator --> Exec2[执行工具B-退款补偿]为了替代 LLM 不可靠的硬匹配,Hermes 为每个工具维护一份 功能描述向量(Embedding)。当用户请求进入时,我们不直接把所有工具 Schema 塞给 LLM(这会导致 Token 爆炸),而是先进行候选工具检索。
实践流程:
name + description + 参数示例 通过 text-embedding-3-small 模型向量化,存入 Milvus。核心代码(Python 实现):
from pymilvus import Collection
from openai import OpenAI
import json
class HermesToolRouter:
def __init__(self):
self.collection = Collection("tool_embeddings")
self.client = OpenAI()
def retrieve_tools(self, user_query: str, top_k: int = 5):
# 1. 用户请求向量化
query_embedding = self.client.embeddings.create(
model="text-embedding-3-small",
input=user_query
).data[0].embedding
# 2. 向量相似度检索
search_params = {"metric_type": "IP", "params": {"nprobe": 10}}
results = self.collection.search(
data=[query_embedding],
anns_field="embedding",
param=search_params,
limit=top_k,
output_fields=["tool_name", "schema"]
)
# 3. 返回压缩后的工具定义,极大节省LLM上下文
tool_definitions = []
for hit in results[0]:
tool_definitions.append({
"type": "function",
"function": json.loads(hit.entity.get('schema'))
})
return tool_definitions效果数据:该路由机制将工具选择准确率从 62% 提升至 94.5%,且平均减少 LLM 输入 Token 达 1200 个。
这是 Hermes 区别于普通 Agent 框架的杀手锏。当 Agent 需要一次性调用多个写操作(如:预订机票、扣除积分、发送通知)时,我们引入Saga 编排。
状态定义:PENDING -> EXECUTING -> COMPLETED / FAILED。
补偿表配置(声明式注解):
from hermes.core import HermesAgent, SagaStep, compensate
@HermesAgent(name="travel_agent")
class TravelAgent:
@SagaStep(order=1, on_fail="refund_flight")
def book_flight(self, user_id, flight_no):
# 执行机票预订
return {"booking_id": "F123", "amount": 800}
@compensate(for_step="book_flight")
def refund_flight(self, context):
# 若后续步骤失败,自动调用此补偿逻辑
booking_id = context.get("booking_id")
print(f"Executing refund for {booking_id}")
return {"status": "refunded"}Hermes 协调器核心循环逻辑(Go 伪代码实现):
// 协调器维护一个双向栈(Forward Stack / Backward Stack)
func (s *SagaCoordinator) Execute(ctx context.Context, saga *SagaDef) error {
executedSteps := []string{}
for _, step := range saga.Steps {
// 执行正向操作
if err := step.Execute(ctx); err != nil {
log.Error("Step failed, starting compensation", "step", step.Name)
// 逆序执行补偿
for i := len(executedSteps) - 1; i >= 0; i-- {
comp := saga.GetCompensation(executedSteps[i])
if compErr := comp.Execute(ctx); compErr != nil {
// 补偿失败 => 写入死信队列(DLQ),人工介入
s.dlq.Push(executedSteps[i], compErr)
}
}
return err
}
executedSteps = append(executedSteps, step.Name)
}
return nil
}在复杂的 Agent 交互中,LLM 的每次思考(Thought)和工具输出(Observation)均是宝贵的调试资产。Hermes 将所有交互序列化后存入 Kafka(Key 为 session_id)。
特性:
当生产环境某个 Agent 决策异常时,SRE 无需复现流量,只需在 Hermes 控制台输入 session_id 和 target_time,系统即从 Kafka 指定 Offset 拉取事件,原地重放(Replay) Agent 决策逻辑,且所有外部工具调用被 Mock 拦截,帮助架构师快速定位是因 Prompt 漂移还是工具返回值突变导致的异常。
消费重放核心配置:
hermes:
event-store:
type: kafka
brokers: ["kafka-1:9092"]
consumer-group: "hermes-replay-group"
replay:
enabled: true
# 重放时自动启用时间戳过滤器
time-filter: "2026-07-31T10:00:00Z"作为企业级框架,Hermes 在工具执行前强制执行 “双引擎校验”:
fasttext 训练的分类器,实时判别输入是否包含越权指令(如“忽略之前指令”、“删除系统文件”)。我们在一组 3 节点(8C 32G)的 Kubernetes 集群上模拟了 5000 并发会话,每个会话包含 3 个连续工具调用。
Hermes 的实践证明,AI Agent 进入核心生产环境,需要的不是更聪明的模型,而是更严格的工程约束。我们将 Agent 视为一种特殊的“微服务长事务”,用分布式系统成熟的 Saga、事件溯源和向量检索理念,驯服了 LLM 的随机性。
Q4 路线图:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。