> ## Documentation Index
> Fetch the complete documentation index at: https://docs.openkova.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 循环视图

> 看清 agent 每一轮在想什么、调了什么工具、为什么停下来——以及进程崩了之后还能看到多少。

agent 的一次回复可能内部跑了十几轮：调模型、跑工具、把结果喂回去、再调模型。
你只看得到最后那段话。中间哪一步慢了、哪个工具失败了三次、模型为什么决定换条路，
默认全是黑盒。

循环视图就是把这个黑盒打开。它在右侧面板里，与「链路追踪」并列，
入口在会话标题旁的**更多**菜单 → **循环**。

## 两个视角，别混淆

同一个会话的同一份数据，两种切法：

| | 链路追踪 | 循环 |
| - | - | - |
| 分层依据 | span 类型（LLM / 工具 / 重试） | **迭代**（一次循环 = 意图 → 工具 → 结果回喂） |
| 擅长回答 | 时间都花在哪了 | 模型想干什么、为什么这么干、为什么停 |
| 形状 | 瀑布 | 迭代带 + 回喂边 |

排查性能看链路追踪，排查行为看循环。

## 迭代带怎么读

每一轮循环是一条**迭代带**：

```
┌ 迭代 3   确认是 4.18.2，把它提到 ^4.21.0 再装          3.27s ┐
│  claude-sonnet-4.5                    ▓▓▓▓▓▓░░░    1.92s    │
│  edit                          ▓▓░░░                148ms   │
│  bash                              ▓▓▓▓▓▓▓▓▓▓▓▓     …   ⟳   │
└─────────────────────────────────────────────────────────────┘
                  ↓ 结果回喂
```

**带头那行是模型自己写的意图**——取它这一轮回复的首句。这是整个视图里最值钱的一层：
它直接告诉你模型打算干什么，而不是让你从工具名去猜。上面那条就是模型原话
「确认是 4.18.2，把它提到 ^4.21.0 再装」。

**每行一个步骤**，右侧时间条按耗时定宽、按 `atMs` 定位，所以横向能直接比出快慢。
失败行整行染红（`exit 127` 这类退出码直接标在行上），重试行染琥珀。

**迭代之间的箭头是回喂边**，标注了喂回模型的内容摘要。这是循环的骨架——
瀑布图里看不出这条边。

**子代理**以缩进形式嵌在派发它的那一轮里，父 run 的迭代计数含子 run。

## 四层 token 读数

上下文逐轮增长是长任务成本的主驱动，所以 token 分四级给：

| 层级 | 位置 | 读的是什么 |
| - | - | - |
| 步骤 | LLM 行右侧 `↑15.2k` | 这次请求带入的**上下文总量** |
| 迭代 | 带头 `上下文 15.2k · 出 1.1k` | 本轮结束时的上下文规模 |
| 运行 | 顶部概要 `↑ 67,740 / ↓ 4,680` | 含子代理递归的合计 |
| 会话 | 左下角汇总 | 跨 run 总计 + 缓存命中量 |

缓存命中单独标绿，因为它是不重复计费的那部分。

## 终止归因

底部那条回答「循环为什么停在这」：

| 归因 | 含义 |
| - | - |
| 自然收尾 | 模型不再要求工具 |
| 用户停止 | 你按了 Stop。**不是错误**，不污染错误率 |
| 上下文溢出 | 压缩后重跑 |
| 长度续跑预算耗尽 | 反复撞长度上限，自动续跑用完 |
| 异常终止 | 模型或 provider 报错 |
| 意外中断 | 进程死在半路（见下） |

前五项在采集时就区分开了：用户取消与模型报错在底层是两回事，混在一起会让
错误率失去意义。

## 长时间任务：跑着就能看

迭代是**逐轮落盘**的，所以任务还在跑的时候，迭代带就一条条往外长
（有在途工具时每 2 秒刷新一次），不必等它跑完。

这依赖一个刻意的取舍：轨迹在每一轮结束时写一次盘，而不是等整个 run 结束。
轮级写入的频率是一次迭代一下，与 token 无关——流式输出的热路径上依然零 IO。

## 进程崩了还能看到什么

这是轨迹唯一的崩溃兜底。

如果 sidecar 在任务中途被杀，那次运行在内存里的完整树会丢。但因为迭代是逐轮落盘的，
下次启动会把它**抢救回来**：面板上出现一条标注「**意外中断**」的运行，
包含崩溃前所有已闭合的轮次。

**边界要说清楚**：丢的是**当前正在跑的那一轮**。比如崩在一次长命令执行中间，
那一轮不会出现——它的工具还没有结果。已经跑完的轮次一轮不少。

（崩溃前对话的消息内容另有转录兜底，所以不会连聊到哪都丢。丢的是时序与归因结构。）

## 筛选

一个长会话可能有几十轮、上百个步骤，靠滚是找不到东西的。

* **只看失败**：一刀切到所有失败、重试与进行中的步骤
* **按工具名筛**：点工具名按钮收窄（可叠加「只看失败」）

右上角实时显示命中比例（如 `13/118 步`）。切换运行会自动清空筛选。

## 数据与分辨率

<Note>
  轨迹落在会话数据目录下的 `traces/<sessionId>.jsonl`，一行一个完整的运行。
  在飞的运行走 `traces/<sessionId>.live.jsonl`，按轮追加。
</Note>

需要知道的几个截断与取舍：

* **请求上下文与工具出参都是截断保存的**。轨迹是元数据视图，不是转录的副本。
  工具失败时的输出保留得更多（stderr 是诊断核心），成功时截得更紧。
* **超长运行的早期轮次会丢弃正文**。单次运行保留的正文总量有上限，超出后从
  **最旧**的轮次开始释放——最新的那次请求才是你要看的。此时点开早期轮次，
  结构、耗时、状态都还在，只是「请求上下文」为空。这是为了让内存不随运行长度
  无限增长。
* **没有 token 级直播**。视图的粒度是「一轮」，看不到正在流式输出的字。

## 下一步

<CardGroup cols={2}>
  <Card title="Agent 引擎" icon="cpu" href="/features/agent-engine">
    循环背后的机制：模式、权限、压缩、子代理。
  </Card>

  <Card title="子代理" icon="users" href="/features/subagents">
    一次派发出去的并行任务，在循环视图里是缩进的嵌套运行。
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.