第 1 卷
19|规则系统:让规则可生成、可审批、可生效
张嘉熙 · DeepSeek Harness 前沿工程实践




你好,我是张嘉熙。
上一讲我们能够手写规则了,但那些规则一切都得靠人:改动就是人手工编辑 rules.json 文件,Agent 既不能生成新规则,也不能在运行期发起变更;而且每次改动就是直接改文件,
留不下历史:谁改的、什么时候改的,事后无从追溯。
一个“能自进化”的防火墙,规则得先能被 Agent 起草,再经审批决定是否放行,并在批准后真正生效;同时每一笔改动都要记进账本,改动才留得下历史。这里有两层要分清:谁来发起
可以由 Agent 起草一版候选规则;是否放行默认等人拍板,但松紧不是写死的,自主级别由人决定。
批准后的规则怎样实际生效?
关于环境:本讲示例在配套 cookbook 的 src/firewall/ch19/,账本事实的通用机制放在 src/firewall/shared/fact-log.ts,第 21 讲共用同一套;需要
DEEPSEEK_API_KEY:其中“Agent 起草候选”一步由真实 DeepSeek 模型把自然语言意图起草成规则(见 agent-draft.ts → shared/llm.ts 的 ask(),后者内部用 dsh
的 LlmRuntime + DeepSeekAdapter);其余机制,包括 ledger 折叠、串行写链、原子写、命令与级别,都是纯确定性代码,与模型无关。审批闸与命令这两条“接 dsh”的线
都有端到端测试:审批走真实 tools.execute 的 pre-execute / 单调 guard 管线(approval-e2e.test.ts),并在真实 agent-loop 里让真实 DeepSeek 模型发起写
工具调用、验证级别 0 被拒 / 级别 2 放行(agent-loop.test.ts);命令走真实 commands 注册表(command-seam.test.ts)。
关于示例:npm run start:ch19 跑完整链路:起草候选 → 人审批发布 → 带外修改补记 → facts 校验 → 重启恢复,末尾还会打印会话日志的权威与投影。
Agent 怎样把意图翻译成规则:给定意图、受约束生成
这一讲我们换个主角:让 Agent 来写。你只给它一句话:“阻止所有访问 /admin 的探测请求”,它就回你一条规则:
复制代码 1{
2"name": "block admin probe",
| 3 | "when": {"field":"path","op":"starts_with","value":"/admin"}, |
|---|---|
| 4 | "action":"deny" |
| 5 | } |
这条规则和第 18 讲你手写的规则是同一套结构,name/when/action 都在。区别只在写的人从你换成了模型:它读取你那句自然语言的意图,然后把它翻译成结构化规则。
办,比如拼错字段名、漏字段、自创算子,所以还要“受约束生成”。真正把关的是代码校验,它用契约约束模型的产出:isValidRuleWhen 就是那道校验:
复制代码
| 1 | exportfunctionisValidRuleWhen(when:unknown):boolean{ |
|---|---|
| 2 | if(typeofwhen !=='object'|| when ===null)returnfalse |
| 3 | constw = whenasRecord<string,unknown> |
| 4 | if(typeofw.field!=='string'|| !(FIELDSasreadonlystring[]).includes(w.fi |
| 5 | if(typeofw.op!=='string'|| !(OPSasreadonlystring[]).includes(w.op))ret |
| 6 | if(typeofw.value!=='string'|| w.value.length===0)returnfalse |
| 7 | returntrue |
| 8 | }</string,unknown> |
field 只能取 path/ip/method/ua/body 中的一个,op 只能取 eq/starts_with/contains/ends_with 中的一个,value 必须是非空字符串,模型只
能在安全边界里填空,吐出来的规则一定合法,不合法的当场被拒。
规则是带状态的,分候选 candidate、生效 active、驳回 rejected 三种,规则生成后且成功通过校验的即为候选规则。
人怎样掌握变更的决定权:审批闸、自主级别与 /firewall 命令
这条候选能直接上线吗?本讲最关键的一条产品决定是:人始终在 Agent 之上。Agent 能起草、能建议,但中间隔着一道闸,开多大由人说了算,自主级别是人设的,Agent 自己提不了
级。
落到机制上,有三样东西:
- 审批闸,装在流水线前两站,一道按级别拦写操作、一道用白名单限定工具范围;
- 自主级别,决定这道闸开多大;