执行轨迹与日志

适用版本:ChengOS v0.1.0+ | 最后核对:2026-08-12 | 来源:crates/cheng-core/src/domain/execution_archive.rscrates/cheng-core/src/domain/archive_policy.rscrates/cheng-nodes/src/nodes/builtin/tools/get_trace.rscrates/cheng-api/src/rest/handlers/execution/mod.rs

一次执行有三种彼此独立的视图,而本页最重要的一点就是:它们从不混为一谈。

视图 消费者 生命周期
执行归档 授权的服务端查询、支持、审计 可配置的持久保留
模型上下文投影 下一次 LLM 回合 受历史编织预算约束
界面轨迹投影 Web 界面与 CLI 默认是瞬时的

把它们当成一样东西,系统最终要么把载荷泄进模型上下文,要么在界面缓存过期时丢掉审计记录。

界面轨迹投影

执行进行时,编辑器与 CLI 依据 WebSocket 事件流渲染它——EXECUTION_STARTEXECUTION_PROGRESSNODE_COMPLETENODE_FAILED、流式与工具事件,以及终态的 EXECUTION_COMPLETE / EXECUTION_FAILED / EXECUTION_CANCELLED。见 WebSocket API

这个投影是瞬时的。为了重连恢复,另有一份有界快照:

GET /executions/:id/trace-snapshot

归属校验刻意跑在存储查找之前,这样响应就无法泄露「别的用户是否存在快照」。运行中途重连的客户端会取这份快照并合并进来,而不是留下空白——见编辑器内嵌对话

执行日志

GET /executions/:id/logs?offset=&limit=

分页的结构化日志,级别为 DEBUG / INFO / WARN / ERROR。这是针对某一次运行的「按顺序发生了什么」视图。

持久执行归档

归档是一次已完成智能体回合的、带版本的结构化记录:循环运行期间可追加,一旦提交即不可变

有三条规则支配它:

  1. 持久化的助手消息始终是权威的公开答案。 归档从不替代它。
  2. ArchiveRef 是不透明的。 它绝不编码路径、租户名、文件名或可预测的回合序号。
  3. 原生工具调用的重建只读结构化步骤。 渲染出来的轨迹文本绝不会被反解析成协议消息。

归档是权威的细节来源;紧凑的历史摘要是它的一个投影,反过来则不成立。

引用

ArchiveRef 是 32 位小写十六进制、无连字符的 UUIDv4。从不可信输入解析时会拒绝其他一切形状,正因如此,路径穿越在存储适配器里是结构上不可能的,而不是适配器需要用字符串检查去防守的东西。目录分片使用从该 ID 自身派生的两级前缀(ab/cd),因此目录规模有界,且没有任何调用方可控的数据抵达文件系统。

步骤

每个归档步骤都携带序号、来源的智能体循环迭代、助手动作、工具结果和时间戳。

replay_blocked 是其中微妙的字段:当捕获本身存在歧义时——供应商的调用 ID 重复,或一次调用出现了第二个结果——该步骤仍然会被归档,因为它是审计者必须看到的真实历史;但它绝不会被重放,因为「哪个结果属于哪次调用」没有真实答案。重放校验会完整检查一一配对规则,而不是抽样检查。

查询模式

归档可以按三种宽度读取:

模式 返回
summary(默认) 计数、工具名、状态、终态——不含参数,不含载荷
tool_calls 逐步的工具名、调用 ID、状态,以及策略允许的参数——不含结果载荷
detail 策略允许的一切,包含有界的结果载荷

无法识别的模式字符串会回落到 summary,而不是悄悄放宽暴露面。

调用方选择的是模式,而不是响应大小。 渲染出的投影在服务端被限制在 24000 字符以内,因此模型无法索要无界的转储。

策略:保留与脱敏

归档策略会被盖章到每一份归档上,因此策略变更之后,旧对象依然可解释。

保留级别

级别 实际 TTL
ephemeral 基准 TTL,且不超过 1 小时
standard(默认) 基准 TTL
extended 基准 TTL × 12

ephemeral 刻意封顶在基准以下:它的存在是为了支撑瞬时的界面恢复窗口,而不是充当第二个持久存储。级别是持久元数据,由清理任务从目录中读取,而不是从当前配置重新推导——因此调低默认 TTL 不会追溯性地缩短、调高也不会追溯性地延长一份已写入归档所声明的寿命。

脱敏模式

模式 归档什么
strict 只有结构化元数据——名称、状态、大小。不存任何载荷字节
balanced(默认) 有界载荷,并对明显敏感的参数键做遮蔽
diagnostic 按配置上限存载荷、不做键遮蔽——仅限短保留期的诊断环境

脱敏发生在生产者边界:落盘的归档已经是脱敏后的。因此后来的策略变更绝不可能把先前写入的数据变得更暴露。当脱敏判定的含义发生变化时,策略版本会递增,于是旧归档保留其原本的解释。

工作区级的轨迹保留可单独配置,并对已完成和失败的执行分别设置天数——失败通常值得比成功活得更久。

在工作流内部读取轨迹

tools/get_trace 让 ReAct 智能体按需读取上一回合的记录。模型先在回合元数据里看到一份紧凑摘要;需要细节时才调用这个工具。

[agent/react].tools ──▶ [agent/get_execution_trace]

两条彼此独立的查找路径:

输入 来源
trace_key{session_id}:{turn} 旧的进程内会话存储——无限期保留
archive_ref 持久归档,带鉴权与基于策略的裁剪

旧会话只有 trace_key;新会话写入 archive_ref;迁移期间二者可能并存,且不会移除或重新解释任何旧键。二选一提供即可。

问「你用了哪些工具」要用 mode: tool_calls——summary 没有调用细节,而 detail 会花掉你多半并不需要的上下文。

重放与重跑

GET  /executions/:id/containers/:cid/iterations             列出循环迭代轨迹
POST /executions/:id/containers/:cid/iterations/:idx/rerun  重跑某一次迭代

循环迭代可以逐次追踪、逐次重跑,因此调试一个 100 项的批处理不必把 100 项全部重来。见子流程与批量子流程

重试失败的执行会产生新的执行 id,而不是改动旧记录:失败的那次运行原样留存,作为证据。

其余接口

GET  /executions                      列表
GET  /executions/active               正在运行的
GET  /executions/history              历史
GET  /executions/:id                  单次执行
GET  /executions/archives/:ref        读取归档
POST /executions/:id/cancel|pause|resume|approve

下一步

© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容