news 2026/9/23 1:28:41

Claude Code 长运行应用开发:Harness design 的 settings.json 配置骨架与验证

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Claude Code 长运行应用开发:Harness design 的 settings.json 配置骨架与验证

1. 长运行任务为什么总在 settings.json 上翻车

Claude Code 在 long-running application development 场景里跑长任务,最容易出问题的不是模型能力,而是 Harness design 没搭好。Harness design 说白了就是给 Claude Code 套一层"线束":权限怎么给、超时怎么设、日志往哪写、会话怎么续。这些全部落在settings.json里。你如果只把 Claude Code 当聊天窗口用,跑个十分钟的小脚本没问题;但一旦让它连续跑几小时去构建一个全栈应用,权限弹窗会打断它、默认超时会掐死它、日志缺失会让你根本不知道它卡在哪一步。

我试过用默认配置跑一个需要多轮迭代的前端生成任务,结果 Claude Code 在第 40 分钟左右因为一次 Bash 权限确认没人点,整个会话挂起,前面的上下文全白费。这就是典型的 Harness design 缺失:模型本身没问题,是外围的配置骨架没给它留出长跑的跑道。

这篇要解决的就是这件事。我会给出一份可以直接复制的settings.json骨架,覆盖权限白名单、超时控制、日志落盘三个核心字段,然后带你用一次真实的长任务运行去验证配置是否生效。适合已经在用 Claude Code、准备把它推进到长运行应用开发场景的开发者。读完你能拿到一份可用的配置模板,以及一套验证动作,知道每一步该看哪个文件、哪个日志、哪个返回码。

需要说明的是,Claude Code 的模型调用需要 API 凭证。我这边用的是 TaoToken 提供的接入方式,它的 API 地址是https://taotoken.net/api,兼容 Anthropic 的接口格式,配置起来和官方 SDK 的写法一致。下面所有配置示例都基于这个接入点,你可以直接替换成自己的凭证。

2. 前置准备:TaoToken 接入与 Claude Code 环境

在动settings.json之前,先把接入层理顺。Claude Code 通过环境变量读取 API 端点和密钥,所以你要先拿到一个可用的 Key,再把它写进环境。

2.1 获取 API Key

打开 TaoToken 的控制台,进入 API Keys 页面创建一个新 Key。创建时注意两点:一是给它起一个能识别用途的名字,比如claude-code-longrun,方便后面在日志里区分;二是记下创建后一次性展示的完整 Key,页面刷新后就看不到了。

拿到 Key 之后,把它写进 shell 的环境变量。我习惯放在~/.zshrc~/.bashrc里,这样每个新终端都能读到:

export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_API_KEY="sk-你的Key"

写完执行source ~/.zshrc让配置生效,然后用一条最简单的请求验证接入是否通:

curl -s https://taotoken.net/api/v1/messages \ -H "x-api-key: $ANTHROPIC_API_KEY" \ -H "anthropic-version: 2023-06-01" \ -H "content-type: application/json" \ -d '{ "model": "claude-sonnet-4-5", "max_tokens": 64, "messages": [{"role": "user", "content": "reply with ok"}] }'

如果返回里带content字段且文本是ok,说明接入层没问题。这一步别跳过,因为后面settings.json里的所有配置都建立在接入可用的前提上,接入不通的话你排查半天配置也是白搭。

2.2 确认 Claude Code 版本与配置目录

Claude Code 的配置分两层:用户级配置在~/.claude/settings.json,项目级配置在项目根目录的.claude/settings.json。长运行任务我建议用项目级配置,因为不同项目的权限需求不一样,混在用户级里容易互相污染。

先确认版本,老版本的字段名和新版本有差异:

claude --version

然后确认配置目录存在:

ls -la .claude/ 2>/dev/null || mkdir -p .claude && echo "created"

目录建好后,我们就可以往里写骨架了。

3. 可复制的 settings.json 配置骨架

这一节是全文的核心。我把骨架拆成权限、超时、日志三块讲,每块给出字段含义和取值理由,最后拼成一份完整文件。

3.1 权限字段:让长任务不被弹窗打断

长运行任务最怕的就是中途停下来等人确认。permissions字段就是干这个的。它的结构是allowdeny两个数组,allow里的工具调用不会触发确认,deny里的直接拒绝。

{ "permissions": { "allow": [ "Bash(git status)", "Bash(git diff:*)", "Bash(git add:*)", "Bash(git commit:*)", "Bash(npm run:*)", "Bash(npm install:*)", "Bash(pytest:*)", "Bash(python:*)", "Read(*)", "Write(src/**)", "Edit(src/**)" ], "deny": [ "Bash(rm -rf:*)", "Bash(curl:* | sh)", "Read(.env)", "Read(**/secrets/**)" ] } }

这里有几个设计取舍值得说。allow里我用了Bash(git diff:*)这种带冒号的写法,冒号后面的*表示匹配该命令的任意参数,这样git diff HEAD~1git diff main都能放行,不用一条条列。WriteEdit我限定在src/**下,是为了防止长任务跑偏去改配置文件或依赖锁文件。

deny里必须放rm -rf和管道执行远程脚本这两类,长任务里模型一旦判断失误执行了这类命令,损失是不可逆的。.env和 secrets 目录也要挡住,避免密钥被读进上下文再写进日志。

注意:allow的匹配是前缀匹配,Bash(python:*)会放行python -c "..."这种任意代码执行。如果你的长任务不需要跑任意 Python,把它收窄成Bash(python -m pytest:*)更安全。

3.2 超时字段:给长任务留足跑道

默认超时对长任务来说太短。timeout相关字段控制单次工具调用的等待上限和整个会话的空闲上限。

{ "timeout": { "toolCallMs": 600000, "sessionIdleMs": 1800000, "bashDefaultMs": 300000 } }

toolCallMs设成 600000(10 分钟),是因为长任务里一次npm install或一次全量测试跑几分钟很正常,默认值会在中途掐断。sessionIdleMs设成 1800000(30 分钟),给的是会话空闲容忍度,模型在思考或等待外部进程时不会因为短暂无输出被判死。bashDefaultMs是 Bash 命令的默认上限,5 分钟覆盖大多数构建和测试。

这三个值不要盲目调大。toolCallMs调到一小时以上,一旦某个命令真的卡死,你要等一小时才能拿到失败信号。我的经验是先用 10 分钟跑一轮,看日志里有没有接近上限的调用,再决定是否上调。

3.3 日志字段:让长任务可观测

长任务跑起来之后,你看不到中间过程就等于盲跑。logging字段把关键事件落盘,出问题时能回溯。

{ "logging": { "level": "info", "file": ".claude/logs/session.log", "rotate": { "maxSizeMb": 50, "maxFiles": 5 }, "includeToolCalls": true, "includeToolResults": false } }

levelinfo就够,debug在长任务里会产生巨量日志拖慢 IO。file指向项目内的.claude/logs/,方便和代码一起管理。rotate防止单个日志文件无限增长,50MB 一个、保留 5 个,足够覆盖一次几小时的长任务。

includeToolCalls开、includeToolResults关,是个折中:你能看到模型调了什么工具、传了什么参数,但不会把每次工具返回的大段内容都写进去。排查"模型为什么走了这一步"时,调用记录比返回内容更有用。

3.4 完整骨架文件

把上面三块拼起来,加上模型和会话相关字段,就是完整的settings.json

{ "model": "claude-sonnet-4-5", "permissions": { "allow": [ "Bash(git status)", "Bash(git diff:*)", "Bash(git add:*)", "Bash(git commit:*)", "Bash(npm run:*)", "Bash(npm install:*)", "Bash(pytest:*)", "Read(*)", "Write(src/**)", "Edit(src/**)" ], "deny": [ "Bash(rm -rf:*)", "Bash(curl:* | sh)", "Read(.env)", "Read(**/secrets/**)" ] }, "timeout": { "toolCallMs": 600000, "sessionIdleMs": 1800000, "bashDefaultMs": 300000 }, "logging": { "level": "info", "file": ".claude/logs/session.log", "rotate": { "maxSizeMb": 50, "maxFiles": 5 }, "includeToolCalls": true, "includeToolResults": false }, "context": { "autoCompact": true, "compactThreshold": 0.85 } }

context这块是给长任务续命用的。autoCompact开启后,上下文接近窗口上限时自动压缩历史,compactThreshold设成 0.85 表示用到 85% 就开始压。长运行应用开发动辄几小时,不压缩的话上下文早就爆了。

把这份文件写到.claude/settings.json,然后进入验证环节。

4. 验证配置生效:一次长任务运行

配置写完不代表生效。这一节带你用一次真实的长任务,逐项确认权限、超时、日志三个字段都按预期工作。

4.1 构造一个会触发多轮工具调用的任务

验证任务要足够长,能触发权限、超时、日志三条路径。我用一个"生成并测试一个小型 Python 包"的任务来验证,它会依次触发 Write、Bash(pytest)、Bash(git commit):

claude -p "在 src/ 下创建一个 Python 包 mycalc,包含 add 和 divide 两个函数,divide 要对除零抛 ValueError。然后写 pytest 测试覆盖正常和异常路径,跑通测试后 git add 并 commit。"

这条命令用-p进入非交互模式,正好模拟长任务无人值守的场景。如果权限配置没生效,它会在第一次 Write 或 Bash 时停下来等确认,任务直接卡住。

4.2 检查权限是否放行

任务跑起来后,另开一个终端看日志:

tail -f .claude/logs/session.log

日志里应该出现类似这样的记录:

{"ts":"2025-01-15T10:23:11Z","event":"tool_call","tool":"Write","args":{"path":"src/mycalc/__init__.py"},"permission":"allowed"} {"ts":"2025-01-15T10:23:45Z","event":"tool_call","tool":"Bash","args":{"command":"pytest tests/"},"permission":"allowed"}

关键是"permission":"allowed"这个字段。如果看到"permission":"prompted",说明你的allow规则没匹配上,需要回去检查命令写法。比如pytest tests/要能被Bash(pytest:*)匹配,如果你写的是Bash(pytest tests/:*)就匹配不到带其他参数的调用。

4.3 检查超时是否按预期工作

超时不好直接观察,但可以通过一个故意跑长的命令来验证。在任务里加一步sleep

claude -p "执行 bash -c 'sleep 400',然后告诉我完成了。"

sleep 400是 400 秒,小于bashDefaultMs的 300000 毫秒(300 秒)?不对,400 秒大于 300 秒,所以这条命令应该被超时掐断。日志里会出现:

{"ts":"2025-01-15T10:30:00Z","event":"tool_result","tool":"Bash","status":"timeout","elapsedMs":300012}

看到"status":"timeout"elapsedMs接近 300000,说明bashDefaultMs生效了。如果你希望这类长命令能跑完,就把它挪到一个单独的allow规则里并配更长的超时,而不是全局调大bashDefaultMs

4.4 检查日志轮转与上下文压缩

长任务跑完后,确认日志文件按预期生成和轮转:

ls -lh .claude/logs/

应该看到session.log以及可能的session.log.1等轮转文件。如果单次任务就产生了超过 50MB 的日志,说明includeToolResults可能被误开了,回去关掉。

上下文压缩的验证看日志里的 compact 事件:

grep "compact" .claude/logs/session.log

出现{"event":"context_compact","beforeTokens":180000,"afterTokens":45000}这样的记录,说明autoCompact在上下文接近上限时触发了压缩,长任务能继续跑下去。

5. 本篇常见错误排查

配置跑不通时,按下面这几类对照排查,基本能覆盖九成问题。

5.1 权限规则不匹配导致任务卡住

最常见的现象是任务跑一半不动了,日志停在某个tool_call没有后续。这通常是allow规则没匹配上。Claude Code 的权限匹配是精确到命令前缀的,Bash(npm run:*)能匹配npm run build,但匹配不了npx npm run build。排查方法是把日志里那条tool_callargs.command复制出来,和你的allow规则逐条比对。

另一个坑是Write(src/**)这种 glob 写法。不同版本对**的支持不一致,保险起见可以写成Write(src/*)Write(src/**/*)两条,覆盖一层和深层目录。

5.2 超时字段名写错导致不生效

timeout下的字段名在不同版本里改过。老版本用toolTimeout,新版本用toolCallMs。如果你写了老字段名,配置不会报错,但也不会生效,任务还是按默认超时跑。排查方法是启动时加--debug看配置加载日志:

claude --debug -p "test" 2>&1 | grep -i timeout

如果输出里没有你配置的值,说明字段名不对,对照当前版本文档改。

5.3 日志文件不生成或为空

日志不生成通常是两个原因:一是logging.file的目录不存在,Claude Code 不会自动创建父目录;二是level设成了error,而正常任务没有 error 事件。先手动建目录:

mkdir -p .claude/logs

再把level调成info重跑。如果日志生成了但内容为空,检查includeToolCalls是否为true,设成false的话工具调用不会记录,日志里就只剩会话级事件。

5.4 上下文压缩没触发导致任务中断

长任务跑到后面报上下文超限,但日志里没有 compact 事件,说明autoCompact没开或compactThreshold设得太高。compactThreshold是比例值,设成 0.95 意味着用到 95% 才压,留给压缩本身的空间就不够了。建议设在 0.8 到 0.85 之间。另外确认context字段是顶层字段,不要嵌在logging里。

5.5 接入层报错被误判为配置问题

如果任务一开始就报 401 或连接失败,别急着改settings.json,先回到第 2 节的 curl 验证接入。接入不通时,Claude Code 的表现和配置错误很像,都是任务起不来。区分方法是看日志里有没有tool_call事件:有tool_call说明接入是通的,问题在权限或超时;一个tool_call都没有就报错,问题在接入层。

6. 把配置沉淀成可复用的骨架

跑通一次验证之后,建议把这份settings.json抽成模板,按项目类型分几套。前端项目、后端服务、数据脚本的权限需求差别很大,混用一套配置要么放得太宽要么卡得太死。

我自己的做法是在仓库里放一个.claude/settings.template.json,新项目初始化时复制成.claude/settings.json再按需改allow列表。模板里denytimeoutlogging三块保持不动,只调权限白名单。这样既保证安全底线一致,又给不同项目留了灵活度。

另外,长运行任务的成本要心里有数。一次几小时的自主构建,token 消耗可能是短任务的几十倍。建议在settings.json里配好日志之后,定期用日志统计工具调用次数和 token 用量,找到哪些步骤在烧钱。如果发现某类工具调用频繁且收益低,就把它从allow里拿掉,逼模型换更高效的路径。

配置骨架搭好只是 Harness design 的第一步。真正跑长任务时,你还会遇到模型在某个功能上反复迭代、评估环节缺失导致质量下滑等问题。这些需要在骨架之上再加规划器和评估器角色,但那属于下一层的设计,先把这份settings.json跑稳,再往上叠。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/23 1:28:12

Synopsys License 部署与排错实战:从 lmgrd 到 snpslmd 全解析

简介:这份资源面向需要配置Synopsys工具授权环境的学习者,尤其是Windows平台下进行license生成与调试的初学者和进阶用户。压缩包内仅含1个docx文档,体积约269KB,以文字说明形式梳理了授权文件从获取到可用的完整流程,…

作者头像 李华
网站建设 2026/9/23 1:27:37

qcow2镜像转vmdk并在VMware Workstation运行的完整指南

简介:针对使用VMware Workstation运行qcow2格式镜像这一高频需求,整理了一份从零开始的操作手册,目标读者是虚拟化运维、系统部署、环境测试人员。手册详细描述了环境准备所需的软件及版本(VMware Workstation 15.x、qemu-img 9.1…

作者头像 李华
网站建设 2026/9/23 1:27:32

HarmonyOS视频通话App开发:从选库到集成的完整链路与质量调优

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/23 1:25:23

CEEMDAN-ISOS-VMD-GRU-ARIMA时间序列预测实战解析

简介:这是一份面向时间序列预测与毕业设计场景的完整且可直接运行的Python工程,基于TensorFlow实现CEEMDAN、VMD、GRU与ARIMA的组合建模,覆盖信号分解、特征提取、神经网络预测和误差修正的完整流程,适合需要开展组合预测研究或课…

作者头像 李华
网站建设 2026/9/23 1:25:17

PaddleOCR 2.6实战指南:从环境搭建到部署避坑

简介:面向希望基于 PaddleOCR 2.6 快速上手文本检测与识别训练的开发者和初学者,提供从零开始的实操教程,教程以 Word 文档形式整理,包内共 1 个 docx 文件,整体大小约 78KB。内容按环境配置、依赖安装、PPOCRLabel 标…

作者头像 李华