0267da93f1
补充精准变更原则的约束条件,更新测试要求为更严格的核心逻辑验证策略, 细化依赖升级的分级策略,新增 Git Scope 推导规则和示例, 重构模块组织章节并提供完整目录结构示例,新增文档方案规范章节
8.2 KiB
8.2 KiB
AGENTS.md
交互要求
- 思考过程全程必须使用中文,包括需求分析、逻辑拆解、方案选择等所有推理环节
- 最终输出内容必须全部使用中文,除代码语法本身和英文关键词以外
核心原则 (Karpathy)
1. 先思考再编码 (Think Before Coding)
不要预设。不要隐藏困惑。呈现权衡。
- 明确陈述你的假设。如果不确定,就问。
- 如果存在多种解释,全部列出——不要默默选择其一。
- 如果有更简单的方法,就说出来。在必要时提出反对。
- 如果某件事不清楚,停下来。说出困惑所在。然后提问。
2. 简洁优先 (Simplicity First)
解决问题的最小代码量。不写任何推测性代码。
- 不实现超出需求的特性。
- 不为只用一次的代码创建抽象。
- 不添加未经要求的"灵活性"或"可配置性"。
- 不为不可能发生的场景做错误处理。
- 如果你写了 200 行而它本可以用 50 行完成,重写它。
3. 精准变更 (Surgical Changes)
只改动必须改的。只清理你自己造成的混乱。
- 未明确要求时不修改已有文件
- 先确认意图再动手
- 不要"优化"相邻的代码、注释或格式。
- 不要重构没有问题的代码。
- 遵循已有风格,即使你自己的写法不同。
- 如果你注意到不相关的死代码,提出来——但不要删除它。
- 删除你的改动导致的未使用的导入/变量/函数。
4. 目标驱动执行 (Goal-Driven Execution)
定义成功标准。迭代直至验证通过。
- "添加验证" → "通过测试验证已有实现的正确性"
- "修复缺陷" → "编写测试复现问题,验证修复"
- "重构 X" → "确保重构后测试仍然通过"
对于多步骤任务,简要列出计划:
1. [步骤] → 验证:[检查项]
2. [步骤] → 验证:[检查项]
技术栈规范
通用规范
包管理器: cargo
代码风格
- 文件/文件夹命名:
kebab-case - 类/组件命名:
PascalCase - 变量/函数命名:
snake_case
测试要求
- 核心业务逻辑需测试(关键算法、边界条件、错误处理)
- 简单逻辑不需要测试(枚举字面值、Getter、无分支的简单转换)
- 不主动补测试(除非用户明确要求)
错误处理
- 优先使用
Result处理错误,避免unwrap() - 异步 API 使用
?传播错误,不在catch中静默吞掉错误 - 错误按层级组织:公开 API 用全局 Error,内部实现可定义细粒度子错误
安全规范
- 不硬编码密钥,使用环境变量
- 用户输入必须验证
- 依赖升级策略:
- 安全补丁:立即升级(修复已知漏洞)
- 次要版本:评估后升级(新功能、向后兼容)
- 主要版本:谨慎升级(可能破坏兼容性,需全面测试)
- 验证:升级后运行完整测试套件确保无回归
Git Commit 规范
- 使用 Conventional Commits 格式:
<type>(<scope>): <description> - 描述使用中文
- 类型:
feat- 新功能fix- Bug 修复enhance- 增强现有功能(非新功能)docs- 文档更新style- 代码格式(不影响功能)refactor- 重构test- 测试相关chore- 构建/工具/配置
- 描述使用祈使句、现在时态、句尾无句号
- Scope 推导规则:
- 从被提交的文件路径中推导出一个最相关的 scope
- 一个 commit 只写一个主要 scope,不要罗列多个
- 如果改动涉及多个模块,选择影响范围最大的那个或使用更上层抽象名称
- 如果改动是全局的,可以省略 scope 或使用
core/global
- 示例:
feat(llm): 添加流式响应支持(修改src/llm/stream.rs)fix(memory): 修复向量检索边界条件(修改src/memory/vector_store.rs)refactor(core): 统一错误类型定义(修改多个模块的错误处理)docs: 更新 API 文档(全局文档更新)chore(deps): 升级 tokio 到 1.40(依赖更新)
Rust
包管理器: cargo
代码风格
cargo fmt格式化,cargo clippy检查- 变量/函数命名:
snake_case - 优先使用
Result处理错误,避免unwrap() - 所有权规则:不使用
&mut时不用,引用必须合法
模块组织
- 按功能领域组织模块(一个模块一个职责)
- 2018+ 版风格:使用
foo.rs作为模块根,子模块放在foo/目录下 - 扁平优先:如果模块没有子模块,直接用单个
foo.rs文件 - 需要子模块时才用目录:只有当模块需要组织多个子模块时才创建
foo/目录 - 避免
mod.rs:不使用foo/mod.rs风格,统一使用foo.rs作为模块根 - 公共 API 重导出:在模块根中使用
pub use重新导出子模块的公共类型,提供清晰的 API 边界
示例结构图:
src/
├── lib.rs # crate 根,声明顶层模块
├── llm.rs # LLM 模块(无子模块,扁平文件)
├── memory.rs # 记忆模块根(有子模块)
├── memory/
│ ├── conversation.rs # ✓ 子模块
│ └── vector_store.rs # ✓ 子模块
├── prompt.rs # 提示词模块根(有子模块)
├── prompt/
│ ├── template.rs # ✓ 子模块
│ └── optimizer.rs # ✓ 子模块
├── tool.rs # 工具模块根(有子模块)
├── tool/
│ ├── mcp.rs # ✓ 子模块
│ └── registry.rs # ✓ 子模块
└── agent.rs # Agent 模块根(有子模块)
└── agent/
├── runtime.rs # ✓ 子模块
└── planner.rs # ✓ 子模块
# ❌ 避免的风格
src/
└── memory/
└── mod.rs # ❌ 不使用 mod.rs 风格
# ✅ memory.rs 示例:声明子模块并重导出公共 API
pub mod conversation;
pub mod vector_store;
// 重导出常用类型,提供简洁的公共 API
pub use conversation::ConversationMemory;
pub use vector_store::VectorStore;
测试文件: 内联测试(#[cfg(test)] mod tests {})或 tests/ 目录
依赖管理: Cargo.toml,语义化版本
文档规范
方案规范 (docs/)
编号规则:创建新方案前必须先通过 shell 命令确认当前实际最大编号(Unix: ls docs/ / Windows: dir docs\),禁止使用上下文中缓存的编号,如遇冲突自动递增
方案文档结构(6 项):
- 背景与目标 - 问题描述、预期目标
- 需求分析 - 功能需求、非功能需求
- 方案设计 - 架构设计、模块划分、接口定义
- 实现计划 - 任务拆解、优先级、时间估算
- 风险评估 - 潜在风险、缓解措施
- 验收标准 - 可验证的完成条件
项目特定规则
项目结构
- 源代码:
src/(lib crate) - 测试:内联
#[cfg(test)] mod tests {}
项目目标
agcore 是一个智能体(Agent)核心工具箱,提供:
- LLM 调用:完整的请求/响应周期管理
- 提示词工程:组合、模板化、优化
- 记忆系统:存储、检索、管理对话/向量记忆
- 工具调用:MCP 协议集成与自定义工具注册
- Agent 运行时:多轮对话、任务编排
设计原则
- 模块化:每个功能领域独立 module,通过 trait 定义接口
- 可插拔:LLM 后端、记忆存储、工具注册均通过 trait 抽象
- 无运行时依赖:core 层尽量少依赖,具体实现在 separate crates
- 异步优先:涉及 IO 的 API 均使用
async
特殊约定
- 所有公开 API 必须有文档注释(
///) - 使用
thiserror或derive_more定义错误类型 - 错误按层级组织:公开 API 用全局 Error,内部实现可定义细粒度子错误
- 跨 module 依赖通过 trait 而非具体类型
- 配置优先从环境变量读取,支持 builder 模式注入
这些指南生效的标志:
- diff 中不必要的改动更少
- 因过度复杂而导致的重写更少
- 澄清问题在实现之前提出
- 干净、精简的 PR