Agent 行为追踪:每一步都要记下来才能事后复盘
Agent 行为追踪每一步都要记下来才能事后复盘一、Agent 说我已经完成了但你根本不知道它做了什么一个典型的 Agent 交互用户发出指令 → Agent 进行 3 次工具调用 → 最终返回结果。表面看起来正常但事后复盘时你会发现 Agent 的第 2 次工具调用参数有个偏差导致获取了错误的数据而 Agent 自己没发现这个错误基于错误数据继续推理最后给出了看起来合理但实际错误的结论。更糟糕的是如果没有记录中间步骤你永远不知道这个错误发生过。Agent 的自主性在带来灵活性的同时也带来了可解释性的黑洞。传统的 LLM 应用是输入→输出的单步模式调试相对简单。Agent 是思考→行动→观察→思考…的多步循环每一步的微小偏差都可能被后续步骤放大形成复合错误。Agent 的行为追踪需要回答三个问题每一步做出了什么决策思维链追踪工具调用的参数和返回值是什么工具链追踪哪个决策导致了最终的错误根因分析二、Agent 执行的状态机可观测的是状态转换而非最终结果stateDiagram-v2 [*] -- Planning: 接收用户指令 Planning -- Reasoning: 制定执行计划 Reasoning -- ToolCall: 需要工具调用 Reasoning -- Response: 直接回答 ToolCall -- Observation: 工具返回结果 Observation -- Reasoning: 分析工具结果 Observation -- Error: 工具调用失败 Error -- Reasoning: 重试或调整 Error -- Fallback: 超过重试次数 Response -- [*]: 完成 Fallback -- Response: 降级回答 note right of Observation 关键观测点 - 工具调用参数是否正确 - 返回结果是否匹配预期 - 是否注意到关键信息 end note note right of Error 关键观测点 - 失败原因分类 - 重试策略是否有效 - 是否需要人工介入 end note在状态转换的每一步都需要记录当前状态Planning → Reasoning → ToolCall → Observation 中的哪一个状态转换的原因为什么决定调用这个工具为什么认为任务已完成状态转换的结果工具返回了什么Agent 对返回结果的理解是什么。三、Agent Trace 采集器不侵入业务逻辑的埋点方案import json import time import uuid from dataclasses import dataclass, field from typing import List, Dict, Any, Optional from enum import Enum class AgentState(Enum): Agent 执行状态枚举 PLANNING planning REASONING reasoning TOOL_CALL tool_call OBSERVATION observation ERROR error RESPONSE response FALLBACK fallback dataclass class AgentStep: Agent 执行步骤记录 step_id: str field(default_factorylambda: str(uuid.uuid4())[:8]) state: AgentState timestamp: float field(default_factorytime.time) # 设计原因每个步骤记录详细的输入输出 # 不做省略或摘要完整保留方便事后回放 input_data: Dict[str, Any] field(default_factorydict) output_data: Dict[str, Any] field(default_factorydict) # 设计原因记录 LLM 调用的 Token 消耗 # 用于成本和效率分析也用于检测 Token 消耗异常 tokens_used: int 0 # 设计原因记录与本步骤相关的元信息 # 如模型名称、temperature、工具名称等 metadata: Dict[str, Any] field(default_factorydict) dataclass class AgentTrace: 一次完整 Agent 会话的追踪记录 trace_id: str field(default_factorylambda: str(uuid.uuid4())[:16]) session_id: str user_query: str steps: List[AgentStep] field(default_factorylist) start_time: float field(default_factorytime.time) end_time: Optional[float] None final_answer: Optional[str] None # 设计原因记录 Agent 的自我评估 # Agent 对自己回答的信心程度对于后续分析非常关键 self_assessment: Optional[str] None class AgentTracer: Agent 行为追踪器 设计原因使用装饰器模式不侵入 Agent 的核心业务逻辑 通过 TraceContext 在 Agent 执行过程中自动采集步骤信息 def __init__(self, storage_backendNone): # 设计原因支持可插拔的存储后端 # 开发环境用本地文件生产环境用远程存储如 Elasticsearch self.storage storage_backend or LocalFileStorage() self.active_traces: Dict[str, AgentTrace] {} def start_trace(self, session_id: str, user_query: str) - AgentTrace: 开始一次追踪 trace AgentTrace(session_idsession_id, user_queryuser_query) self.active_traces[trace.trace_id] trace return trace def record_step( self, trace_id: str, state: AgentState, input_data: Dict, output_data: Dict, metadata: Dict None, tokens_used: int 0 ): 记录一个执行步骤 设计原因记录是原子的——要么全记录要么全不记录 避免部分记录导致的幽灵步骤有头无尾的记录 if trace_id not in self.active_traces: # 设计原因未注册 trace_id 表示追踪未正确初始化 # 不应静默忽略应该抛出错误或记录告警 raise ValueError(f未找到 Trace: {trace_id}请先调用 start_trace()) step AgentStep( statestate, input_datainput_data, output_dataoutput_data, metadatametadata or {}, tokens_usedtokens_used ) self.active_traces[trace_id].steps.append(step) def end_trace(self, trace_id: str, final_answer: str, self_assessment: str None): 结束追踪并持久化 trace self.active_traces.pop(trace_id) trace.end_time time.time() trace.final_answer final_answer trace.self_assessment self_assessment # 设计原因持久化时做一次统计汇总 # 将原始步骤数据转化为分析指标方便查询 summary self._summarize(trace) self.storage.save({ trace: trace, summary: summary, timestamp: time.time() }) return trace def _summarize(self, trace: AgentTrace) - Dict: 从原始步骤中提取汇总指标 total_tokens sum(s.tokens_used for s in trace.steps) tool_calls [s for s in trace.steps if s.state AgentState.TOOL_CALL] errors [s for s in trace.steps if s.state AgentState.ERROR] return { trace_id: trace.trace_id, duration_seconds: (trace.end_time - trace.start_time), total_steps: len(trace.steps), total_tool_calls: len(tool_calls), total_errors: len(errors), total_tokens: total_tokens, # 设计原因统计状态转换序列如 Planning→Reasoning→ToolCall # 不同任务的典型转换序列不同异常序列是排查问题的线索 state_sequence: [s.state.value for s in trace.steps], } class LocalFileStorage: 本地文件存储后端 def __init__(self, base_path: str ./agent_traces): import os self.base_path base_path os.makedirs(base_path, exist_okTrue) def save(self, data: Dict): trace_id data[trace][trace_id] filepath f{self.base_path}/{trace_id}.json # 设计原因使用 dataclass 的 __dict__ 序列化 # 对于复杂类型如 Enum需要自定义 JSON encoder with open(filepath, w, encodingutf-8) as f: json.dump(data, f, ensure_asciiFalse, indent2, defaultstr)四、追踪数据的使用与存储取舍全量记录还是采样Agent 行为的完整追踪数据量大需要考虑存储策略。全量记录优点不遗漏任何异常事后可以分析任意一次用户交互缺点存储成本高每天数百万次 Agent 调用 × 每 Trace 10KB 数十 GB/天适用金融、医疗等对可追溯性要求极高的行业。采样记录优点存储成本可控保留长期趋势数据缺点低概率的异常行为可能被采样遗漏适用对可追溯性要求一般的通用场景。分层存储策略推荐热数据近 7 天全量存储支持实时查询和回放温数据7~30 天只保留汇总指标和异常 Trace支持趋势分析冷数据30 天以上仅保留统计摘要用于长期容量规划。额外考虑追踪数据包含用户输入隐私合规是硬约束。需要在采集阶段就对敏感信息做脱敏处理PII 屏蔽而非事后删除。五、总结Agent 的行为追踪需要记录每一步的状态转换、输入输出和决策依据。追踪器应采用非侵入设计如装饰器模式不修改 Agent 的核心业务逻辑。Agent 的状态机视角将执行过程分解为可观测的状态转换序列根因分析通过回溯状态转换找到最早偏离预期的步骤。存储策略需要在全量信息和存储成本之间权衡——分层存储热/温/冷是工程实践中的平衡方案。追踪数据中的用户输入涉及隐私合规需在采集阶段做脱敏处理。

相关新闻

NLP 服务 SLA 设计:99% 的可用性目标不是拍脑袋定的

NLP 服务 SLA 设计:99% 的可用性目标不是拍脑袋定的

NLP 服务 SLA 设计:99% 的可用性目标不是拍脑袋定的 一、领导说"要 99.9% 可用",但你算过这需要多少钱吗 接到需求:NLP 推理服务需要"高可用"。领导说 SLA 定 99.9%。但当你开始分析这意味着什么时,发现问题没…

2026/7/15 22:35:23阅读更多 →
模板驱动型文档自动化:非设计人员的电子书生成原理

模板驱动型文档自动化:非设计人员的电子书生成原理

1. 项目概述:当“写书”变成填空题——一个模板驱动型文档自动化系统的底层逻辑你有没有过这种经历:手头有一篇写得不错的行业分析,或者一份整理好的客户案例集,突然被要求“做成一本电子书发给潜在客户”。接下来就是打开Word&am…

2026/7/15 22:35:23阅读更多 →
TurtleBot3 SBC系统配置:Ubuntu MATE 16.04+ROS Kinetic嵌入式环境搭建全指南

TurtleBot3 SBC系统配置:Ubuntu MATE 16.04+ROS Kinetic嵌入式环境搭建全指南

1. 项目概述:为什么SBC软件设置是TurtleBot3落地的第一道门槛 刚拿到TurtleBot3 Burger套件时,我拆开包装、装好底盘、接上OpenCR主控板,满心期待地插上树莓派3B——结果屏幕一黑,或者卡在启动LOGO,又或者连Wi-Fi都搜不…

2026/7/15 22:35:23阅读更多 →
Kubernetes 监控实战:使用 Alertmanager 实现邮件告警、分组路由与告警抑制

Kubernetes 监控实战:使用 Alertmanager 实现邮件告警、分组路由与告警抑制

前言在前面的监控实践中,我们已经通过 ServiceMonitor 让 Prometheus 抓取了 NVIDIA DCGM Exporter 和 vLLM 的指标,并使用 PrometheusRule 编写了 GPU 与推理服务告警规则。但是,Prometheus 负责的是“判断告警是否成立”,并不负…

2026/7/15 23:30:35阅读更多 →
OpenAMP 架构深度剖析:remoteproc 与 RPMsg 在 FreeRTOS+Linux 双系统通信中的协作机制

OpenAMP 架构深度剖析:remoteproc 与 RPMsg 在 FreeRTOS+Linux 双系统通信中的协作机制

OpenAMP 架构深度剖析:remoteproc 与 RPMsg 在 FreeRTOSLinux 双系统通信中的协作机制 一、多核异构系统的通信地狱——当 Cortex-A 的 Linux 遇上了 Cortex-M 的裸机 现代边缘 SoC(如 STM32MP1、i.MX 8M Mini)普遍集成 Cortex-A Cortex-M…

2026/7/15 23:30:35阅读更多 →
【沐风老师】3DMAX编织建模插件:从可编辑多边形到艺术品的进阶指南

【沐风老师】3DMAX编织建模插件:从可编辑多边形到艺术品的进阶指南

1. 为什么可编辑多边形是编织建模的最佳载体第一次接触3DMAX编织建模时,我也曾疑惑:为什么教程都强调要使用可编辑多边形?直到亲手对比测试才发现,这简直是天壤之别。想象你要编织一个竹篮,用原始圆柱体和用可编辑多边…

2026/7/15 23:30:35阅读更多 →
NCNN 多线程推理的负载均衡调度对决:按输出通道均分与按计算量均分两种策略的基准测试报告

NCNN 多线程推理的负载均衡调度对决:按输出通道均分与按计算量均分两种策略的基准测试报告

NCNN 多线程推理的负载均衡调度对决:按输出通道均分与按计算量均分两种策略的基准测试报告 一、线程闲置的真相——当 4 核 CPU 的推理吞吐量还不如单核时发生了什么 在 NCNN 的边缘推理部署中,开启多线程后延迟反而恶化的情况并不少见。以 RK3588 上的 …

2026/7/15 23:30:35阅读更多 →
TFLite 异步推理流水线架构:用 C++ future/promise 榨干边缘 SoC 的每一毫秒计算力

TFLite 异步推理流水线架构:用 C++ future/promise 榨干边缘 SoC 的每一毫秒计算力

TFLite 异步推理流水线架构:用 C future/promise 榨干边缘 SoC 的每一毫秒计算力 一、同步推理的死锁陷阱——当预处理阻塞了下一帧 在边缘 AI 部署场景中,推理引擎的吞吐量瓶颈往往不在模型本身,而在数据流水线的串行阻塞。以 TFLite 在 ARM…

2026/7/15 23:30:35阅读更多 →
GPT-5.6模型发布:三箭齐发策略与API接入实战指南

GPT-5.6模型发布:三箭齐发策略与API接入实战指南

OpenAI 在 2026 年 7 月 9 日正式发布了 GPT-5.6 系列模型,这次采用了"三箭齐发"的产品策略,推出了旗舰型号 Sol、平衡型 Terra 和经济型 Luna 三个不同定位的模型。这次发布不仅是性能的全面提升,更重要的是在效率、成本控制和实际…

2026/7/15 23:25:35阅读更多 →
VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异当你在VSCode中启动一个新的TypeScript项目时,第一个技术决策往往从安装方式开始。这个看似简单的选择——全局安装还是项目本地安装——实际上会深刻影响你的开发流程、团队协作和…

2026/7/15 6:42:19阅读更多 →
智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手 【免费下载链接】zhihuishu 智慧树刷课插件,自动播放下一集、1.5倍速度、无声 项目地址: https://gitcode.com/gh_mirrors/zh/zhihuishu 智慧树刷课插件是一款专为智慧树在线教育平台设计的Chrome浏…

2026/7/15 6:12:45阅读更多 →
Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在GOG或Epic Games Store购买了心仪的游戏…

2026/7/15 10:54:00阅读更多 →
AI框架决定企业AI能走多远

AI框架决定企业AI能走多远

企业AI建设的第一性原理 企业搞AI,最关键的决定是什么?不是选哪家大模型,不是先做哪个场景,不是招多少AI人才——而是选哪个AI开发框架。 为什么?因为框架决定了企业AI能力的"天花板"。选对了框架&#xff0…

2026/7/15 0:01:30阅读更多 →
Java企业为什么需要AI框架

Java企业为什么需要AI框架

Java企业在AI时代的尴尬处境 Java是全球企业级应用开发的主流语言——全球超过一半的企业系统跑在Java上。但在AI浪潮面前,很多Java企业感到尴尬:大模型的接口是各种语言的,AI开发社区以其他语言为主流,似乎Java在AI时代"掉队…

2026/7/15 0:01:30阅读更多 →
CC3230x嵌入式开发实战:SD主机、定时器与低功耗模式深度解析

CC3230x嵌入式开发实战:SD主机、定时器与低功耗模式深度解析

1. 项目概述:为什么需要关注CC3230x的SD主机、定时器与低功耗?在物联网和嵌入式设备开发领域,我们常常面临一个核心矛盾:设备需要具备强大的连接能力、可靠的数据存储和实时控制功能,同时又必须严格控制功耗以延长电池…

2026/7/15 0:01:30阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/15 15:50:47阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/15 8:52:38阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/15 14:06:23阅读更多 →