第 2 课

CLAUDE.md 项目记忆与 claude -p 无头模式

按官方 Memory 与 Headless 文档:/init 生成 CLAUDE.md、写可验证指令、@ 导入、/context 核对;claude -p 管道、JSON 与 Schema 输出、--allowedTools、续接对话与 --bare。

图文25 分钟Claude Code 官方文档 ↗

课程目录第 2 / 2 课

学习位置仅保存在当前浏览器,有效期 180 天。

01 / 图文教材

图文讲义

来源:Anthropic 官方文档 · How Claude remembers your project、Run Claude Code programmatically、CLI reference。核对日期 2026-10-06。 假设你已完成课时 1:claude 可用、已登录,并有练习项目 ~/kun-claude-demo。

你将得到什么

  • 一份项目级 CLAUDE.md:让 Claude 每次会话都记得构建命令、代码规范和「必须做」的规矩
  • 会用 /init、/context、/memory 生成、核对与编辑记忆文件
  • 会用 claude -p 以非交互方式运行 Claude Code:管道输入、JSON 输出、预先授权工具、续接对话

为什么需要 CLAUDE.md

官方说明:每个 Claude Code 会话都从全新的上下文窗口开始。跨会话保留知识有两种机制:

CLAUDE.md自动记忆(auto memory)
谁来写你Claude 自己
内容指令与规则从你的纠正和偏好中学到的要点
作用范围项目、个人或组织每个仓库一份,worktree 间共享
加载每次会话每次会话(MEMORY.md 前 200 行或 25KB)

两者都被当作上下文而不是强制配置。必须拦截的操作(例如禁止某条命令)应改用 hook 或权限规则。

步骤 1:用 /init 生成起始 CLAUDE.md

在练习项目中启动会话:

cd ~/kun-claude-demo
claude

在会话中输入:

/init

对照结果:

  • Claude 分析代码库后,在项目根目录创建 CLAUDE.md,写入它发现的构建、测试命令与项目约定
  • 若 CLAUDE.md 已存在,/init 会提出改进建议而不是覆盖
  • 它也会读取 .cursor/rules/、.cursorrules、.github/copilot-instructions.md 等其他工具的规则并合并相关部分

想要多阶段交互流程,可在运行 /init 前设置环境变量 CLAUDE_CODE_NEW_INIT=1:它会询问要生成 CLAUDE.md、skills 还是 hooks,再给出可审阅的方案。

步骤 2:把规矩写成可验证的指令

打开生成的 CLAUDE.md(或用会话命令 /memory 选中项目 CLAUDE.md 在编辑器中打开),整理成下面这样。官方建议:每个文件少于 200 行,用标题和列表分组,指令要具体到可验证。

# kun-claude-demo

## Commands
- Run tests: `python3 test_calc.py` (prints `ok` on success)

## Conventions
- Use 4-space indentation and type hints on public functions
- Raise `ValueError` for invalid input; never return `None` silently
- Run the tests before every commit

## Layout
- Library code lives in `calc.py`; tests live in `test_calc.py`

官方给出的写法对比,可直接套用:

含糊(效果差)具体(效果好)
Format code properlyUse 2-space indentation
Test your changesRun npm test before committing
Keep files organizedAPI handlers live in src/api/handlers/

文件放哪里

范围位置是否进版本库
个人(所有项目)~/.claude/CLAUDE.md否,仅你自己
项目(团队共享)./CLAUDE.md 或 ./.claude/CLAUDE.md是
项目(仅本人)./CLAUDE.local.md否,加入 .gitignore

启动时会加载当前目录及所有上级目录中的 CLAUDE.md 与 CLAUDE.local.md,并按「从根目录到当前目录」的顺序拼接;子目录中的文件在 Claude 读取该目录文件时才按需加载。

用 @ 导入其他文件

CLAUDE.md 里可以用 @路径 导入文件,导入内容在启动时一并加载(最多递归 4 层):

See @README.md for project overview.

# Additional Instructions
- git workflow @docs/git-instructions.md

注意:导入只帮助组织内容,不会减少上下文占用。若只是想提到一个路径而不导入,把它写成行内代码(用反引号包起来)即可。

步骤 3:确认 CLAUDE.md 已生效

退出后重新启动会话(/exit,再执行 claude),输入:

/context

对照结果:在 Memory files 列表中看到 ~/kun-claude-demo/CLAUDE.md。然后做一次行为验证:

add a multiply(a, b) function and commit it

对照结果:新函数带类型标注;Claude 在提交前先运行 python3 test_calc.py。这两点都来自你写进 CLAUDE.md 的规矩。

已经在用 AGENTS.md 的仓库:v2.1.277 及以上,若目录链上没有任何 CLAUDE.md,Claude 会直接读取 AGENTS.md;两者都有时默认只读 CLAUDE.md。想共用一份,可在 CLAUDE.md 首行写 @AGENTS.md。

查看自动记忆

当你在会话里说「always use pnpm, not npm」这类偏好时,Claude 会写入自动记忆,位置在 ~/.claude/projects/<project>/memory/,索引文件是 MEMORY.md。用 /memory 可浏览这些文件、打开记忆文件夹或开关自动记忆。要写进 CLAUDE.md 而不是自动记忆,直接说「add this to CLAUDE.md」。

步骤 4:用 claude -p 一次性提问

-p(--print)让 Claude Code 非交互运行:执行完就退出,成功时退出码为 0,失败为非零,方便脚本判断。

cd ~/kun-claude-demo
claude -p "What does calc.py do? Answer in one sentence."
echo "exit code: $?"

对照结果:终端打印一句对 calc.py 的说明,随后是 exit code: 0。

管道输入与重定向输出

非交互模式会读取 stdin,可以像普通命令行工具一样串联:

python3 -c "import calc; calc.divide(1, 0)" 2> error.txt
cat error.txt | claude -p "concisely explain the root cause of this error" > output.txt
cat output.txt

对照结果:output.txt 中是对 ValueError: b must not be zero 的简短解释(若你在课时 1 已改过 divide)。管道输入上限 10MB,更大的内容请写成文件并在提示中引用路径。

步骤 5:JSON 输出与结构化结果

--output-format 可选 text(默认)、json、stream-json。json 会返回结果、会话 ID 与元数据,文本在 result 字段中。先确认本机有 jq(jq --version),再运行:

claude -p "Summarize this project" --output-format json | jq -r '.result'

对照结果:只打印摘要文字。JSON 中还带有 session_id 与 total_cost_usd(客户端估算,可能与账单不同)。

需要固定结构时,加 --json-schema,结果放在 structured_output 字段:

SCHEMA='{"type":"object","properties":{"functions":{"type":"array",
"items":{"type":"string"}}},"required":["functions"]}'
claude -p "List the function names defined in calc.py" \
  --output-format json --json-schema "$SCHEMA" | jq '.structured_output'

对照结果(函数顺序以实际输出为准):

{
  "functions": ["add", "divide", "multiply"]
}

步骤 6:预先授权工具,让脚本不被卡住

非交互运行时没人点「允许」,需要用 --allowedTools 预先放行,语法与权限规则一致:

claude -p "Run python3 test_calc.py and fix any failures" \
  --allowedTools "Bash(python3 *),Read,Edit"

Bash(python3 *) 中 * 前的空格表示前缀匹配:允许所有以 python3 开头的命令。官方特别提醒:没有空格时,Bash(git diff*) 也会匹配 git diff-index。

也可以直接指定整次运行的权限模式:

写法效果
--permission-mode acceptEdits可直接写文件,其他命令仍需放行
--permission-mode dontAsk凡是需要询问的一律拒绝,适合锁死的 CI
--permission-mode auto由分类器审核每个操作

示例:让它直接改文件补注释,而不放行其他命令。

claude -p "Add a one-line docstring to every function in calc.py" \
  --permission-mode acceptEdits

对照结果:calc.py 中每个函数都多了一行 docstring,git diff 可见改动。

步骤 7:续接对话

claude -p "Review calc.py for edge cases"
claude -p "Now focus on divide()" --continue

第二条带 --continue,会接着最近一次对话继续。并行跑多个对话时,用会话 ID 精确续接:

sid=$(claude -p "Start a review of calc.py" --output-format json | jq -r '.session_id')
claude -p "Continue that review" --resume "$sid"

对照结果:第二条回复明确引用上一轮的审查内容,而不是从头开始。

步骤 8(CI 推荐):--bare 模式

--bare 会跳过 hooks、skills、插件、MCP 服务器、自动记忆和 CLAUDE.md 的自动发现,让每台机器上的结果一致,官方推荐在脚本与 CI 中使用。注意:bare 模式不读取订阅登录凭据,需要设置 Claude Console 创建的 ANTHROPIC_API_KEY:

export ANTHROPIC_API_KEY="sk-ant-..."   # 换成你自己的 Key,勿提交到仓库
claude --bare -p "Summarize README.md" --allowedTools "Read"

对照结果:快速返回 README 摘要;因为跳过了 CLAUDE.md,回答不会体现你在步骤 2 写的项目规矩。需要额外上下文时,用 --append-system-prompt、--settings、--mcp-config 等参数显式传入。

本课检查清单

  • /context 的 Memory files 中能看到项目 CLAUDE.md
  • Claude 的新改动遵守了你写的规矩(类型标注、提交前跑测试)
  • claude -p ... --output-format json | jq -r '.result' 只输出文本
  • 能用 --allowedTools 让脚本无人值守地跑完

常见问题

现象处理
Claude 不遵守 CLAUDE.md用 /context 确认已加载;把指令改具体;排查多个文件互相矛盾
CLAUDE.md 太长控制在 200 行内;只对部分文件生效的规则移到 .claude/rules/
-p 运行卡在权限用 --allowedTools 放行,或指定 --permission-mode
--bare 报未认证bare 不用订阅登录,需设置 ANTHROPIC_API_KEY
--json-schema 报错检查 Schema 是合法 JSON Schema,引号是否被 shell 吃掉

延伸阅读:官方 Best practices 与 CLI reference。

本课资料

适用环境

  • macOS
  • Windows
  • Linux
  • 网页
  • iOS

官方文档

Claude Code ↗