AI编程助手行为约束实践:从规则到脚本的自动化演进
1. 项目缘起与核心价值
去年年中,当AI编程助手开始从简单的代码补全向更复杂的“代理”模式演进时,我像很多开发者一样,一头扎进了Cursor的怀抱。它当时集成的Claude Code模型,配合其独特的“Agent”模式,确实让人眼前一亮——你不再仅仅是和它一问一答,而是可以给它设定一个目标,比如“重构这个模块”或“修复这个测试”,然后看着它自己打开文件、分析、修改、甚至运行测试。这种体验,仿佛身边多了一个不知疲倦的初级工程师。然而,兴奋劲没过多久,我就遇到了一个普遍且棘手的问题:这个“代理”太有主见了,或者说,太“放飞自我”了。
我让它优化一个函数,它可能把整个类的结构都改了;我让它修复一个空指针异常,它可能引入了一堆不相关的依赖。它的每一次“自主行动”都像一次冒险,结果难以预测,代码评审的工作量不降反增。这让我意识到,要让AI代理真正成为得力的助手,而不是一个需要被时刻盯防的“熊孩子”,就必须给它立规矩。这就是agent-rules这个项目诞生的背景。它不是什么复杂的框架,而是一套我在实践中总结、提炼出来的“规则集”,专门用于约束和引导像Cursor Agent这类工具的“行为”,确保它的产出是可预测、可审查、且符合团队规范的。
简单来说,agent-rules解决的核心痛点是:在赋予AI代理自主权的同时,如何防止它“好心办坏事”或“过度发挥”,从而将AI的自动化能力安全、可控地集成到真实的生产和开发流程中。它适合所有正在或打算深度使用Cursor、Claude Code、乃至其他具备类似“代理”能力的LLM工具的开发者、技术负责人和团队。无论你是想提升个人开发效率,还是为团队制定AI协作规范,这里面的经验和“规矩”都能提供直接的参考。
2. 规则集的设计哲学与架构思路
设计一套给AI用的规则,和给人写代码规范有相似之处,但逻辑截然不同。人的规则可以理解“精神”,比如“写出可读的代码”;但AI需要的是明确、无歧义、可被其文本处理逻辑直接匹配和执行的指令。我的设计哲学基于以下三个核心原则:
2.1 原则一:指令必须原子化与场景化
你不能对AI说“请写出健壮的代码”。这太模糊了。你必须拆解:在什么场景下(例如,处理用户输入),什么是“健壮”(例如,进行非空校验、类型检查、长度限制)。因此,agent-rules中的每一条规则都绑定一个具体的开发场景或任务类型。
例如,针对“创建新的API端点”这个场景,规则集里会包含:
- 文件结构规则:必须在
src/api/v1/目录下创建。 - 命名规则:文件名为
[resource]_controller.py,类名为[Resource]Controller。 - 导入规则:必须从
core.schemas和core.database导入基类和会话。 - 方法规则:必须包含
GET(列表/详情) 和POST方法的最小实现模板。 - 文档规则:必须使用特定的
apidoc格式注释。
这样,当AI代理接到“创建用户管理端点”的任务时,它拿到的不是模糊的创意要求,而是一份可以逐步勾选的、明确的施工图纸。
2.2 原则二:规则应具备强制性与可验证性
规则不能是建议,而应是强制性的约束。这通过两种方式实现:
- 前置约束:在给AI的提示词(Prompt)中直接写入“你必须遵守以下规则:...”,利用LLM本身的指令遵循(Instruction Following)能力。
- 后置验证:规则本身描述的结果应该是可被自动化工具(如linter、测试、脚本)快速验证的。例如,“所有数据库查询必须使用参数化查询”这条规则,可以通过一个简单的代码扫描脚本来检查是否存在字符串拼接的SQL。
在我的实践中,我会将关键规则同时用于前置提示和后置验证,形成一个闭环。AI在过程中被约束,而最终的产出物又能被快速检查,确保规则没有被无意或有意地绕过。
2.3 原则三:规则需分层与可扩展
不是所有规则都同等重要。我将其分为三个层级:
- L1 安全与正确性规则:涉及安全、数据完整性、系统稳定性的规则。例如:“禁止执行未经审查的外部脚本”、“所有金额计算必须使用Decimal类型”。这些是红线,绝对不允许违反。
- L2 架构与一致性规则:涉及项目结构、设计模式、公共约定的规则。例如:“服务层类必须继承自
BaseService”、“DTO命名必须以Request/Response结尾”。这些保证了项目长期的可维护性。 - L3 风格与质量规则:代码格式、命名风格、注释要求等。例如:“函数长度不超过50行”、“使用Black格式化代码”。这些可以通过工具自动修复,重要性相对较低,但能提升协作效率。
agent-rules的架构就是基于这些原则,以YAML或JSON等结构化格式组织,每个规则包含id(唯一标识)、scope(适用范围,如python/api)、description(描述)、constraint(给AI的约束文本)和verification(验证方法或脚本片段)。这种结构化的设计,使得规则集本身也易于被其他自动化工具管理和应用。
3. 核心规则详解与实操配置
下面,我挑选几类最具代表性的规则,拆解其设计细节和如何在Cursor等工具中实际配置。你可以把这些看作是一个可直接复用的“规则包”。
3.1 代码修改类任务的“黄金规则”
这是最常用也最容易出问题的场景。AI代理经常过于“积极”地重构它认为需要改进的代码。
规则CR-01:变更范围隔离描述:任何代码修改必须严格局限在指定的函数、方法或类内,除非任务明确要求分析模块间影响。给AI的约束文本:“你本次的修改范围仅限于文件
[file_path]中的[function_name]函数。禁止修改此函数之外的任何代码,包括其所属类的其他方法、导入语句、文件顶部的注释等。如果你的修改方案需要变动外部代码,请先停止,并向我说明原因,请求授权。”实操心得:这条规则极大地减少了“惊吓”。我会在给Cursor Agent的任务描述里,把文件路径和函数名用反引号明确标出,并把这条约束放在提示词的最前面。实测下来,它能将AI的“扩散式修改”概率降低80%以上。
3.2 数据库与API操作的安全规则
涉及数据持久化和对外接口,安全是重中之重。
规则SEC-01:SQL注入防护描述:所有数据库查询必须使用参数化查询或ORM提供的方法,绝对禁止使用字符串拼接。给AI的约束文本:“当你需要编写数据库查询代码时,必须使用SQLAlchemy的
session.execute(text(“SELECT * FROM table WHERE id = :id”), {“id”: value})参数化形式,或使用ORM的查询方法(如session.query(User).filter_by(id=id))。在任何情况下,都不得将变量值通过f-string或+运算符直接拼接到SQL字符串中。请在你的回答中确认你使用了安全的方式。”验证脚本片段(Python):import ast import re def check_sql_string_interpolation(file_path): with open(file_path, ‘r’) as f: tree = ast.parse(f.read()) for node in ast.walk(tree): if isinstance(node, ast.JoinedStr): # f-string # 简单检查:如果f-string中包含‘SELECT‘, ‘INSERT‘等关键词,则报警告(需人工复核) if re.search(r‘\b(SELECT|INSERT|UPDATE|DELETE|FROM|WHERE)\b‘, ast.unparse(node), re.IGNORECASE): print(f“警告:文件 {file_path} 第 {node.lineno} 行可能存在SQL字符串拼接: {ast.unparse(node)[:100]}...”)
3.3 项目结构与命名的一致性规则
保持项目整洁,让任何团队成员(包括未来的你)都能快速理解。
规则ARCH-01:分层架构约束描述:严格遵守
controllers->services->repositories->models的调用链,禁止跨层或反向依赖。给AI的约束文本:“本项目采用严格的分层架构。controllers层负责处理HTTP请求和响应,只能调用services层的方法。services层包含业务逻辑,只能调用repositories层或其它services。repositories层负责数据访问,直接操作models。请确保你新增或修改的代码遵守此依赖方向。例如,controller中不应出现session.query(...)语句。”配置方法:对于Cursor,你可以在项目根目录创建一个.cursorrules文件(这是一个自定义的实践,并非Cursor原生功能,但可以通过提示词工程实现类似效果),在里面用注释的形式写明这些架构规则。然后,在每次开启Agent任务时,通过指令/rules(假设的自定义指令)或直接在对话中粘贴这些规则,让AI加载上下文。
3.4 与AI模型交互的“元规则”
这类规则用于管理AI代理自身的行为模式,非常关键。
规则META-01:分步确认与人工检查点描述:对于复杂任务,AI必须将解决方案分解为步骤,并在关键步骤前请求确认。给AI的约束文本:“在开始执行这个任务前,请先将其分解为不超过4个清晰的步骤,并向我概述你的计划。在涉及以下操作前,必须暂停并等待我的明确‘批准’指令:1. 创建新的数据库表或修改现有表结构。2. 删除任何现有的文件或代码块。3. 安装新的第三方依赖包。4. 修改项目的核心配置文件(如
settings.py,package.json)。现在,请先给出你的步骤计划。”实操心得:这条规则把“自动驾驶”模式变成了“领航员”模式。AI先给出路线图,你在关键路口握着方向盘。这虽然增加了一点交互成本,但完全避免了AI一头扎进你不想让它改的领域所带来的灾难性后果。在Cursor中,你可以把这条规则保存为一个代码片段或笔记,每次启动复杂任务前先发给它。
4. 规则集的实施、集成与迭代流程
有了规则,如何让它真正用起来,而不是躺在文档里睡大觉?我摸索出了一套从个人到团队的落地流程。
4.1 个人工作流集成
对于个人开发者,轻量级集成是关键。我的做法是结合Cursor的自定义指令(Custom Instructions)和简单的Shell脚本。
- 初始化规则库:在项目根目录创建
docs/agent_rules.md文件,用Markdown表格清晰分类列出所有规则(L1, L2, L3)。 - 配置Cursor全局指令:在Cursor的设置中,找到Custom Instructions(或类似功能,不同版本位置可能不同)。在“关于我/我的项目”部分,插入以下内容:
我的项目遵循一套严格的开发规则(Agent Rules),旨在保证代码安全、一致性和可维护性。在开始任何编码、重构或分析任务前,请务必首先阅读并理解项目根目录下 `docs/agent_rules.md` 文件中的全部内容。你的所有输出必须严格遵守这些规则,尤其是L1和L2级别的规则。如果任务要求与规则冲突,请向我指出冲突点并询问处理方式。 - 任务级提示词模板:对于特定类型的任务,我准备了更具体的提示词模板。例如,创建新API的模板:
任务:创建关于[资源名]的RESTful API端点,包含列表、详情、创建功能。 约束:请严格遵循 `docs/agent_rules.md` 中“场景:创建新API端点”章节的所有规则(规则ID: API-01至API-05)。 请先输出你将遵守的规则清单和实现步骤概要,经我确认后再开始编写代码。 - 后置验证脚本:编写一个简单的Python脚本
scripts/verify_rules.py,利用正则表达式或AST(抽象语法树)对SEC-01(SQL注入)等关键规则进行快速扫描。在提交代码前运行一下。
4.2 团队协作与知识共享
当在团队中推广时,重点在于降低采纳门槛和建立共识。
- 规则库作为活文档:将
agent-rules仓库(或项目内的规则文档)作为团队的技术规范之一。利用Git的版本控制来管理规则的变更,每次修改都需要提交Pull Request并经过团队成员评审。 - 开发环境标准化:在团队的项目模板(Cookiecutter或自定义脚手架)中内置
.cursorrules文件和验证脚本。新项目一经创建,规则就自动就位。 - Code Review清单:在团队的Pull Request模板中,增加一个“AI生成代码检查”部分,列出几条最重要的L1规则作为必查项。例如:
- [ ] 确认无SQL字符串拼接。
- [ ] 确认本次修改未超出指定范围(链接到相关Issue)。
- [ ] 确认新增API符合分层架构。
- 定期规则评审会:每月花15-30分钟,回顾规则的有效性。哪些规则被频繁违反?哪些规则已经过时?是否有新的“AI迷惑行为”需要立规矩?让规则集随着项目和AI工具的能力共同进化。
4.3 规则的迭代与反模式
规则不是一成不变的。在实践过程中,我总结出几个需要避免的“反模式”:
- 规则过细,扼杀创造性:如果你把“函数必须用动宾短语命名”这种风格细节也作为L1规则强制要求,AI会变得束手束脚,产出僵化。应对:将L3规则定位为“建议”,或通过Pre-commit Hook(如
black,isort)在提交时自动格式化,而不是让AI在创作时分心。 - 规则冲突,让AI困惑:如果规则A说“所有错误必须被日志记录”,规则B说“控制器层代码应保持简洁,不超过50行”,AI在处理错误日志时可能陷入两难。应对:建立规则的优先级和例外机制。在规则文档中明确:“当L1规则与L2/L3规则冲突时,优先满足L1规则。若L2规则间冲突,请向人类请求澄清。”
- “纸面规则”,无法验证:制定了一条“代码必须高性能”的规则,但无法在AI生成时或生成后有效评估。应对:要么将规则具体化为可衡量的指标(如“时间复杂度不应超过O(n log n)”),要么将其降级为“设计原则”而非“代理规则”,在人工评审时考量。
5. 从Rules到Scripts:自动化能力的演进
随着使用深入,我发现仅仅用自然语言规则去约束AI,效率仍有瓶颈。AI可能会“理解”规则,但在执行复杂、多步骤的任务时,依然可能出错或需要大量人工交互。于是,我的工作重心从制定静态的agent-rules,转向了开发动态的agent-scripts(即我新项目的工作)。
5.1 Rules的局限性
规则本质上是“禁止性”或“描述性”的,它告诉AI“不要做什么”或“应该做成什么样”。但对于“如何一步步做到”这个动态过程,控制力较弱。例如,规则可以要求“最终生成的API需要包含Swagger文档”,但无法精确控制AI先写代码、再写测试、最后生成文档的顺序和方式。这个过程仍然依赖AI自身的“规划”能力,而这是当前LLMs的薄弱环节。
5.2 Scripts的设计理念
agent-scripts的核心思想是:将复杂任务分解为一系列原子化的、可预测的步骤,并用脚本(或结构化的指令集)来驱动AI按顺序执行,每一步的输入和输出都被严格定义。
举个例子,以前的任务是:“在用户模块添加一个根据邮箱查找用户的服务方法”。现在,这个任务被一个脚本定义:
- 步骤1:分析- 输入:
UserService现有代码。输出:确认方法签名位置和依赖。 - 步骤2:实现- 输入:方法签名、规则约束(SEC-01等)。输出:
find_by_email方法实现代码。 - 步骤3:测试- 输入:新方法代码、测试文件模板。输出:对应的单元测试代码。
- 步骤4:集成- 输入:所有生成代码。输出:在
__init__.py中导出新方法(如果需要)的修改建议。
每个步骤都是一个独立的、上下文清晰的子任务,AI只需要专注于当前这一步。脚本引擎(可以是一个简单的Python脚本,或者利用Cursor的自动化特性)负责串联这些步骤,并将上一步的输出作为下一步的输入。这样,整个流程就变得像流水线一样可靠。
5.3 一个简单的脚本实例
假设我们有一个用来自动创建标准化CRUD接口的脚本。它不是一个可执行程序,而是一个给AI的“超级提示词”模板。
# script: generate_crud_api.yaml name: “生成标准CRUD API” target: “FastAPI项目” steps: - step: 1 action: “collect_info” prompt: | 请为我创建名为 `{resource}` 的资源的完整CRUD API。首先,请向我询问并确认以下信息: 1. 资源的主要属性(字段名和类型,例如:id: int, name: str, email: str)。 2. 数据库表名(如果与资源名不同)。 3. 希望API放置在哪个模块下(例如:`app/api/v1`)。 请逐个提问,在我回答完一个问题后再问下一个。 output: 一个收集好的信息字典。 - step: 2 action: “generate_pydantic_schemas” prompt: | 基于上一步收集的信息,创建Pydantic模型(Schemas)。 规则: 1. 创建 `{Resource}Create`、`{Resource}Update`、`{Resource}InDB` 三个Schema。 2. 所有字段使用Python类型提示。 3. `{Resource}Create` 和 `{Resource}Update` 中,id字段应为Optional,且默认None。 请只输出代码块,不要解释。 input: “step1.output” output: “schemas_code” - step: 3 action: “generate_crud_service” prompt: | 基于Schemas和资源名,生成一个CRUD服务类 `{Resource}Service`。 规则: 1. 类必须继承自 `BaseService[Model, CreateSchema, UpdateSchema]`。 2. 必须包含 `get`, `get_multi`, `create`, `update`, `delete` 方法的最小实现。 3. 所有数据库操作必须通过 `BaseRepository` 进行。 请只输出代码块。 input: [“step1.output”, “step2.output”] output: “service_code” # ... 后续步骤:生成Controller、路由、单元测试等在实际操作中,我会在Cursor中手动启动这个“脚本”,即按照这个YAML结构,一步步给AI发送提示词,并粘贴上一步的输出。未来,这完全可以由一个外部的自动化工具来驱动Cursor的API完成。
5.4 Rules与Scripts的关系
你可以将agent-rules看作是交通法规(限速、禁止逆行),而agent-scripts则是具体的导航路线和驾驶操作指南(前方300米右转,进入辅路)。规则确保了行为的安全与合规,是底线;脚本则提供了高效、可靠的达成目标的路径,是效率工具。二者结合,才能让AI代理在正确的道路上安全、快速地行驶。
6. 常见问题与实战排坑记录
在实际推行AI代理规则的过程中,我遇到了不少坑。这里记录一些典型问题和我的解决方案,希望能帮你绕开这些弯路。
6.1 AI“忘记”或“忽略”规则怎么办?
这是最常见的问题。你明明在提示词开头写了规则,AI却在输出时违反了。
- 原因分析:LLM的上下文窗口有注意力限制。如果提示词过长,或者任务描述过于复杂,后面的规则可能会被“稀释”。此外,如果规则表述模糊,AI可能无法准确理解。
- 解决方案:
- 规则前置与精简:把最重要的L1规则放在系统提示词(如Cursor的Custom Instructions)或用户消息的最开头,并用加粗或“规则:”这样的前缀强调。规则描述务必简洁、无歧义。
- 分步激活规则:不要一次性抛出所有规则。对于多步骤任务,在每一步开始前,重申与该步骤最相关的1-3条核心规则。例如,在AI要写数据库代码前,再次强调“记住,使用参数化查询(规则SEC-01)”。
- 要求复述与确认:在给出复杂任务后,追加一句:“请先复述你将遵循的核心规则,以确保你已理解。”这能强制AI“思考”一遍规则,提高遵循率。
6.2 规则与任务目标发生冲突时,AI如何处理?
有时,AI会死板地遵守某条规则,导致任务无法完成。例如,规则要求“函数不超过30行”,但一个复杂的算法逻辑确实需要35行。
- 解决方案:在规则体系中建立例外沟通机制。在给AI的指令中加入:“如果你认为严格遵守某条规则将导致无法实现任务核心目标,或产生更糟糕的代码,请明确指出冲突的规则ID,并提出你的修改建议及理由,等待我的决策。” 这赋予了AI“申诉”的权利,将决策权交回给人类。
6.3 如何验证AI生成的代码真的遵守了规则?
人眼逐行检查低效且容易遗漏。
- 解决方案:投资编写自动化验证脚本。从最简单的开始:
- 正则表达式扫描:针对“禁止
print调试语句”、“必须使用logging”等规则非常有效。 - AST分析:对于检查代码结构、导入依赖、函数复杂度等更复杂的规则必不可少。Python的
ast库、JavaScript的@babel/parser等工具可以帮你。 - 集成到CI/CD:将关键规则的验证脚本设置为Git预提交钩子(pre-commit hook)或CI流水线中的一个环节。任何违反L1规则的代码都无法合并,从流程上保障安全。
- 正则表达式扫描:针对“禁止
- 实操工具推荐:对于Python项目,
pre-commit框架是管理这类钩子的神器。你可以轻松集成black(格式化)、flake8(风格检查)和你自定义的规则检查脚本。
6.4 团队成员对规则接受度不高,觉得麻烦
推行任何新规范都会遇到阻力。
- 解决方案:
- 价值先行:通过一次“事故复盘”来展示规则的价值。例如,展示一段因没有参数化查询而导致SQL注入漏洞的AI生成代码,再对比遵守规则后的安全代码。
- 渐进式推行:不要一开始就抛出50条规则。先挑选3-5条最能立竿见影提升代码质量或减少Review工作量的核心规则(如“修改范围隔离”、“SQL安全”),让大家先用起来,看到好处。
- 工具赋能:尽可能让工具去承担检查规则的工作,而不是靠人脑记忆和人眼检查。当团队成员发现大部分规则检查是自动完成、无需他们额外费心时,抵触情绪会大大降低。
- 共同维护:鼓励团队成员提出修改或新增规则的建议。让规则集成为团队共同智慧的产物,而不是自上而下的命令。
6.5 面对不同的AI模型(Claude、GPT等),规则需要调整吗?
需要。不同模型的理解能力、指令遵循能力和“性格”有差异。
- 实战观察:Claude系列模型(如Claude Code)通常对长上下文和复杂指令的理解更稳定,更“守规矩”,适合执行严谨、多步骤的任务。GPT系列模型可能更具“创造性”,但有时也会更“叛逆”,需要更明确的约束。
- 调整策略:为不同的主力模型准备略微不同的规则表述。对于“叛逆”一点的模型,规则要写得更绝对、更不容置疑(使用“必须”、“禁止”、“绝对不可以”等强语气词)。同时,可以准备一个“规则兼容层”,即一套核心的、所有模型都必须遵守的规则(L1),和一套可选的、针对模型特性调整的补充规则。
7. 个人体会与未来展望
回顾从杂乱无章地使用AI编码,到系统化地制定agent-rules,再到探索agent-scripts的自动化,这个过程让我深刻认识到,将AI融入开发工作流,不是一个简单的工具替换,而是一次工作范式的升级。它要求我们从“如何写代码”转向“如何设计任务、制定规则、并验证结果”。
最大的体会是:信任源于可控,效率生于规范。早期对AI的恐惧和不信任,很大程度上源于其输出的不可预测性。而一套好的规则集,就像给一匹千里马套上了缰绳和鞍具,你不再担心它狂奔乱跑,而是可以驾驭它去往你想去的地方。规则越清晰,AI的行为就越可预测,你才敢把更重要的任务交给它。
目前,agent-scripts的方向让我更加兴奋。它意味着我们可以将常见的开发模式(如搭建CRUD脚手架、实现特定设计模式、进行依赖升级)封装成可重复执行的“剧本”。未来,我设想能有一个轻量级的“脚本运行器”,它可以读取一个YAML格式的脚本定义,然后自动与Cursor、Claude等工具的API交互,一步步驱动AI完成从需求分析到代码生成、测试乃至提交的全过程。这将把开发者的角色进一步推向“架构师”和“质检员”,专注于更高层次的设计和决策。
当然,这条路没有终点。AI模型在快速进化,我们的方法和工具也需要持续迭代。但无论如何,从制定几条简单的规则开始,有意识地去管理和引导你的AI助手,这绝对是当前投入回报比最高的实践。它不仅能立刻提升你当下的开发体验和代码质量,更是在为未来更高程度的人机协同打下坚实的基础。不妨就从为你当前的项目定义前三条最重要的“L1安全规则”开始吧。
