mcpField
A
agent-session-batch-export

agent-session-batch-export

github.com/samuka007数据与数据库096 次安装6 周前更新
代码仓库

关于 agent-session-batch-export

agent-session-batch-export 将 Claude Code 和 Codex 对话记录整理为供 Agent 分析的语料。分阶段筛选和导出会原样保留选中文件并记录哈希,同时提供审核式、可复现及优先召回的收集流程。

主要功能

  1. 01扫描并筛选会话记录
  2. 02审核并批准保留或丢弃项
  3. 03导出逐字节一致的文件并记录 SHA-256
  4. 04按主题运行可复现的方向导出
  5. 05收集带注释的数据池和行卡片

适用场景

  1. 01准备对话记录以分析 Agent 轨迹
  2. 02创建经用户审核的会话语料
  3. 03导出可复现的主题会话集合
  4. 04构建供后续标注使用的广泛候选池

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/samuka007/skills --skill agent-session-batch-export

安装后在 Claude Code 中输入/agent-session-batch-export确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

README.md
scripts/
curate-sessions.ps1
curate-sessions.sh
export-direction.sh
funnel.py
pick-sessions.ps1
pick-sessions.sh
policy.json
themes/
coding.json
multimodal.json
planning.json
report-analysis.json
rewriting.json
role-play.json
translation.json
writing.json

详细介绍

将 Agent 会话整理为轨迹材料

将大量 claude_code / codex 转录整理为少量可验证未修改的语料,供 Agent 分析。

scripts/curate-sessions.sh — 无索引、无守护进程、无网络。python3 是此技能的前置条件,而非某个分支的前置条件:选择引擎是 scripts/funnel.py,不存在不依赖它就能生成语料的受支持路径。

核心特性:保留的文件是与原件逐字节相同的副本,每个文件都记录了 sha256。不会重新渲染、总结或转换,因此下游分析读取的是实际轨迹(每次工具调用及其结果),而非有损视图。

流程

在 Windows 上使用 scripts\pick-sessions.ps1 / scripts\curate-sessions.ps1(参数相同)——原因见“交互界面”。下方的 .sh 示例采用 Linux/WSL/macOS 写法。

根据谁能看到终端来选择入口,而非凭个人偏好:

交互式 Shell(你或用户能看到终端)。 单命令入口会运行整个流程并打开选择器;必要时会启动一个终端:

bash scripts/pick-sessions.sh -o ./cur --agent codex --min-lines 20

Agent / 无头环境 / CI(没有可见终端)。 不要循环调用入口。运行这四个阶段;它们就是入口内部调用的内容,分阶段路径完全受支持(使用的是相同代码):

C=scripts/curate-sessions.sh

# 1. scan — enumerate candidates -> OUT/candidates.tsv
bash $C scan -o /tmp/cur --workspace cits4012 --min-lines 20

# 2. screen — YOU read the candidates and annotate them (see Screening)
#
# 3. review --ui tsv — emit decisions.tsv (no TUI, never blocks)
bash $C review --ui tsv -o /tmp/cur

# 4. THE USER edits decisions.tsv: set decision=keep|drop per row.
#    STOP here and run the Hand-off gate first — never fill the
#    decision column yourself.
#
# 5. finalize — ONLY after user approval (gate step 3), as their delegate:
#    materialize -> OUT/keep/*.jsonl + OUT/manifest.json
bash $C finalize -o /tmp/cur

用户可以打开终端,但 Agent 不行时(纯 Linux、无桌面):在第 2 阶段后生成一键启动器并交给用户——这就是此环境下的交互式审查:

bash $C package -o /tmp/cur
# -> /tmp/cur/open-review.sh
# tell the user: open a terminal in /tmp/cur and run `bash open-review.sh`

启动器会在经过筛选的候选项上打开 fzf 选择器;用户确认后,会在同一次运行中完成语料定稿和验证。一次交互即可完成——Agent 负责扫描和筛选,用户负责决定保留或丢弃。

如果你仍在无头环境中调用入口,它不会假装能够运行:它会打印出这套包含实际路径的分阶段流程,然后以非零状态码退出。

每个阶段都有一个完成标准:

阶段完成条件
scancandidates.tsv 中每个通过元数据筛选的会话各有一行
screen每行都有一个 suggested(keep/drop)和一行 reason
reviewdecisions.tsv 的每一行都有 decision
finalize用户已批准保留/丢弃列表(交接关卡),manifest.json 列出了每个保留的会话,并且每个 kept_as 与其 source 比较结果相同
预筛选:candidates.tsv 可能已经是 funnel 筛选后的幸存项

你开始处理前,scan 和你之间可能已经运行了确定性预筛选。如果运行过,幸存项就是 candidates.tsv——完整扫描结果已归档在旁边的 candidates.full.tsv 中——而 screen.tsv 也已针对这些行重新生成,其 suggested/reason 列留空,供筛选步骤填写。funnel 的推荐体现在行集合本身:这些幸存项就是它认为值得关注的会话,仍由你负责筛选。你标记为 keep 的行会由选择器预先选中,也会由 --yolo 导出。所有下游步骤——review、finalize、关卡——无论哪种情况,读取的都是相同文件。该引擎随此技能一同提供,位于 scripts/funnel.py。

方向导出(scripts/export-direction.sh)

方向是一项采购——一组命名主题,不由 Agent 对散文内容作判断就直接导出。之所以有这条路径,是因为合作方必须能够复核的选择必须可复现,而让模型阅读散文内容则无法做到这一点。

bash scripts/export-direction.sh --direction-file DIR.json -o OUT --yolo

与上面的流水线相比,最关键的区别是:**没有筛选步骤。**漏斗留下的会直接写入 decisions.tsv,因此没有 screen.tsv 行需要你填写。你可以查看漏斗表,并在出现灾难性问题时中止运行。你不能编辑 candidates.tsv、screen.tsv、decisions.tsv 或漏斗的输出,也不能自行选择保留或剔除哪些行。这样做会以你的判断取代可复现的选择,而这正是这条路径要消除的唯一因素。

所有数值都来自一套全局策略:scripts/policy.json 是共享的质量标准,执行引擎会在自身所在目录查找它——文件缺失会导致硬错误,不会使用默认值。主题文件(themes/<name>.json)只包含主题身份信息:keywords、label、来源信息,以及可选的 override,用于替换该主题的策略键(翻译主题会调整每条消息的下限,角色扮演主题会收紧工具上限,而 themes/coding.json 会将编码信号词表视为正向主题)。方向文件会列出主题,并在采购有所约束时携带覆盖项——非代码方向的根级 override 提供 exclude_keywords,即定义“非代码”的词表。各值按键合并,后者优先:标志、方向条目、方向根级配置、主题、全局策略;null 会清除某个键,空列表会关闭该阶段。报告时切勿重述阈值;请指出键名。

两种长度控制互不相关

如果要求不要剔除短会话,应使用 --min-lines:此脚本(以及 scan)中的文件行数下限。传入 0 后,扫描到的文件不会因为过短而被剔除。它是一个标志,而在此路径中,这是你唯一可以设置的长度控制项。

会话中的消息是否足够长,则由独立的策略决定。全局策略中有一个单条消息字符数下限,键为 min_user_msg_chars,由漏斗的 L5 length 阶段应用;主题或方向的 override 可以替换它,翻译主题就是如此。运行器没有为它提供选项——方向的选择必须仅凭策略及其覆盖项即可复现——因此,即使运行时使用 --min-lines 0,用户发言低于该键要求的会话仍会被剔除。漏斗表会如实报告剔除原因(longest later user msg N < M),运行器也会打印调用方需要更改的键。报告时请指出该键名;切勿重述其值。

有两种可处理而非致命的失败情况,都需要由用户决定:

  • **python3 不可用。**执行引擎使用 Python,没有备用方案。请显示脚本提供的 scoop install python / winget install Python.Python.3.13 提示,并询问是否安装后重试。切勿自行替代语义筛选。
  • 发现凭证格式。默认情况下,这些会话会从交付内容中排除——绝不会写入;运行结果会列出每项排除的信息(来源和凭证类型)及数量;请将该列表报告给用户。其余内容照常交付,清单会记录这些排除项。 使用 --allow-credentials 会将这些会话纳入交付——这是明确的人为决定,并会记录在清单中;可以向用户提供此选项,但切勿擅自启用。 使用 --credential-hard-gate 则会拒绝整个批次(退出码为 3,不写入任何内容)。无论采取何种处理方式:交付的会话都不会清理脱敏——分享前请先审核。

Collection (funnel.py collect) — 第三种模式

交付阶段会筛选;收集阶段会添加注释。collect CANDIDATES.tsv OUTDIR [--theme NAME] [--max-first-prompt-chars N] 是上游的、优先保证召回率的模式,详见 DESIGN.md § Collection and labeling:不消耗模型令牌、不设阈值,也不会读取全局策略。唯一会丢弃的是结构上无法使用的行(unparseable)和字节完全相同的文件(exact_duplicate);其余内容都会进入 OUTDIR/pool.tsv,其中包含完整的补充信息和注释列;此外,OUTDIR/row-cards.jsonl 中每行还会有一张独立的行卡片(首条提示词、计数、标记、主题匹配项——买家自己的模型可以据此判断,约几百个令牌),并生成 dropped.tsv,列明每条被丢弃记录及其原因。--theme NAME 只会将关键词添加到 theme_hits,绝不作为阈值。不要筛选、排序或精简池:精确度判断由下游标注者负责,而此模式承诺不会丢失任何仍可能通过行卡片售出的内容。引擎文档字符串和 FUNNEL.md § Collection mode 提供了逐列参考。

筛选(阶段 2)

scan 会写入两个文件:candidates.tsv(7 列,仅供参考)和 screen.tsv——包含相同行,并在末尾附加两列 suggested 和 reason,列标题已写好,内容留空。阶段 2:直接编辑 screen.tsv。 不要另起文件名(此前运行生成的 candidates.screen.tsv 不属于约定),也不要从头新建文件:review 和 finalize 会准确读取 OUT/screen.tsv / OUT/decisions.tsv。逐行填写:

  • suggested:填写 keep 或 drop(只能是这两个词)
  • reason:填写一行证据(不能包含制表符或换行符——该文件是 TSV)

然后,review --ui tsv 会将其转换为 decisions.tsv,并将 decision 默认设为你填写的 suggested;人工只需修改自己不同意的行。

交接关卡(在此停止——这不是由你决定的)

首先,根据请求选择路径。 对交付用途的非代码会话导出,默认使用 nocode 方向启动器(session-export-nocode),且该启动器按设计无需人工参与:它始终运行 --yolo,因此无需交接,也没有需要通过的关卡。本节中的分阶段流水线——筛选、交接关卡、经用户批准后完成——适用于没有已发布方向涵盖的请求,以及用户想逐行审核的情况。不要因为偏好而将普通的非代码导出请求转到分阶段路径;方向默认设置的目的,正是避免这种由心情驱动的路径选择。

保留或丢弃由用户决定。你的筛选只是建议,绝不能代替用户做决定。两条路径中,完成操作的含义不同:

  • 交互式(pick-sessions.sh / .ps1 入口 / open-review.sh): 用户在 fzf 中按下 ENTER 即表示批准——随后会自动运行完成操作,无需再询问任何内容。
  • 无头模式:finalize 是交由 Agent 执行的接口,只有通过下方关卡后才可以使用。

第 2 阶段结束后,你必须停止,并在任何操作改动 decision 或运行 finalize 之前,将选择交给用户:

  1. 展示筛选摘要:候选项数量、你标记为保留的数量,以及丢弃原因(按组归类,每组一行)。
  2. 然后为用户启动交互式选择器——这是默认方式,不是可选项: 在 Windows 上运行 pick-sessions.ps1(或在 WSL 下运行 pick-sessions.sh);选择器窗口会显示筛选后的列表,用户在 fzf 中按下 ENTER 后即可一次性完成并验证。你可以自行启动;不要只是描述它,然后退而要求用户通过文本回复。只有在选择器无法打开时(纯 Linux、没有桌面环境),才将已打包的启动器交给用户:curate-sessions.sh package,然后告知他们在任意终端运行 bash open-review.sh。
  3. 仅在用户明确拒绝使用选择器,或无法打开终端时,才使用纯文本确认(“回复 确认导出”)作为后备方案。不要自行填写任何内容:由用户编辑 decisions.tsv(或告知你确切的修改),然后且仅然后,你才能以其代理人的身份运行 finalize。review --ui tsv 会在退出时打印此关卡提示,确保无头路径上的每个 Agent 都能看到。

切勿自行填写 decision 列并运行 finalize。有两次实际运行就犯了这个错误:用户请求导出,却从未看过保留/丢弃列表,导出就已经完成。用户未批准的导出不算完成任务,即使每份副本都已验证为逐字节一致也是如此。

豁免条款:--yolo(仅限明确选择退出)

如果用户明确表示不需要审核(“直接导出”“不用我看”或 “just export it”),则运行 pick-sessions.sh --yolo(或 finalize --yolo):跳过选择器,导出已筛选的 keep 行(若未筛选,则导出所有候选项),并在清单中记录 mode=yolo, reviewed=false, approved_by=user-opt-out。不会跳过完整性检查 — sha256 + cmp 仍会验证每个副本。只有用户明确表述时才能使用 Yolo:绝不能根据用户话少、沉默或听起来很忙来推断。若用户没有明确表示要退出审核,则运行上述常规关卡。

在方向路径中,此条款已是默认设置:session-export-nocode 启动器始终传入 --yolo(清单会记录 batch_confirmed=false),而 --confirm 会恢复批次级的 [y/N] 确认点。上述措辞要求适用于暂存路径和交互路径,在这些路径中,审核是默认设置。

根据正文判断,而不是根据元数据行。第 6 列(first_prompt)是分流提示,可能为空:codex 会将 <environment_context>、AGENTS.md 和 skills 脚手架内容写成用户消息,而这些内容会作为脚手架剥离,不会作为正文报告。first_prompt 为空表示会话没有由人编写的开场轮次 — 这本身就是应设为 drop 的信号。

Codex 会将这些注入的区块标记为普通 message 项,因此,仅根据 payload.type == "message" 进行筛选的读取器也会提取约 80 行系统样板内容。请将范围限制为 payload.role 为 user 或 assistant 的项。

finalize 只读取 decision 列,因此人工只需编辑一个字段,就能覆盖你的 suggested 值。

验证语料库

finalize 会为每个会话记录 source、kept_as 和 sha256。移交语料库前,请确认每个副本都逐字节相同:

jq -r '.[] | "\(.source)\t\(.kept_as)"' /tmp/cur/manifest.json > /tmp/pairs.tsv
while IFS=$'\t' read -r s d; do cmp -s "$s" "$d" || echo "MISMATCH $s"; done < /tmp/pairs.tsv

先将配对列表写入文件。从进程替换(done < <(jq …))向循环提供输入时,如果作业在后台运行或被中断,read 会因管道阻塞而卡住,导致挂起而不是失败。

选择器会在完成最终处理后自行运行此检查,并输出 verified: N/N copies byte-identical。

选项

scan:

  • --agent claude|codex|both(默认 both)
  • --workspace SUBSTR — 会话实际 cwd 的子字符串
  • --topic REGEX — 对提取出的正文应用扩展正则表达式
  • --since YYYY-MM-DD
  • --min-lines N — 丢弃占位会话:设置 FILE 行数下限,与全局策略中的每条 MESSAGE 行数下限无关(见方向导出)

review:

  • --ui fzf(存在 fzf 时的默认值)或 --ui tsv — tsv 会生成 decisions.tsv,供手动编辑,对应无头路径的第 3 步
  • --resume — 保留 decisions.tsv 中已有的决定

finalize:

  • --from FILE — 读取默认文件以外的决策 TSV
  • --yolo — 在清单中标记 mode=yolo, reviewed=false(仅限不审核的运行;参见关卡的豁免条款)
  • --hardlink — 创建硬链接而非复制。仅用于只读分析:下游写入者可能会通过链接损坏原件。

validate 会检查 TSV 的列结构,并统计其决策列。

delivery 会将 OUT/keep/ + OUT/manifest.json 打包为一个归档文件以供移交。格式遵循平台要求(Windows Git Bash 上为 zip,其他平台上为 tar.gz),且 --out FILE 可显式指定归档文件名;清单始终包含在归档中。打包前会验证所有已记录的 sha256,之后会重新读取归档;若没有可打包的内容,则会拒绝操作,而不会生成空归档。

pick-sessions.sh 接受 -a/--agent、-w/--workspace、-t/--topic、 --since、-n/--min-lines、-o/--out、-y/--yes、--review-only、 --yolo、--no-finalize、--stay、-h。

输出目录

pick-sessions.sh 会建议一个带日期和 Agent 标记的默认目录 (./curated-<agent>-<YYYYmmdd-HHmm>),并通过交互方式确认: 按 Enter 接受;输入 e 后再输入路径(按 Tab 补全);输入 q 退出;或者直接输入路径。 -y 会跳过提示;非 tty 调用也会跳过提示,因此脚本化运行不会阻塞。固定的默认目录会让连续运行的结果堆到同一个目录中,语料也就无法再反映单次选择。

如果第二次运行时选择数量更少,keep/ 会被替换,而非在其基础上添加,因此语料始终与当前的选择结果完全一致。

数据源

Agent路径工作区字段正文内容字段
claude_code~/.claude/projects/<munged>/<uuid>.jsonl.cwd.message.content(字符串,或 {type:"text",text} 数组)
codex~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonlsession_meta.payload.cwdpayload.type=="message" 且 payload.role 为 user/assistant 时的 .payload.content[].text

由此可得出两条规则,且两条都至关重要:

  • 从字段中读取工作区,绝不从目录名读取。 claude 会将 / 替换为 -,因此 -home-nixos-workspace-cits4012-a1 可能指 …/cits4012/a1,也可能指 …/cits4012-a1,无法区分。
  • 只将提取出的正文内容与主题匹配。 匹配原始 JSONL 行字节会命中 base64 附件和 tool_result 负载,产生看似确凿的垃圾结果。

交互界面

这个技能本身就是产品;其交互体验按环境定义,关键只在于一个问题:能否启动 Windows 端终端? 答案决定了其他一切:

环境交互式选择器无 tty 时
Windows Git Bash(原生)启动运行 Git Bash 的 Windows Terminal分阶段流程
WSL(可访问 Windows 桌面)启动运行 wsl.exe 的 Windows Terminal分阶段流程
纯 Linux/服务器无 — 没有可统一启动的终端;如果调用方已有 tty(用户在自己的终端中运行 review --ui fzf),则可以正常工作分阶段流程或打包的启动器

“分阶段流程”是非交互式的完成方式:screen → review --ui tsv → 编辑 → finalize(参见 Pipeline)。在没有用户终端的无头运行中, curate-sessions.sh package 会写入一个单击式启动器,供用户之后在自己的终端中运行 — 这就是纯 Linux 上的交互体验。

绝不会使用 tmux/zellij 为用户启动窗口;它们仅作为未公开的内部测试工具,供 Agent 以编程方式驱动 TUI 使用。

会话分布在两端;scan 会读取当前所在环境的 HOME

scan 会读取脚本运行环境中的 $HOME/.claude/projects 和 $HOME/.codex/sessions。在 WSL 中运行时,它读取的是 Linux 端;Windows 端的目录(/mnt/c/Users/<you>/.claude/projects、 /mnt/c/Users/<you>/.codex/sessions)格式相同,但不会自动扫描。若要将其纳入扫描,请针对该 HOME 运行脚本:

HOME=/mnt/c/Users/<you> bash $C scan -o /tmp/cur-win --agent both

(可以在 WSL 中执行 — 格式相同,而且由于 Windows cwd 会规范化为 / 分隔符,--workspace 匹配的工作方式也相同。)

WSL:没有可见终端 → 选择器会在 Windows 端打开终端

如果 WSL shell 有真实终端,pick-sessions.sh 会直接运行。如果没有 — 例如从工具调用、CI 步骤或任何非交互式上下文中调用 — 它会请求启动 Windows 端终端,并按以下顺序在那里运行选择器:

  1. wt.exe -- wsl.exe -d $WSL_DISTRO_NAME — Windows Terminal(首选)
  2. cmd.exe /c start … wsl.exe — 普通控制台窗口

启动请求仅代表已请求,不代表已确认:wt.exe 会在启动操作交接后立即以 0 退出,因此“已请求”仍可能意味着没有可见窗口出现(桌面连接断开、服务会话)。因此,父进程会在显示启动消息的同时输出分阶段流程,并以 0 退出;如果没有窗口出现,只需运行它输出的分阶段命令即可。

Windows:在 bash 中原生运行(Git Bash / MSYS)

整个脚本都在 MSYS 下运行,不涉及 WSL——这是原生的 Windows 交互方式。在 Windows 上,请调用 .ps1 包装脚本,而不是 bash xxx.sh: scripts\pick-sessions.ps1 / scripts\curate-sessions.ps1 会定位 Git Bash,并用它重新执行实际脚本,因此调用方的 shell 身份(cmd、PowerShell,或 bash 指向 WSL bash 的 Agent)无关紧要。 两个入口,两种意图:.ps1 包装脚本表示“我想要的会话在 Windows 端”;在 WSL 中运行 .sh 表示使用 Linux 端的会话。脚本无法根据运行环境推断这种意图,因此不要根据哪个 shell 恰好位于 PATH 中来选择入口。

如果未安装 Git Bash,包装脚本会显示安装说明(winget install Git.Git)。

设置需要两个软件包——MSYS 已捆绑其余 POSIX 用户空间组件:

scoop install jq ripgrep          # or: winget install jqlang.jq BurntSushi.ripgrep.MSVC

没有 tty 时,pick-sessions.sh 会启动 运行 Git Bash 的 Windows Terminal,为选择器提供真实的 tty。

将脚本指向 Windows 端的会话目录树:~/.codex 和 ~/.claude 会解析为 C:\Users\<you>\…,其中存放着相同格式的文件。

评论

支持 Markdown