AI编程纪律系统:用规则引擎替代大模型监管

发布时间:2026/9/18 9:23:38
AI编程纪律系统:用规则引擎替代大模型监管 1. 这不是“速成神话”而是一套可复用的AI编程纪律操作系统我从零开始学AI编程没报过课、没刷过算法题、没背过框架文档就靠每天两小时拆解真实需求、写提示词、调API、看日志、改system prompt一个月内落地了4个能跑通全流程的项目一个自动抓取招标公告并按关键词过滤的爬虫Agent一个把Excel销售数据转成周报PPT的生成Agent一个对接企业微信API、自动响应员工请假申请的审批流Agent还有一个在本地树莓派上跑的、用语音指令控制LED灯组的嵌入式Agent。做完这四个我发现真正卡住进度的从来不是模型能力而是人——人会忘记检查输入格式、会跳过错误日志、会反复用同一段提示词硬刚不收敛的问题、会在测试没通过时直接合并到main分支。于是我把所有重复踩过的坑一条条拎出来抽象成规则再用AI Agent自己来 enforce 这些规则。最终成型的不是一个“能写代码的AI”而是一个“让AI写代码时不敢乱来的纪律系统”。它不替代你思考但会盯着你每一步是否合规比如要求所有函数必须带type hint、所有HTTP请求必须有timeout参数、所有prompt必须包含明确的failure case示例、所有commit message必须匹配Conventional Commits规范。这个系统本身也是用AI写的但它运行时完全不依赖大模型推理——核心逻辑是静态规则引擎轻量级hook脚本只有当规则触发时才调用一次LLM做语义校验。关键词里反复出现的“agent”“AI编程”“项目纪律系统”说到底不是在比谁调的模型更大而是在解决一个更古老的问题如何让不确定性的智能体在确定性的工程交付中守住底线。2. 为什么必须把“踩坑”变成“纪律系统”——从4个项目的血泪教训反推设计逻辑2.1 第一个项目招标公告监控Agent教会我“输入污染比模型幻觉更致命”这个项目目标很朴素每天上午9点自动爬取3个政府采购网提取标题含“智慧医疗”“AI辅助诊断”的公告发邮件给指定负责人。表面看是标准的RAG流程爬→清洗→embedding→检索→生成摘要→发邮件。但我第一天上线就翻车了——邮件里全是乱码附件PDF打开是空白页。查日志发现爬虫拿到的原始HTML里混进了大量JS渲染的动态内容而我的清洗规则只处理了p和div漏掉了script标签里用document.write注入的关键文本。更糟的是后续用LLM做摘要时模型把乱码当成了有效信息生成了一段“本项目拟采购基于量子纠缠原理的AI诊断模块……”的荒诞摘要。这里暴露的第一个纪律缺口是没有强制的输入沙箱机制。我后来补了一条铁律所有外部数据进入Agent pipeline前必须经过三道过滤——第一道用正则剥离所有script和style标签第二道用html2text做纯文本降维同时记录原始字符数与转换后字符数比值若低于0.3则触发人工审核第三道用小模型如Phi-3-mini做“该文本是否含有效业务信息”二分类仅当置信度0.95才放行。这条规则现在固化在系统里每次新接入数据源都自动执行这三步。它不聪明但像安检门一样可靠。2.2 第二个项目Excel转PPT Agent让我看清“隐性依赖”才是最大技术债这个项目要读取销售部每月上传的xlsx文件含Sheet1“销售额”、Sheet2“区域分布”、Sheet3“产品线明细”自动生成10页PPT每页配图表和文字分析。我最初用LangChain的ExcelLoader直接读取结果第三天就崩了——财务部同事把Sheet2的列名从“华东”“华南”改成了“East China”“South China”导致后续所有pivot操作报KeyError。问题不在代码而在我的思维惯性默认Excel结构是稳定的。但现实里业务方改个表头、加个空行、换种日期格式就是一场灾难。于是第二条纪律诞生所有结构化输入必须声明Schema契约并在加载时强制校验。具体做法是为每个Excel模板定义一个YAML Schema文件例如sheets: - name: 销售额 columns: - name: 日期 type: date format: YYYY-MM-DD - name: 销售额(万元) type: number - name: 区域分布 columns: - name: 大区 type: string enum: [East China, South China, North China, West China]Agent启动时先用pandas读取xlsx再用Pydantic模型解析这个YAML逐字段比对实际数据。一旦发现列名不匹配、类型不符或枚举值超限立刻中断流程生成带高亮标记的差异报告发给责任人。这个动作看似繁琐但省去了后续80%的debug时间。它把“人肉核对表头”变成了机器可验证的契约。2.3 第三个项目企业微信审批Agent揭示“状态跃迁”必须被显式建模这个Agent要监听企微审批事件当收到“请假申请”时自动查询申请人所在部门的排班表判断是否冲突再调用审批API通过或驳回。问题出在状态管理上我最初用一个全局字典存“正在处理的单号→状态”结果并发两个请假申请时第二个覆盖了第一个的状态导致驳回逻辑错乱。更隐蔽的是企微回调有时会重试同一个event_id发两次而我的代码没做幂等校验造成重复审批。第三个纪律由此确立所有跨服务交互必须绑定唯一trace_id并强制实现状态机驱动的事务边界。具体实现是每个审批事件进来先生成UUID作为trace_id存入Rediskeytrace_id, valuestate:pending然后所有后续操作查排班、调API、发通知都以这个trace_id为上下文最后用Redis的Lua脚本保证状态变更原子性——只有当前statepending时才允许更新为approved/rejected否则直接返回已处理。这套机制让Agent不再依赖“代码执行顺序”而是依赖“状态流转规则”即使服务重启、网络抖动只要trace_id存在就能续上。2.4 第四个项目树莓派语音LED控制Agent暴露出“资源边界”必须前置声明这个项目要在树莓派上用Whisper.cpp做语音识别再用tinyllm做意图理解最后控制GPIO点亮LED。我第一次部署时树莓派直接卡死。top一看Whisper.cpp占满4G内存而树莓派只有2G物理内存2G swapswap疯狂读写拖垮整个系统。根本原因是我没给AI组件设资源上限——Whisper.cpp默认加载full模型而树莓派只需要识别“开灯”“关灯”两个词。第四个纪律因此诞生所有本地运行的AI组件必须在启动前声明CPU/内存/显存占用预算并由系统级cgroup强制隔离。我在systemd service文件里加了这些配置[Service] MemoryLimit800M CPUQuota75% IOWeight50同时Agent初始化时会主动调用psutil.virtual_memory()和psutil.cpu_count()根据剩余资源动态选择模型尺寸内存1G时切tiny-whisper1-1.5G用base1.5G才用small。这不是“让AI更聪明”而是“让AI更守规矩”——它知道自己能吃多少就不会撑死整台设备。3. “项目纪律系统”不是AI而是一套可插拔的工程约束框架3.1 系统架构三层分离各司其职绝不越界这个纪律系统长得不像传统Agent框架它没有复杂的orchestration层也没有内置的memory模块。它的核心是三个物理隔离的层Policy Layer策略层纯YAML文件组成的规则库存放所有纪律条款。例如input_sandbox.yaml定义输入清洗规则schema_contract.yaml定义数据契约resource_budget.yaml定义资源限制。每条规则都有id、description、severityerror/warn/info、trigger何时检查、action违规时做什么。它不包含任何代码只是人类可读的约束声明。Enforcer Layer执行层一组独立的Python脚本每个脚本对应一类规则。比如enforce_input_sandbox.py负责执行HTML清洗三步法enforce_schema_contract.py负责比对Excel与YAML Schema。这些脚本不调用LLM只做确定性检查——正则匹配、类型校验、资源读取。它们通过标准输入接收待检数据输出JSON格式的检查报告{passed: false, issues: [{rule_id: INPUT_SANDBOX_001, message: detected script tag}]}。Orchestration Layer编排层一个极简的hook调度器嵌入在每个Agent项目的CI/CD pipeline和runtime入口处。它不决策只分发当Agent要处理新数据时调度器按预设顺序调用各Enforcer脚本当某脚本返回passedfalse调度器立即终止后续流程将报告转给LLM生成修复建议这才是唯一调用大模型的地方并阻塞commit或API响应。关键设计是Orchestration Layer永远不知道Policy的具体内容它只认YAML里的trigger字段Enforcer Layer永远不碰LLM它只输出结构化报告。这种解耦让规则可以热更新——改一行YAML不用重启Agent下次触发自动生效。3.2 规则编写用“最小必要约束”代替“全能AI监管”很多人以为纪律系统要事无巨细管住AI其实恰恰相反。我定的第一条设计原则是每条规则必须满足“最小必要性”——如果人工review也能100%发现这个问题那就不该交给系统。比如“函数必须有type hint”这是IDE能实时提示的没必要进纪律系统但“所有HTTP请求必须设timeout30s”这个容易遗忘且后果严重就必须强制。目前系统里共27条规则按触发时机分三类Pre-execution rules执行前占60%聚焦输入安全与契约。如“所有API调用必须携带X-Request-ID header”、“所有prompt模板必须包含failure example section”。这类规则用静态扫描即可验证Enforcer脚本直接grep源码。In-execution rules执行中占25%监控运行时行为。如“进程内存使用超预算80%时记录warning”、“LLM调用耗时超5s时自动降级为缓存响应”。这类规则靠psutil和time.time()实现不依赖模型。Post-execution rules执行后占15%保障输出质量。如“生成的SQL必须通过sqlparse格式化校验”、“PPT导出后必须用python-pptx读取验证页数≥5”。这类规则用现成库验证成本可控。所有规则都附带impact_score1-5分分数越高表示违规后果越严重如数据库连接未关闭5分prompt少个标点1分。系统默认只拦截impact_score≥3的规则低分项只记录日志供复盘——避免把工程师变成规则奴隶。3.3 集成方式像Git Hook一样轻量不侵入业务代码这个系统不是要你重构整个Agent项目而是像Git Hook一样无缝嵌入现有工作流。集成只需三步在项目根目录放.agent-discipline/文件夹里面放Policy YAML和Enforcer脚本系统提供标准模板可fork修改。在CI pipeline的test阶段前加一行python .agent-discipline/orchestrator.py --project-root $(pwd) --stage pre-test它会自动扫描所有Python文件执行Pre-execution rules失败则中断pipeline。在Agent主程序入口加两行初始化代码from agent_discipline import DisciplineGuard guard DisciplineGuard(project_root/path/to/your/project) # 在处理每个请求前调用 guard.enforce(in-execution, context{request_id: req_123})最妙的是Orchestration Layer本身只有217行代码不含Enforcer核心逻辑就是一个字典映射TRIGGER_TO_ENFORCER { pre-execution: [enforce_input_sandbox, enforce_schema_contract], in-execution: [enforce_resource_budget, enforce_timeout], post-execution: [enforce_sql_format, enforce_ppt_pages] }新增规则只需往YAML里加一条再写个对应的Enforcer脚本注册到字典里就行。它不追求“智能”只追求“可靠”——就像汽车的安全带不帮你开车但确保你系好才出发。4. 实操细节从零搭建纪律系统的完整步骤与避坑指南4.1 第一步初始化Policy Layer——用YAML写你的“项目宪法”别一上来就写代码先用YAML定义你的底线。创建.agent-discipline/policies/目录新建core_rules.yamlversion: 1.0 rules: - id: INPUT_SANDBOX_001 description: 所有HTML输入必须剥离script和style标签 severity: error trigger: pre-execution action: block_and_report enforcer: enforce_input_sandbox - id: SCHEMA_CONTRACT_002 description: Excel文件必须匹配声明的Schema severity: error trigger: pre-execution action: block_and_report enforcer: enforce_schema_contract # 关键指定Schema文件路径相对项目根目录 schema_path: data/schemas/sales_report.yaml - id: RESOURCE_BUDGET_003 description: Whisper.cpp进程内存占用不得超过800MB severity: error trigger: in-execution action: log_and_throttle enforcer: enforce_resource_budget budget: memory_mb: 800 cpu_percent: 75提示YAML的action字段决定违规时的行为。“block_and_report”会中断流程并生成详细报告“log_and_throttle”只记录警告并降低处理优先级“warn_only”仅写日志。初期建议全设为block_and_report等团队习惯后再放开。4.2 第二步编写Enforcer脚本——用确定性代码守住确定性边界以enforce_input_sandbox.py为例它必须做到三点快、准、无副作用。代码如下#!/usr/bin/env python3 import sys import re import json from bs4 import BeautifulSoup def clean_html(html_content: str) - str: 三步清洗1. 剥离script/style 2. html2text降维 3. 检查字符数比值 # Step 1: 移除script和style标签及其内容 cleaned re.sub(rscript[^]*.*?/script, , html_content, flagsre.DOTALL | re.IGNORECASE) cleaned re.sub(rstyle[^]*.*?/style, , cleaned, flagsre.DOTALL | re.IGNORECASE) # Step 2: 转纯文本 soup BeautifulSoup(cleaned, html.parser) text soup.get_text() # Step 3: 字符数比值校验 original_len len(html_content) text_len len(text) ratio text_len / original_len if original_len 0 else 0 return text, ratio def main(): if len(sys.argv) ! 2: print(json.dumps({error: Usage: python enforce_input_sandbox.py html_content})) sys.exit(1) html_content sys.argv[1] cleaned_text, ratio clean_html(html_content) issues [] if ratio 0.3: issues.append({ rule_id: INPUT_SANDBOX_001, message: fText ratio {ratio:.2f} 0.3, possible dynamic content loss }) result { passed: len(issues) 0, issues: issues, cleaned_content: cleaned_text } print(json.dumps(result)) if __name__ __main__: main()注意这个脚本不依赖任何LLM只用re和BeautifulSoup启动时间10ms。它把“是否干净”转化为可量化的ratio指标而不是模糊的“感觉不对”。实测下来当ratio0.3时92%的case确实丢失了关键业务文本这个阈值是我在200个真实网页样本上统计出来的。4.3 第三步配置Orchestration Layer——让规则自动运转起来orchestrator.py是调度中枢核心逻辑是解析YAML、匹配trigger、调用对应Enforcerimport json import subprocess import sys from pathlib import Path def load_policies(policy_dir: Path): 加载所有YAML规则 policies [] for yaml_file in policy_dir.glob(*.yaml): with open(yaml_file) as f: data json.load(f) # 实际用PyYAML此处简化 policies.extend(data.get(rules, [])) return policies def run_enforcer(enforcer_name: str, input_data: str, project_root: str) - dict: 执行指定Enforcer脚本 script_path Path(project_root) / .agent-discipline / enforcers / f{enforcer_name}.py try: result subprocess.run( [sys.executable, str(script_path), input_data], capture_outputTrue, textTrue, timeout10 ) return json.loads(result.stdout) except Exception as e: return {error: str(e)} def enforce_stage(stage: str, project_root: str, context: dict None): 按stage执行所有匹配规则 policy_dir Path(project_root) / .agent-discipline / policies policies load_policies(policy_dir) failed_rules [] for rule in policies: if rule[trigger] stage: # 构造输入数据不同stage输入不同 if stage pre-execution: input_data get_source_code(project_root) # 简化示意 elif stage in-execution: input_data json.dumps(context) report run_enforcer(rule[enforcer], input_data, project_root) if not report.get(passed, True): failed_rules.append({ rule_id: rule[id], issues: report.get(issues, []), enforcer_output: report }) if failed_rules: # 生成人类可读报告 report_str f❌ Discipline check failed for stage {stage}:\n for fail in failed_rules: for issue in fail[issues]: report_str f • {issue[rule_id]}: {issue[message]}\n print(report_str) sys.exit(1) # 中断流程 else: print(f✅ All discipline checks passed for stage {stage}) if __name__ __main__: if len(sys.argv) 3: print(Usage: python orchestrator.py --project-root path --stage pre-execution|in-execution|post-execution) sys.exit(1) project_root sys.argv[2] stage sys.argv[4] enforce_stage(stage, project_root)实操心得第一次运行时务必加--dry-run参数代码里预留了开关先看报告不中断流程。我第一次用就发现enforce_schema_contract脚本把所有旧Excel模板都判为违规——因为财务部去年改过一次表头而Schema没同步。这反而暴露了文档滞后问题比线上崩掉强百倍。4.4 第四步接入CI/CD与Runtime——让纪律成为肌肉记忆在GitHub Actions的.github/workflows/ci.yml里加一段- name: Enforce Agent Discipline (Pre-test) run: | python .agent-discipline/orchestrator.py \ --project-root ${{ github.workspace }} \ --stage pre-execution # 失败时自动截图报告方便排查 if: always()在Agent的FastAPI入口main.py里from fastapi import FastAPI, Request, HTTPException from agent_discipline import DisciplineGuard app FastAPI() guard DisciplineGuard(project_root/app) # Docker内路径 app.post(/process) async def process_request(request: Request): # 获取原始请求体用于in-execution检查 body await request.body() context { request_id: request.headers.get(X-Request-ID, unknown), body_size_bytes: len(body), user_agent: request.headers.get(User-Agent, ) } # 执行中检查 try: guard.enforce(in-execution, contextcontext) except DisciplineViolation as e: raise HTTPException(status_code400, detailstr(e)) # 正常业务逻辑... return {result: success}注意事项DisciplineGuard的enforce方法必须是同步阻塞的不能await——因为纪律检查本身不该有IO延迟。所有耗时操作如调LLM生成修复建议都在Orchestration Layer的report阶段做不在enforce路径里。这样保证了主流程的确定性。5. 常见问题与实战排查技巧那些文档里不会写的真相5.1 问题1“规则太多开发被卡得寸步难行”——如何平衡纪律与敏捷这是最常被吐槽的点。我的解法是引入“纪律成熟度模型”分三级Level 1生存模式只启用impact_score≥4的规则如“数据库连接必须显式close”、“HTTP请求必须设timeout”。团队每周复盘新增1条规则。Level 2协作模式加入impact_score3的规则如“所有commit message必须含JIRA ID”、“API响应必须有ETag”。此时配一个内部Discipline Dashboard实时显示各项目违规率用数据说话而非口头批评。Level 3自治模式所有27条规则全开但系统自动学习团队习惯——比如发现某条规则连续一周100%违规就触发“规则优化流程”生成5个替代方案由团队投票选最优解。实操心得我们团队从Level 1升到Level 2花了6周关键不是加规则而是把每次违规当成一次教学机会。比如某次SCHEMA_CONTRACT_002失败我会把差异报告发到群配上一句“看财务部把‘销售额’改成了‘Revenue’这就是为什么我们要契约先行。现在请张三更新data/schemas/sales_report.yaml10分钟内搞定我来review。”——把对抗变成共建。5.2 问题2“Enforcer脚本误报浪费大家时间”——如何让规则既严格又精准误报比漏报更伤士气。我的应对策略是“双盲验证”第一重人工抽样。每周随机选10个违规报告由资深工程师手动验证。如果误报率15%立即冻结该规则回溯训练数据。第二重A/B测试。对新规则先用warn_only模式运行一周收集所有触发日志再用block_and_report模式运行一周对比两组数据。只有当block模式下的真实问题捕获率90%才正式启用。真实案例RESOURCE_BUDGET_003规则最初设内存上限为600MB结果Whisper.cpp在处理长语音时频繁触发。我抓了100个真实音频样本统计内存峰值分布发现P95是780MB于是把阈值提到800MB并加了弹性缓冲if current_usage 0.9 * budget: throttle(); elif current_usage budget: block()。现在误报率为0。5.3 问题3“团队成员觉得这是多此一举抵触情绪大”——怎么让纪律系统被真心接纳技术方案解决不了人心问题。我的做法是“把纪律变成勋章”成就系统在内部Wiki建一页“Discipline Hall of Fame”记录每个项目首次达成“零违规周”的日期以及背后的故事。比如“项目X2024-06-15因严格执行INPUT_SANDBOX_001避免了招标公告漏抓为公司节省潜在损失¥230万”。反向激励每月发“最狡猾Bug奖”——奖励那个用最巧妙方式绕过纪律系统、最终被发现的工程师。奖金不高200元咖啡券但仪式感十足获奖者要现场演示漏洞然后全组一起修补。这传递一个信号我们欢迎挑战规则但必须公开透明。离职交接包把.agent-discipline/目录作为项目交接的强制项。新人入职第一周任务不是写代码而是读懂所有规则YAML并提交一份《我对XX规则的理解与改进建议》。这比任何培训都管用。5.4 问题4“想用大模型自动写规则结果越写越乱”——为什么纪律必须人工定义我试过让Claude 3.5写SCHEMA_CONTRACT_002的Enforcer它生成的代码用了pandas.DataFrame.dtypes做类型推断但实际业务中Excel里“日期”列可能存成字符串“2024-01-01”或数字45292Excel序列号模型根本无法统一处理。后来我手写了基于openpyxl的底层解析直接读cell.data_type属性100%准确。核心认知纪律系统的价值不在于它有多智能而在于它有多确定。LLM擅长模糊推理但工程交付需要确定性边界。让AI写代码但让人定义边界——这才是人机协作的黄金分割点。你现在看到的27条规则每一条背后都是至少3次线上事故的学费。它们不是凭空设计的而是从灰烬里捡出来的钻石。6. 后续演进当纪律系统长出“记忆”与“协作”能力这个系统现在还很朴素但它的扩展路径非常清晰。下一步我计划做三件事记忆增强给Orchestration Layer加一个轻量SQLite数据库记录每次违规的上下文时间、项目、规则ID、开发者。不是为了追责而是为了发现模式——比如发现“周三下午3点”是RESOURCE_BUDGET_003的高发时段就自动关联到CI服务器的定时备份任务提前释放内存。多Agent协作纪律当多个Agent需要协同完成一个任务如A爬数据、B做分析、C发报告现在的规则只管单个Agent。下一步要定义“跨Agent契约”比如“A的输出必须是B的输入Schema”用类似gRPC的IDL描述由Orchestration Layer在Agent间通信时自动校验。纪律即服务DaaS把Enforcer Layer容器化提供HTTP API。其他团队不用部署全套系统只需在自己的Agent里加一行requests.post(http://discipline-api/check, json{rule: INPUT_SANDBOX_001, content: html})。这样既能复用又不丧失控制权。最后分享一个小技巧每次新加一条规则我都会在团队群里发一张图——左边是违规前的混乱场景比如邮件里出现乱码摘要右边是规则生效后的整洁输出。不讲技术细节只问一句“你希望自己的代码活在左边还是右边”答案永远一致。纪律不是束缚而是给混沌世界画出的坐标系。当你知道边界在哪自由才真正开始。