HumanLayer 跨会话交接指南:用 create_handoff 规范手写 Handoff 文档,让 AI 编程会话无缝续跑
【免费下载链接】humanlayerThe best way to get AI coding agents to solve hard problems in complex codebases.项目地址: https://gitcode.com/GitHub_Trending/hu/humanlayer
导读
本指南以 HumanLayer 仓库中.claude/commands/create_handoff.md为核心,系统讲解如何为 AI 编程助手生成一份高质量的手写交接文档(handoff document),将当前会话的上下文(任务状态、关键引用、近期改动、经验教训、待办事项)压缩打包给下一个新会话。读完本文,你将掌握交接文档的命名规范、元数据生成脚本、YAML frontmatter 模板、八段式正文结构与humanlayer thoughts sync同步流程,以及配套的/resume_handoff恢复机制,从而在多会话、多 Agent 协作场景下实现"零信息丢失"的上下文延续。
Handoff 文档是什么,为什么需要它
大模型驱动的 AI 编程助手(如 Claude Code)在长时间工作中会积累大量上下文。当一次会话的资源耗尽、需要开启新会话继续时,如果只靠口述或零散笔记,很容易丢失关键的任务细节、架构决策和踩坑经验。
HumanLayer 的解决方案是一份结构化、紧凑、信息密度高的交接文档:由当前会话的 Agent 按固定规范撰写,保存到 thoughts 系统的共享目录,再由新会话通过/resume_handoff命令完整读取并继续工作。正如命令文档开篇所定义的:
"You are tasked with writing a handoff document to hand off your work to another agent in a new session. You will create a handoff document that is thorough, but alsoconcise. The goal is to compact and summarize your context without losing any of the key details of what you're working on."
核心目标只有一个:在不丢失任何关键信息的前提下,将你的上下文压缩并总结。这与 HumanLayer 的 Thoughts 管理系统(详见 hlyr/THOUGHTS.md)深度绑定——交接文档默认存放在thoughts/shared/handoffs/下,属于团队共享类笔记,天然支持 git 版本管理和跨会话检索。
从源码结构看,这一整套交接机制由三份核心文件构成,构成了"创建 → 同步 → 恢复"的完整闭环:
| 环节 | 文件 | 职责 |
|---|---|---|
| 创建 | .claude/commands/create_handoff.md | 规定交接文档的命名、元数据、模板与写作原则 |
| 同步 | hlyr/src/commands/thoughts/sync.ts | 将交接文档提交进 thoughts 仓库并构建可搜索索引 |
| 恢复 | .claude/commands/resume_handoff.md | 读取并验证交接文档,生成行动计划继续工作 |
整体流程:创建、批准同步、恢复三步走
create_handoff命令把整个交接过程划分为三个明确的阶段,Agent 必须依次执行:
第一步:确定文件路径与收集元数据
- 按照下文"文件路径与命名规范"一节确定交接文档的存放位置;
- 运行元数据生成脚本
spec_metadata.sh收集日期、commit、分支、仓库名等元数据(脚本实际实现见 hack/spec_metadata.sh)。
第二步:按模板撰写交接文档
使用命令文档给定的 YAML frontmatter + 八段式正文模板撰写,内容必须完整覆盖任务状态、关键引用、近期改动、经验教训、产物、下一步行动等。
第三步:批准与同步
运行humanlayer thoughts sync将文档保存进 thoughts 仓库。完成后,以<template_response></template_response>为边界(标签本身不输出)回复用户,告知后续恢复命令:
/resume_handoff path/to/handoff.md例如:
/resume_handoff thoughts/shared/handoffs/ENG-2166/2025-01-08_13-44-55_ENG-2166_create-context-compaction.md文件路径与命名规范
交接文档必须存放在thoughts/shared/handoffs/下的 ticket 目录中,命名格式如下:
thoughts/shared/handoffs/ENG-XXXX/YYYY-MM-DD_HH-MM-SS_ENG-ZZZZ_description.md各字段含义:
| 字段 | 说明 |
|---|---|
ENG-XXXX | 工单号(ticket number),若无工单则替换为general |
YYYY-MM-DD | 当天日期 |
HH-MM-SS | 24 小时制的时、分、秒(即13:00表示下午 1 点) |
ENG-ZZZZ | 工单号(无工单时省略该段) |
description | 简短的 kebab-case(连字符小写)描述 |
官方给出的两个示例:
- 带工单:
2025-01-08_13-55-22_ENG-2166_create-context-compaction.md - 不带工单:
2025-01-08_13-55-22_create-context-compaction.md
完整路径示例(与 resume_handoff.md 中的定位逻辑一致):
thoughts/shared/handoffs/ENG-2166/2025-01-08_13-44-55_ENG-2166_create-context-compaction.md注意:时间戳嵌入文件名不是装饰。
resume_handoff在按工单号(如ENG-XXXX)恢复时,会先ls该 ticket 目录,若存在多个交接文档,则依据文件名中的YYYY-MM-DD_HH-MM-SS(24 小时制)自动选择最近的一份。因此命名规范直接决定了恢复时能否选中最新的交接状态。
元数据生成:spec_metadata.sh 脚本
命令文档要求运行scripts/spec_metadata.sh来生成所有相关元数据。在当前仓库中,该脚本的实际位置是 hack/spec_metadata.sh(命令文档中写作scripts/spec_metadata.sh,使用时以仓库实际位置为准)。其实现要点如下:
- 输出当前日期时间(含时区,ISO 风格):
date '+%Y-%m-%d %H:%M:%S %Z' - 输出用于文件名的无冒号时间戳:
date '+%Y-%m-%d_%H-%M-%S' - 若处于 git 仓库内(通过
git rev-parse --is-inside-work-tree判断),输出:- 仓库根目录与仓库名(
git rev-parse --show-toplevel+basename) - 当前分支(
git branch --show-current,回退到git rev-parse --abbrev-ref HEAD) - 当前 commit 哈希(
git rev-parse HEAD)
- 仓库根目录与仓库名(
- 若检测到
humanlayer命令可用,则捕获humanlayer thoughts status的前 40 行输出,用于获取研究者姓名等信息
这些输出将直接填充 YAML frontmatter 中的date、researcher、git_commit、branch、repository等字段,确保交接文档的时间线与代码状态可精确复现。
YAML frontmatter 模板详解
交接文档以 YAML frontmatter 开头,随后才是 Markdown 正文。命令文档给出的完整模板字段如下:
--- date: [Current date and time with timezone in ISO format] researcher: [Researcher name from thoughts status] git_commit: [Current commit hash] branch: [Current branch name] repository: [Repository name] topic: "[Feature/Task Name] Implementation Strategy" tags: [implementation, strategy, relevant-component-names] status: complete last_updated: [Current date in YYYY-MM-DD format] last_updated_by: [Researcher name] type: implementation_strategy ---各字段的填写说明与用途:
| 字段 | 填写内容 | 用途 |
|---|---|---|
date | 含时区的 ISO 格式当前时间 | 记录文档创建时间,配合文件名时间戳排序 |
researcher | 来自humanlayer thoughts status的研究者名 | 标识文档作者,便于追溯 |
git_commit | 当前 commit 哈希 | 精确锁定交接时的代码版本 |
branch | 当前分支名 | 记录工作分支,恢复时避免跑错分支 |
repository | 仓库名 | 多仓库场景下定位归属 |
topic | 形如"<功能/任务名> Implementation Strategy" | 一句话概括主题,便于检索 |
tags | [implementation, strategy, 相关组件名] | 供 AI 与搜索引擎检索的标签 |
status | complete(或进行中状态) | 标记文档本身是否定稿 |
last_updated | YYYY-MM-DD格式日期 | 支持文档被多次更新 |
last_updated_by | 研究者名 | 记录最后更新人 |
type | implementation_strategy | 文档类型,与 plans / research 等类型区分 |
type字段尤其重要:resume_handoff恢复流程会依据交接文档中链接的thoughts/shared/plans或thoughts/shared/research文档继续读取上下文,因此保持type、tags的一致性有助于自动化流程正确分类与跟进。
正文八段式模板:每段的写作要点
frontmatter 之后,正文必须包含以下八个部分。命令文档对每段给出了明确的写作指引:
1. Task(s)——任务与状态清单
描述你在处理的任务及其状态(completed 完成 / work in progress 进行中 / planned/discussed 已计划或已讨论)。若你正在推进某个实施计划,务必标明当前处于哪个阶段。如果会话开始时提供了计划文档或研究文档,应明确引用它们。
2. Critical References——关键引用
列出必须遵守的关键规范文档、架构决策或设计文档。命令文档明确要求只保留 2~3 个最重要的文件路径,避免罗列过多稀释重点。若没有则留空。
3. Recent changes——近期改动
用line:file语法(命令文档原文写法)描述你刚对代码库做的改动,例如:
packages/dashboard/src/app/dashboard/page.tsx:12-24让接手者能快速定位到具体行号,而不是大海捞针。
4. Learnings——经验教训
记录重要收获:代码模式、bug 根因,或其他接手者必须知道的关键信息,尽量显式列出文件路径。这是交接文档中信息价值最高的部分——resume_handoff的恢复流程会优先"完整读取 Learnings 中的文件"来建立认知。
5. Artifacts——产物清单
穷举你产出或更新的所有产物,以文件路径和/或file:line引用形式给出,例如功能文档、实施计划的路径。接手者按此清单顺序阅读即可无缝恢复工作。
6. Action Items & Next Steps——行动项与下一步
为下一个 Agent 列出基于当前任务与状态应该做的行动项清单,并排出优先级。
7. Other Notes——其他备注
其他有用的参考信息,例如相关代码库的位置、相关文档的位置,以及其他你学到但无法归入以上类别的重要信息(命令文档原文保留了 "leanrned" 拼写,实际含义即 learnings 的补充)。
写作总原则
命令文档在最后给出了三条贯穿始终的写作纪律,这是交接文档质量的"硬性底线":
- 更多信息,而不是更少(more information, not less)——该原则定义了交接文档的信息量下限,必要时永远可以补充更多内容;
- 彻底且精确(be thorough and precise)——既要包含顶层目标,也要包含必要的底层细节;
- 避免过量的代码片段(avoid excessive code snippets)——除非确有必要(例如正在调试的报错),否则不要贴大段代码或 diff;优先使用
/path/to/file.ext:line引用,让接手 Agent 在需要时再自行打开对应位置。
批准与同步:humanlayer thoughts sync 做了什么
交接文档写好之后,必须执行humanlayer thoughts sync将文档保存到 thoughts 仓库。这一步由 hlyr/src/commands/thoughts/sync.ts 实现,其底层行为值得了解:
- 校验配置:先加载 thoughts 配置,未配置或当前仓库未初始化 thoughts 时直接报错退出;
- 补齐新用户符号链接:扫描 thoughts 仓库中的用户目录,为当前仓库补充缺失的
thoughts/<user>符号链接; - 重建可搜索索引:创建
thoughts/searchable/目录(旧版为.search),递归遍历(含符号链接解析、环检测),对所有非CLAUDE.md文件在 searchable 目录下建立硬链接,供不跟随符号链接的搜索工具直接检索(findFilesFollowingSymlinks函数负责此逻辑,见 sync.ts 第 101-196 行); - 提交与推送:对 thoughts 仓库执行
git add -A→ 若有变更则git commit(默认消息为Sync thoughts - <ISO时间>,可用-m/--message覆盖)→git pull --rebase拉取远端 → 若配置了origin远端则git push; - 冲突处理:若 pull 时出现冲突(检测
CONFLICT (、Automatic merge failed、Patch failed at等特征),会明确提示用户手动解决冲突后执行git rebase --continue再重新 sync。
值得一提的是,日常开发中通常不需要手动执行 sync——humanlayer thoughts init会安装 git hooks(见 init.ts 第 188-317 行):
- pre-commit hook:检测暂存区出现
thoughts/路径时直接拒绝提交并git reset HEAD -- thoughts/,防止私有笔记被误提交进代码仓库; - post-commit hook:每次代码提交后自动在后台执行
humanlayer thoughts sync --message "Auto-sync with commit: <提交消息>"(worktree 场景除外,见其引用的 ENG-1455 说明)。
因此交接文档保存到thoughts/shared/handoffs/后,配合后续代码提交即可自动进入 thoughts 仓库。命令文档中的标准做法仍是显式执行一次humanlayer thoughts sync,以确保文档立即落库。
恢复交接:/resume_handoff 的完整流程
恢复侧由 .claude/commands/resume_handoff.md 定义,支持两种调用方式:
# 方式一:直接指定交接文档路径 /resume_handoff thoughts/shared/handoffs/ENG-XXXX/YYYY-MM-DD_HH-MM-SS_ENG-XXXX_description.md # 方式二:仅给工单号,自动选择该 ticket 下最近的交接文档 /resume_handoff ENG-XXXX恢复流程分四步:
- 完整读取:无分页地读完整个交接文档,并立即读取其链接的
thoughts/shared/plans与thoughts/shared/research文档(不委派子 Agent 读取这些关键文件); - 并行研究任务:派发并行子任务收集所有产物上下文、提取关键需求与决策,并等待全部完成;
- 综合呈现:向用户呈现"原始任务 → 当前验证状态、关键经验 → 是否仍有效、近期改动 → 是否存在/变更、产物 → 要点、推荐下一步、潜在问题"的结构化分析,取得用户确认后再行动;
- 制定行动计划:将交接文档中的行动项转换为 todo 列表,按依赖与优先级排序后开始实施。
该文档还总结了四种典型恢复场景及应对策略,交接文档的作者在撰写时即可预判:
| 场景 | 特征 | 策略 |
|---|---|---|
| 干净延续(Clean Continuation) | 改动齐全、无冲突、下一步明确 | 按推荐行动直接推进 |
| 代码库已分叉(Diverged Codebase) | 部分改动缺失或被修改、有新代码 | 先协调差异、调整计划 |
| 交接工作未完成(Incomplete Handoff Work) | 存在in_progress任务 | 先补完未完成的工作 |
| 交接已过期(Stale Handoff) | 时间久远、大重构发生 | 重新评估策略,不盲信旧方案 |
同时强调五条纪律:分析要彻底(先读全文再验证所有改动)、保持交互(先呈现再动手)、善用交接智慧(重点看 Learnings)、保持连续性(在 commit 中引用交接文档)、行动前验证(绝不假设交接状态等于当前状态,所有文件引用都要复核存在性)。
与 Thoughts 系统的目录与配置上下文
交接文档之所以放在thoughts/shared/handoffs/下,是因为 HumanLayer Thoughts 系统专门为"与代码分离的笔记 + AI 友好检索"而设计(完整说明见 hlyr/THOUGHTS.md)。初始化后代码仓库会出现:
your-project/ ├── thoughts/ │ ├── alice/ # → ~/thoughts/repos/your-project/alice(个人笔记) │ ├── shared/ # → ~/thoughts/repos/your-project/shared(团队共享,handoffs 在此) │ ├── global/ # → ~/thoughts/global(跨仓库笔记) │ ├── searchable/ # 供 AI 搜索的硬链接索引(自动生成、只读) │ └── CLAUDE.md # 自动生成的 AI 上下文说明 └── .gitignore相关配置项定义在 hlyr/src/thoughtsConfig.ts 中,核心结构为:
{ "api_key": "...", "thoughts": { "thoughtsRepo": "~/thoughts", "reposDir": "repos", "globalDir": "global", "user": "alice", "repoMappings": { "/Users/alice/projects/app": "app_thoughts", "/Users/alice/projects/api": "api_backend" } } }常用管理命令(对应实现见 init.ts、status.ts、config.ts):
humanlayer thoughts init # 初始化(安装 hooks、建立符号链接、生成 CLAUDE.md) humanlayer thoughts status # 查看配置、仓库映射、thoughts 仓库 git 状态 humanlayer thoughts sync -m "描述" # 手动同步(含 searchable 索引重建) humanlayer thoughts config --edit # 编辑配置(--json 输出 JSON)交接文档最佳实践清单
综合create_handoff命令规范与恢复流程的要求,一份高质量的交接文档应满足:
- 信息量只多不少:宁可多写,不可省略;顶层目标与底层细节并重;
- 引用优先于贴码:用
file:line引用代替大段代码,只在调试报错等必要场景贴少量代码; - 关键引用精炼:Critical References 只保留 2~3 个最重要的文档;
- Learnings 是核心资产:根因、模式、反例都要记录并附文件路径;
- 命名即元数据:时间戳 + 工单号 + kebab-case 描述,确保
/resume_handoff ENG-XXXX能选中最新的文档; - 交接后立即同步:
humanlayer thoughts sync落库,并告知用户/resume_handoff <path>恢复命令; - 恢复时先验证:接手者不得假定交接状态等于当前状态,需逐一核对文件引用与改动是否仍然存在。
总结
HumanLayer 的 handoff 交接机制把"跨会话续跑"从临时的口头交接升级为规范化的文档工作流:create_handoff负责按统一模板压缩上下文,humanlayer thoughts sync负责将文档纳入 git 版本管理的共享仓库并构建 AI 可检索的硬链接索引,/resume_handoff负责完整读取、验证状态并生成行动计划。三者配合,再叠加 pre-commit / post-commit 钩子的自动保护与同步,让多会话、多 Agent 的长周期开发任务不再因上下文丢失而返工。对任何使用 AI 编程助手处理复杂代码库的团队而言,这套"命名规范 + 元数据 + 模板 + 同步 + 恢复"的交接范式都值得直接借鉴到日常研发流程中。
【免费下载链接】humanlayerThe best way to get AI coding agents to solve hard problems in complex codebases.项目地址: https://gitcode.com/GitHub_Trending/hu/humanlayer
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考