该文件定义了一个用于指导AI程序员(Engineer2)的复杂指令集(EXTRA_INSTRUCTION),它整合了基础角色指令(ROLE_INSTRUCTION)和一系列关于文件编辑、终端操作、项目创建、技术栈选择、代码编写与部署的详细规则和最佳实践。核心功能是为一个自主编程代理提供操作上下文、约束条件和执行流程的详细规范。
graph TD
A[开始: 接收用户需求] --> B{是否提供Issue链接?}
B -- 是 --> C[使用Browser工具导航至Issue页面]
B -- 否 --> D[检查当前路径下是否存在目标仓库]
D -- 不存在 --> E[下载仓库并导航至其路径]
D -- 存在 --> F[导航至仓库路径]
F --> G[进入项目主循环]
G --> H{根据需求制定计划?}
H -- 是 --> I[列出待编码文件,规划任务]
H -- 否 --> J[直接执行简单任务]
I --> K[循环处理每个文件/任务]
K --> L{使用哪种工具修改文件?}
L -- 大范围重写/多次编辑失败 --> M[使用Engineer2.write_new_code]
L -- 小范围精确编辑 --> N[使用Editor工具链]
N --> O[使用Editor.open_file打开文件]
O --> P[执行编辑命令(如edit_file_by_replace)]
P --> Q[验证更改,确保符合PEP8]
K --> R{是否为前端项目?}
R -- 是 --> S[使用指定模板(Vue/React)创建项目]
R -- 否 --> T[在`{project_name}_{timestamp}`文件夹中工作]
S --> U[复制模板,读取关键文件]
U --> V[重写src/和index.html文件]
V --> W[使用Tailwind CSS等指定技术栈]
K --> X[完成所有文件后]
X --> Y[构建项目(pnpm install && pnpm run build)]
Y --> Z[部署dist文件夹到公开环境]
Z --> AA[结束]
该文件不包含显式的类层次结构。它是一个配置/指令脚本,主要包含:
├── 全局常量 (EXTRA_INSTRUCTION, CURRENT_STATE, ENGINEER2_INSTRUCTION)
├── 全局函数 (无)
└── 从外部导入的常量 (REACT_TEMPLATE_PATH, VUE_TEMPLATE_PATH, ROLE_INSTRUCTION)一个包含详细操作指南和约束条件的多行字符串,用于扩展和定制AI工程师(Engineer2)的行为指令。
类型:str
一个格式化字符串模板,用于描述代码编辑器的当前状态,包括工作目录和打开的文件。
类型:str
AI工程师(Engineer2)的完整指令,由基础角色指令(ROLE_INSTRUCTION)和扩展指令(EXTRA_INSTRUCTION)拼接而成。
类型:str
定义代码编写AI系统角色的提示词,强调遵循设计、完整实现和代码质量。
类型:str
一个格式化字符串模板,用于在具体编写单个代码文件时,向AI提供用户需求、计划状态、文件路径和描述等上下文信息。
类型:str
定义了用于指导AI代理(如自主程序员)行为的多层级指令和系统提示词,包括核心角色指令、额外操作约束、代码编写规范以及当前状态模板。
管理项目模板(如React, Vue)的绝对路径,并通过time.time()动态生成时间戳,用于构建唯一的项目文件夹名称。
规定了代码生成(Engineer2.write_new_code)与文件编辑(Editor工具系列命令)的使用场景、优先级和最佳实践,例如何时重写整个文件、如何避免重复编辑导致的语法错误等。
定义了使用特定技术栈(Vite, Vue/React, MUI, Tailwind CSS)创建前端项目的标准化步骤,包括模板复制、文件读取、重写计划以及最终的构建和部署流程。
包含了一系列针对文件编辑、目录导航、命令使用频率的详细约束和错误预防措施,旨在确保AI代理操作的稳定性和代码质量。
- 指令字符串硬编码与格式化风险:
EXTRA_INSTRUCTION字符串通过.format()方法进行格式化,但字符串内部包含大量需要动态替换的占位符(如{{project_name}},{{workspace}},{{template_folder}}),这些占位符并未在.format()调用中被实际替换。这会导致运行时这些占位符保持原样,可能引发下游工具或代理的解析错误或逻辑混乱。 - 指令逻辑矛盾与歧义:
- 第11条与第11.1条存在潜在的逻辑冲突。第11条建议在一次响应中只执行第一个编辑操作,将后续操作推迟到下一轮;而第11.1条禁止在单个命令列表中使用多次
Editor.insert_content_at_line或Editor.edit_file_by_replace。虽然意图相似,但表述不够清晰,可能被误解为完全禁止在一次 交互 中进行多次编辑规划,而不仅仅是单次 命令列表。 - 第24条与第25条关于技术栈优先级的描述存在重叠和潜在的决策路径不清晰。第24条给出了一个优先级列表,而第25条又为特定技术栈(Vite, Vue/React, MUI, Tailwind CSS)规定了一套详细步骤。当条件满足时,代理应遵循哪一套规则?是优先应用第25条的详细步骤,还是先根据第24条判断优先级再决定?这增加了代理决策的复杂性。
- 第11条与第11.1条存在潜在的逻辑冲突。第11条建议在一次响应中只执行第一个编辑操作,将后续操作推迟到下一轮;而第11.1条禁止在单个命令列表中使用多次
- 时间戳静态化:
EXTRA_INSTRUCTION中的{timestamp}在字符串格式化时被固定为模块加载时刻的时间(int(time.time()))。这意味着所有后续使用该指令的会话都会共享同一个时间戳,与第14条要求的“每次生成唯一文件夹”的意图相悖,可能导致文件夹命名冲突。 - 路径引用潜在问题:
VUE_TEMPLATE_PATH和REACT_TEMPLATE_PATH被解析为绝对路径并格式化进指令。如果这些路径在系统间不一致或包含特殊字符,可能引发问题。且指令中关于模板路径不存在的处理(第29条“Just continue the work”)过于宽松,可能导致后续步骤因缺少模板而失败。 - 代码重复与维护性:
WRITE_CODE_PROMPT模板字符串虽然清晰,但如果需要调整输出格式或增加新的上下文变量,需要直接修改字符串,不利于维护和复用。
- 重构指令生成机制:
- 将
EXTRA_INSTRUCTION定义为一个模板字符串(例如使用string.Template或 Jinja2 模板),将真正的动态变量(如project_name,workspace,timestamp)留待每次任务执行时根据上下文注入。移除无效的.format()调用。 - 将
CURRENT_STATE的格式化整合到指令组装逻辑中,确保状态信息能正确反映实时环境。
- 将
- 澄清和简化操作指令:
- 合并并重写第11条和第11.1条,明确表达核心约束:“在一次行动响应中,至多规划一个文件编辑操作(使用
Editor.insert_content_at_line或Editor.edit_file_by_replace)。如果需要对同一文件进行多处修改,应将它们规划在连续的多个响应中依次执行。” - 重构第24条和第25条。建议将第25条作为第24条优先级中“Vite, React, MUI and Tailwind CSS”或“未指定”情况下的 具体实施细则。在指令中明确说明:“若根据优先级选定或默认使用 Vite/React/Vue 等技术栈,则必须遵循以下详细步骤(25.1-25.5)”。
- 合并并重写第11条和第11.1条,明确表达核心约束:“在一次行动响应中,至多规划一个文件编辑操作(使用
- 确保时间戳唯一性:移除
EXTRA_INSTRUCTION中静态的{timestamp}占位符。应在每次创建任务或代理初始化时,动态生成一个时间戳并注入到最终发送给代理的完整指令中。 - 增强路径安全性与错误处理:
- 在将模板路径注入指令前,增加路径存在性检查,并给出更明确的警告或备选方案,而不是简单地“继续工作”。
- 考虑对路径进行字符串转义,防止路径中的特殊字符破坏指令结构。
- 提升提示模板可维护性:将
WRITE_CODE_PROMPT等提示模板移出代码文件,放入独立的配置文件或模板文件中(如 YAML, JSON)。这样可以在不修改代码的情况下调整提示内容,也便于进行多语言支持或 A/B 测试。 - 引入配置类或工厂模式:考虑创建一个
InstructionConfig类或使用工厂函数来集中管理所有指令模板的加载、变量替换和组装。这可以提高代码的模块化程度和可测试性。
本代码模块的核心设计目标是构建一个用于指导AI代理(特别是“工程师”角色)进行自动化编程任务的指令系统。它通过整合角色基础指令、特定工具使用规范、项目操作流程以及代码编写原则,形成一个结构化的、可执行的行动指南。主要约束包括:必须与特定的工具集(如Editor, Terminal, Browser)兼容;指令必须清晰、无歧义,以避免AI代理产生循环错误或无效操作;必须支持多种前端技术栈(React/Vue)的初始化流程;必须强制遵守既定的系统设计或项目排期文档。
代码本身不包含运行时错误处理逻辑,因为它主要定义的是提示词(Prompt)字符串。其“错误处理”体现在对AI代理行为的预防性指导上:
- 操作失败重试与规避:明确指示代理观察前序操作结果,避免触发重复错误(如
avoid triggering repeated errors)。当编辑命令失败时,建议扩大代码修改范围或改用重写整个文件的方法(Engineer2.write_new_code)。 - 语法与格式错误预防:通过强调PEP8标准、缩进重要性以及在编辑后验证更改,来预防代码语法和格式错误。
- 流程异常处理:定义了当仓库不存在时的处理流程(下载并进入),以及当模板路径不存在时的应对策略(
Just continue the work),确保了主流程的鲁棒性。 - 工具使用异常预防:规定了工具使用的先决条件(如使用Editor编辑前必须先
open_file)和限制(如每轮响应中特定编辑命令只能使用一次),以防止工具调用层面的异常。
本模块定义了AI代理心智模型中的数据流和隐式状态机:
- 输入数据流:
- 静态配置:
REACT_TEMPLATE_PATH,VUE_TEMPLATE_PATH,用于模板路径解析。 - 动态上下文:通过
CURRENT_STATE模板注入current_directory和editor_open_file,反映工作环境实时状态。 - 任务参数:通过
WRITE_CODE_PROMPT模板注入user_requirement,plan_status,file_path等,提供具体编码任务上下文。
- 静态配置:
- 内部状态转换(代理行为逻辑):
- 初始状态:接收用户需求。若提供issue链接,则必须转换到“浏览issue”状态。
- 仓库就绪状态:检查并确保目标仓库存在于工作路径。若不存在,则转换到“下载仓库”子流程,完成后进入该仓库目录。此状态为后续所有操作的稳定态,代理不应离开此目录。
- 文件操作状态:围绕
Editor工具进行。状态包括:文件未打开->打开文件->读取/定位(goto_line)->编辑(insert/replace)->验证。指令明确禁止在单次响应中进行多个可能改变行号的编辑操作,这强制了状态的串行推进。 - 项目创建状态:当需要创建前端项目时,遵循一个严格的子状态机:
创建目录->复制模板->进入目录->读取模板文件->规划改写->执行改写->构建部署。 - 规划与执行状态:代理在“制定计划”和“执行任务”间切换。指令要求制定计划时列出所有文件,执行时一次只读写一个文件,并将同一文件上的多个操作合并,这定义了从宏观规划到微观执行的层次化状态转移。
- 输出数据流:最终输出是符合
WRITE_CODE_PROMPT格式要求的、完整的源代码文件内容。整个指令系统的目的是引导AI代理产生此输出。
- 外部依赖:
metagpt.const:依赖REACT_TEMPLATE_PATH和VUE_TEMPLATE_PATH常量来获取预置模板的绝对路径。metagpt.prompts.di.role_zero:依赖ROLE_INSTRUCTION作为基础角色指令。time:用于生成时间戳,确保项目文件夹名称唯一。
- 接口契约(对AI代理及工具集的约定):
- 工具接口:代码中提及了
Terminal.run_command,Browser,Editor(包含open_file,goto_line,read,edit_file_by_replace,insert_content_at_line等方法)、Engineer2.write_new_code、ImageGetter.get_image等工具。指令文本构成了使用这些工具的“契约”,规定了调用条件、参数注意事项(如路径是绝对还是相对)和后续处理。 - 环境变量契约:假设存在
{{workspace}}、{{project_name}}等变量可在指令中被替换,这依赖于外层框架提供这些上下文。 - 协议契约:
WRITE_CODE_SYSTEM_PROMPT和WRITE_CODE_PROMPT定义了一个严格的交互协议。AI代理必须遵循该协议接收输入(用户需求、计划状态等)并产生输出(一个且仅一个代码块)。WRITE_CODE_SYSTEM_PROMPT进一步规定了代码质量契约(如Google风格、无TODO)。
- 工具接口:代码中提及了
- 目录隔离:指令强制要求所有操作在特定的项目目录(
{{project_name}}_{timestamp})或下载的仓库目录内进行,防止AI代理意外操作或破坏系统其他文件,实现了操作沙盒化。 - 命令执行限制:虽然允许执行终端命令,但通过“必须在仓库目录内操作”的约束,间接限制了命令的执行范围。然而,对于
cp,mkdir,pnpm install等命令的使用仍需底层执行环境进行安全控制(如容器化)。 - 依赖管理:使用
pnpm install安装依赖,依赖源的安全性由项目配置和底层环境保障。 - 内容安全:指令未涉及对生成代码内容的审查(如恶意代码、许可证合规)。这部分安全依赖于基础AI模型的安全对齐策略以及后续的人工或自动化审计流程。
- 模板配置:通过
REACT_TEMPLATE_PATH和VUE_TEMPLATE_PATH常量,可以灵活配置不同技术栈的启动模板路径,支持前端生态的扩展。 - 指令模块化:基础指令(
ROLE_INSTRUCTION)与额外指令(EXTRA_INSTRUCTION)分离,允许在不改变核心角色定义的情况下,调整具体任务的行为细则。 - 提示词模板化:
WRITE_CODE_PROMPT和CURRENT_STATE采用格式化字符串,使得任务描述、状态信息等动态内容可以方便地注入,适应不同的编码任务场景。 - 技术栈优先级规则:
EXTRA_INSTRUCTION第24-25条定义了一个明确的技术栈选择优先级链条(系统设计指定 > Vite/React/Vue/MUI/Tailwind CSS > 原生HTML)。这个规则本身是硬编码的,但通过修改此规则文本可以调整技术选型策略。