欢迎光临
我们一直在努力

AI 工程化的下一个阶段——从 MLOps 到 LLMOps 再到 AgentOps

AI 工程化的下一个阶段——从 MLOps 到 LLMOps 再到 AgentOps

一、为什么 MLOps 无法直接套用到 LLM 场景

MLOps 作为传统机器学习的工程化最佳实践,在过去几年已经形成了成熟的工具链和流程框架:特征存储(Feast)、模型注册中心(MLflow)、训练流水线(Kubeflow)、模型服务(TensorFlow Serving / Triton)。但这个体系在面对 LLM 应用时出现了多个"不适配"的点。

首先,模型规模带来了部署范式的根本变化。传统 ML 模型(几百 MB 到几 GB)可以每个服务实例加载一个模型副本,但 LLM 的权重文件动辄几十到上百 GB,加载到 GPU 显存需要数分钟,这在 MLOps 的热替换模型中完全不可接受。

其次,评估体系的结构性差异。ML 模型可以用离线测试集的准确率、召回率、F1 值直接评估,部署上线后模型行为不发生显著变化。但 LLM 的输出是非确定性的、上下文相关的,离线 Benchmark(MMLU、HumanEval)并不能预测它在真实对话场景中的表现。

最后,Agent 的出现将运维的对象从"模型推理服务"变成了"多模型协作网络"。Agent 涉及工具调用、多轮反思、条件分支和跨模型路由——这些行为的观测、调试和灰度发布让传统 MLOps 的监控仪表盘捉襟见肘。

二、MLOps → LLMOps → AgentOps 的演进路径

三个阶段的核心差异可以概括为:MLOps 关注模型质量,LLMOps 关注输出质量与成本效率,AgentOps 关注行为正确性与协作可靠性。这三者的递进不是替代关系而是叠加关系——AgentOps 是 LLMOps 的超集,LLMOps 是 MLOps 的超集。

三、AgentOps 的核心工程挑战与落地方案

AgentOps 最核心的挑战是Agent 行为的可调试性。当 Agent 输出不符合预期时,工程师需要回溯完整的多步推理链——包括每一轮 LLM 调用、每一次工具调用的参数和返回、每一次反思和条件分支。这比单次 API 调用的调试复杂一个数量级。

以下是基于 Spring Boot 的 Agent 行为追踪服务的关键实现:

/**
* Agent 行为追踪与回放服务
* 记录 Agent 的完整推理链路,支持事后分析和回放
*/
@Service
public class AgentTraceRecorder {

private final TraceStorage traceStorage;
private final MetricsExporter metricsExporter;
private final AlertRuleEngine alertEngine;

public AgentTraceRecorder(TraceStorage traceStorage,
MetricsExporter metricsExporter,
AlertRuleEngine alertEngine) {
this.traceStorage = traceStorage;
this.metricsExporter = metricsExporter;
this.alertEngine = alertEngine;
}

/**
* 开始追踪一个 Agent 会话
*
* @param sessionId 会话标识
* @param agentId Agent 实例标识
* @param config Agent 配置快照
* @return 追踪上下文
*/
public AgentTraceContext beginTrace(String sessionId, String agentId,
AgentConfig config) {
AgentTraceContext ctx = new AgentTraceContext();
ctx.setTraceId(UUID.randomUUID().toString());
ctx.setSessionId(sessionId);
ctx.setAgentId(agentId);
ctx.setConfigSnapshot(config);
ctx.setStartTime(Instant.now());
return ctx;
}

/**
* 记录 Agent 的一次 LLM 调用
* 包含完整的 Prompt、响应和 Token 统计
*/
public void recordLlmCall(AgentTraceContext ctx, LlmCallEvent event) {
try {
TraceStep step = TraceStep.builder()
.stepType(StepType.LLM_CALL)
.sequence(ctx.getAndIncrementSeq())
.llmRequest(event.getRequest()) // 完整 Prompt
.llmResponse(event.getResponse()) // 完整响应
.promptTokens(event.getPromptTokens())
.completionTokens(event.getCompletionTokens())
.latencyMs(event.getLatencyMs())
.modelName(event.getModelName())
.build();

ctx.addStep(step);

// 导出 Token 用量指标
metricsExporter.recordTokenUsage(
event.getModelName(),
event.getPromptTokens(),
event.getCompletionTokens());

} catch (Exception e) {
log.error("LLM 调用记录失败: traceId={}", ctx.getTraceId(), e);
// 追踪记录失败不影响 Agent 执行
}
}

/**
* 记录 Agent 的工具调用
*/
public void recordToolCall(AgentTraceContext ctx, ToolCallEvent event) {
try {
TraceStep step = TraceStep.builder()
.stepType(StepType.TOOL_CALL)
.sequence(ctx.getAndIncrementSeq())
.toolName(event.getToolName())
.toolInput(event.getInput()) // 调用参数
.toolOutput(event.getOutput()) // 返回结果
.success(event.isSuccess())
.errorMessage(event.getErrorMessage())
.latencyMs(event.getLatencyMs())
.build();

ctx.addStep(step);

// 工具调用成功率监控
metricsExporter.recordToolCallResult(
event.getToolName(), event.isSuccess());

// 工具调用失败率告警
if (!event.isSuccess()) {
alertEngine.evaluateToolFailure(ctx, event);
}

} catch (Exception e) {
log.error("工具调用记录失败: traceId={}", ctx.getTraceId(), e);
}
}

/**
* 结束追踪并持久化完整的 Agent Trace
*/
public void endTrace(AgentTraceContext ctx, AgentResult result) {
try {
ctx.setEndTime(Instant.now());
ctx.setFinalResult(result);

// 计算追踪摘要指标
AgentTraceSummary summary = AgentTraceSummary.from(ctx);

// 持久化完整 Trace(异步写入,避免阻塞 Agent 返回)
traceStorage.saveAsync(ctx.toPersistable());

// 导出 Agent 级别指标
metricsExporter.exportAgentMetrics(summary);

log.info("Agent Trace 完成: traceId={}, steps={}, totalTokens={}, latencyMs={}",
ctx.getTraceId(), ctx.getStepCount(),
summary.getTotalTokens(), summary.getTotalLatencyMs());

} catch (Exception e) {
log.error("Trace 持久化失败: traceId={}", ctx.getTraceId(), e);
// 持久化失败不影响 Agent,但需要告警
}
}
}

AgentOps 的 Trace 数据量远大于传统的 APM Trace——一次 Agent 调用可能产生 5~15 次的 LLM 调用和多次工具调用,每个调用都包含完整的 Prompt 和 Response 文本。存储策略必须区分热数据(近 24 小时用于实时调试)和冷数据(归档到廉价存储用于离线分析)。

四、AgentOps 的过度工程化风险

AgentOps 是一个仍在快速演进的领域,当前的实践中有几个值得警惕的过度工程化风险:

风险一:在基础设施不成熟时过早引入复杂编排。如果团队连模型的 Token 用量监控和 Prompt 版本管理(LLMOps 的基础)都没做好,直接跳到多 Agent 协作和回放调试会导致问题排查成本爆炸。

风险二:Trace 数据膨胀。Agent Trace 如果记录所有 LLM 调用的完整 Prompt 和 Response,单个 Trace 的大小很容易达到几百 KB 甚至几 MB。在高 QPS 场景下,Trace 的存储和传输成本可能超过推理本身。AgentOps 必须在"全量记录"和"采样记录"之间做策略选择。

风险三:将 Agent 当作确定性系统。Agent 的非确定性输出使得传统的"输入-预期输出"测试范式失效。A/B 测试和在线人工评估的成本远高于传统软件的自动化测试,团队需要在测试投入和风险承受度之间找到平衡。

结论

AI 工程化正从 MLOps 向 LLMOps 再向 AgentOps 递进演进。对于绝大多数团队,当前的合理实践是:先做好 LLMOps——包括 Prompt 版本管理、Token 用量与成本追踪、在线评估与 A/B 测试;在 LLMOps 成熟后再引入 AgentOps——包括 Agent 行为 Trace、工具调用监控和 Agent 级灰度发布。不要在单模型服务还没管好的时候就追求多 Agent 编排。AgentOps 的核心工程投入应该放在"可调试性"上——当 Agent 出问题时,团队需要能在 5 分钟内回放完整推理链并定位到出错步骤,而不是靠猜和手动复现。

赞(0)
未经允许不得转载:171主机测评 » AI 工程化的下一个阶段——从 MLOps 到 LLMOps 再到 AgentOps
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址