Harness 可以理解为包在模型外面的运行时控制层。模型本身只会“读上下文、生成下一段文本或工具调用”harness 负责把用户输入、系统指令、工具、文件系统、权限、hook、技能等东西组织起来然后再喂给模型。具体链路大概是这样用户输入↓Claude Code / Ducc CLI runtime↓harness 预处理- 读取 CLAUDE.md / project rules / memory- 识别 slash command、skill、关键词- 注入 system-reminder- 准备可用工具列表- 加载当前目录、git、环境信息↓发送给模型↓模型输出- 普通文本- 或工具调用例如 Read / Bash / Edit / Skill / Agent↓harness 执行工具调用- 权限检查- 调用真实 shell / 文件系统 / MCP / agent runtime- 执行 PreToolUse / PostToolUse hook↓工具结果再次注入上下文↓模型继续下一步核心原理模型不直接访问你的机器。它只能“请求调用工具”。真正执行Bash、Read、Edit、Skill、Agent 的是 harness。所以 harness 的职责主要有 6 类1.上下文装配它把这些东西拼进模型上下文- 系统提示词- 用户消息- ~/.claude/CLAUDE.md- 项目内 CLAUDE.md- 当前工作目录信息- 可用工具列表- 已加载 skill 指令- hook 产生的 system-reminder2.权限控制当模型想执行 Bash、Write、Edit、Agent 等工具时harness 判断- 当前权限模式是否允许- 是否需要用户确认- 是否命中 deny / allow 规则- 是否是危险操作例如删除、覆盖、外发模型不能绕过这层。3.工具执行模型输出的是结构化工具调用比如{tool: Read,file_path: /path/to/file}3. harness 收到后才真的去读文件再把结果作为 tool_result 放回上下文。4.Hook执行在工具调用前后harness 会跑 hook例如- PreToolUse:Bash- PostToolUse:Write- PostToolUseFailure:Readhook 可以注入提醒例如- “长任务用 background”- “编辑后要验证”- “Read 多文件时并行”- “工具失败后分析错误继续处理”这些提醒不是用户说的也不是模型自己想出来的是运行时插入的控制信号。5.Skill加载当用户输入 /skill或者模型调用 Skill 工具时harness 会- 找到对应 skill 目录- 读取 skill 的说明文件- 把 skill 指令注入上下文- 后续模型按 skill 流程执行skill 本质上是“按需加载的专业提示词 工作流规则”。6.Agent/Workflow编排当模型调用 Agent 或 Workflow 时harness 会启动子模型实例或工作流脚本- 子 agent 有自己的上下文和工具权限- 可以并行跑- 最后把结果返回主会话- 主模型再综合结果关键词识别的位置这里有两种A.harness硬识别比如你刚才的 ultrathink。运行时检测到关键词后直接插入system-reminderThe user included the keyword ultrathink, requesting deeper reasoning on thisturn./system-reminder这是 CLI/harness 层完成的不靠模型主动发现。B.模型软识别比如 ralph、ulw、autopilot 这类CLAUDE.md 告诉模型“看到这些词要调用对应skill”。模型读到后自己决定是否调用。所以区别是- harness 硬识别确定性更强命中就注入- 模型软识别灵活能结合语境但不如硬规则确定本质总结Harness 是一个“模型运行容器 工具代理 权限网关 上下文编排器”。模型负责判断和生成下一步动作harness 负责- 给模型什么上下文- 允许模型调用什么工具- 工具调用是否能执行- 执行结果如何回填- 哪些规则和 hook 要强制插入- 如何启动 skill、agent、workflow所以你看到的 Ducc / Claude Code 体验不只是一个 LLM而是LLM 推理能力 CLI harness 工具系统 权限系统 hook 系统 skill 系统 agent/workflow 编排 本地文件和 shell 集成这些组合在一起才形成“能在本地开发环境里持续执行任务”的 Agent。