EverOS 代码风格规范:以 Ruff 为唯一工具的全量类型注解 Python 工程实践
EverOS 代码风格规范以 Ruff 为唯一工具的全量类型注解 Python 工程实践【免费下载链接】EverOSOne portable memory layer for every AI agent: local-first, Markdown-native, user-owned, and self-evolving across apps, tools, and workflows.项目地址: https://gitcode.com/gh_mirrors/ev/EverOSEverOSsrc/everos/是一套本地优先、Markdown 原生、面向 AI Agent 的便携记忆层框架其 Python 代码库采用了一套严格且自洽的代码风格规范以 Ruff 作为唯一格式化与静态检查工具全量类型注解约 100% typed并配套了一套清晰的后缀命名体系。本文以仓库内.claude/rules/code-style.md规则文档为骨架结合 pyproject.toml、Makefile 及核心源码展开帮助读者掌握一套可直接落地到 AI 工程项目的 Python 工程化规范——读完后你将能够为项目配置 Ruff 的规则集与格式参数、写出完全类型化的函数签名、遵循可读性优先的命名后缀约定并用make format/make lint将规范固化为可重复执行的 CI 门禁。一、工具链统一Ruff 取代 Black / isort / flake8EverOS 的规则文档第一条明确Ruff 是该项目的唯一格式化与 Linter 工具替代了此前 Python 生态中常见的 Black格式化、isort导入排序、flake8静态检查三件套组合。这一决策的工程收益在于Ruff 用单个 Rust 二进制同时覆盖格式化ruff format与静态检查ruff check规则与配置集中在一处消除了多工具配置漂移问题。在 pyproject.toml 的[tool.ruff]段中可以找到项目的具体配置[tool.ruff] line-length 88 target-version py312 extend-exclude [src_old] [tool.ruff.lint] select [E, F, I, N, UP, B, SIM, ASYNC, RUF] ignore [ RUF001, # ambiguous Unicode in strings (intentional × – symbols) RUF002, # ambiguous Unicode in docstrings RUF003, # ambiguous Unicode in comments RUF012, # mutable class attribute default (SQLModel requires this) ]其中line-length 88与规则文档中的行宽要求一一对应target-version py312表明代码按 Python 3.12 语法目标进行格式化requires-python 3.12见 pyproject.toml。关于规则集规则文档列出的是E F I N UP B SIM ASYNC而 pyproject.toml 的select中额外追加了RUFRuff 自带的规则同时通过ignore对RUF001/002/003字符串中的歧义 Unicode 字符和RUF012可变类属性默认值做了有依据的豁免——后者的注释明确说明 SQLModel 的 ORM 声明方式要求可变默认值属于不可修复的上游约束。规则集对应的检查类别为前缀含义典型示例EPEP 8 风格错误pycodestyle行长超限、多余空行F逻辑错误pyflakes未使用导入、未定义名称I导入排序isort 规则导入顺序、分组N命名规范pep8-naming类名应为 CapWords、函数应为 snake_caseUPpyupgrade 现代化语法使用X \| None代替Optional[X]Bbugbear 易错点易踩坑的写法SIM简化重构建议flake8-simplify可合并的 if 分支ASYNC异步代码专用检查异步函数中的同步阻塞调用RUFRuff 专属规则统一 API、额外防御从 pyproject.toml 的per-file-ignores可以看到一个“有理由才豁免”的实践范例benchmarks/run.py单独豁免了E501行长超限因为该文件内嵌 LoCoMo 基准测试的 LLM 提示词字符串ANSWER_PROMPT/JUDGE_*_PROMPT换行会改变 LLM 实际看到的内容。这正是规则文档除非有真实理由否则不要内联禁用规则——优先修复代码的落地体现。二、日常命令make format 与 make lint规则文档指定了三个日常入口make format自动修复、make lint检查。对应实现见 Makefilelint: uv run ruff check src tests uv run ruff format --check src tests uv run lint-imports uv run python scripts/check_repo_assets.py uv run python scripts/check_file_sizes.py uv run python scripts/check_deprecated_names.py uv run python scripts/check_github_contributor_docs.py uv run python scripts/check_datetime_discipline.py uv run python scripts/dump_openapi.py --check format: uv run ruff check --fix src tests uv run ruff format src tests关键细节format目标先执行ruff check --fix自动修复可机械修复的 lint 问题再执行ruff format按 88 列宽规范化排版作用范围限定在src与tests两个目录不会触及仓库中的脚本或示例代码。lint目标不仅仅是 Ruffruff format --check用于校验格式未被破坏lint-imports是 import-linter 的 CLI对应 pyproject.toml 中[[tool.importlinter.contracts]]定义的分层架构约束后续一串scripts/check_*.py是仓库自研的门禁脚本文件体积、废弃产品名、GitHub 贡献者文档、datetime 纪律、OpenAPI 漂移检查。这印证了规则文档所说的make lintchecks是一整套工程门禁而非单纯的语法检查。完整的开发工作流是make ci其定义为ci: lint test integration package即静态检查 → 单元测试 → 集成测试 → 打包冒烟全部通过才算合格。相关命令含义可参考 Makefile 顶部的help目标lint ruff (check format-check) import-linter datetime discipline openapi drift format Format src/tests with ruff test pytest tests/unit integration pytest tests/integration package Build sdist/wheel and smoke-test wheel import ci full CI: lint test integration package三、全量类型注解公共函数签名必须完整标注规则文档要求每个公共函数的签名都必须标注参数与返回值类型整个代码库约 100% 类型化并需要保持这一水平。这在 pyproject.toml 的分类器Typing :: Typed以及py.typed标记文件见 src/everos/py.typed中都有体现——后者是 PEP 561 规定的内联类型标记向类型检查器宣告该包自带类型信息。在源码中随处可见这种纪律。以 LLM provider 为例async def chat( self, messages: list[ChatMessage], *, model: str | None None, temperature: float | None None, max_tokens: int | None None, response_format: Mapping[str, Any] | None None, **extra: Any, ) - ChatResponse:再看 embedding provider 的并发批处理入口参数、默认值、返回值全部有精确注解async def embed_batch(self, texts: Sequence[str]) - list[list[float]]: Embed many strings, preserving input order. if not texts: return [] chunks [ list(texts[i : i self._batch_size]) for i in range(0, len(texts), self._batch_size) ] results await asyncio.gather(*(self._embed_chunk(chunk) for chunk in chunks)) return [vec for chunk in results for vec in chunk]值得注意texts: Sequence[str]的写法——这正对应规则文档中优先使用collections.abcSequence、Mapping而非具体的list/dict的要求函数接受任何序列型输入list、tuple 等在实现内部保持只读语义这比硬编码list[str]更灵活且不损失安全性。四、from __future__ import annotations免费的前向引用规则文档要求每个模块顶部放置from __future__ import annotations理由是注解变为字符串后前向引用与X | None联合类型PEP 604写法无需任何额外处理即可使用。这一规范在代码库中得到了近乎全量的执行——对 src/everos/ 目录的检索显示200 个 Python 源文件几乎都在首行声明了该 future import覆盖 API 路由、CLI 命令、内存层、基础设施层等全部子系统。从 settings.py 可以直观看到该特性的价值——它在定义嵌套设置模型时直接使用了 PEP 604 联合类型与结构化写法class LLMSettings(BaseModel): model: str gpt-4.1-mini api_key: SecretStr | None None base_url: str | None None若没有from __future__ import annotationsSecretStr | None这类写法在运行时求值可能引发问题尤其涉及延迟求值或循环引用的场景作为字符串注解后PEP 563 保证其只在类型检查阶段被解析。这意味着开发者在写自身引用的递归类型如树状 DTO或跨模块的循环类型依赖时无需再为名字尚未定义而头痛。五、命名约定*Manager / *Provider / *Reader / *Writer / *Recaller规则文档给出了一套后缀命名体系用于在大型代码库中快速定位对象的职责后缀职责仓库中的实例*Manager编排器orchestratorsget/manager.py记忆读取编排、sqlite_manager.py、lancedb_manager.py存储管理、search/manager.py搜索编排*Provider可注入服务injectable servicesllm/openai_provider.py、embedding/openai_provider.py、rerank/ 下的dashscope_provider.py/deepinfra_provider.py/vllm_provider.py*Reader/*Writer持久化读写markdown/readers/ 与 markdown/writers/ 下的各类 reader / writer*Recaller搜索召回search routessearch/recall/ 下的episode.py、atomic_fact.py、agent_case.py等在 recall/base.py 中可以看到*Recaller与*Deps搭配使用的结构性设计——RecallerDeps以 frozen dataclass 打包召回器共享依赖KindRecaller则是一个runtime_checkable的Protocol声明sparse_recallBM25与dense_recall向量 ANN两个异步调用点dataclasses.dataclass(frozenTrue) class RecallerDeps: Shared dependencies for every LanceDB-backed recaller. tokenizer: Tokenizer runtime_checkable class KindRecaller(Protocol): One business kind, BM25 vector recall over its LanceDB table. kind: ClassVar[str] async def sparse_recall(self, query: str, where: str, *, limit: int) - list[Candidate]: ... async def dense_recall(self, vector: Sequence[float], where: str, *, limit: int) - list[Candidate]: ...这同时示范了规则文档的另一要求用Protocol表达结构化接口。everos 的 provider 层正是通过 PEP 544 的Protocol与外部算法包everalgo对接——见 llm/protocol.py 的模块文档LLM 的结构性契约是everalgo.llm.LLMClienteveros 的 provider 必须pass-through-compatible透传兼容使构造出的客户端能直接注入给 everalgo 提取器使用。以Protocol而非抽象基类表达接口使跨包对接无需继承关系天然符合面向行为而非继承的设计取向。六、无死代码原则删除而非注释规则文档规定不得存在注释掉的代码块、未使用的导入、投机性抽象speculative abstractions主张删除而非注释掉。这条纪律在 pyproject.toml 的多个强制配置中形成了制度化支撑import-linter 分层契约[[tool.importlinter.contracts]]定义了everos.entrypoints → everos.service → everos.memory → everos.infra的分层架构任何下层被上层以外的模块错误引用都会失败同时还定义了子包内部为私有的 forbidden 契约——外部模块只能通过子包__init__.py的公开 API 访问持久化层直连sqlite.tables/lancedb.repos等内部模块即被拦截。这让未使用的抽象和绕道导入在 CI 阶段就无法存活。覆盖率门槛[tool.coverage.report]中fail_under 80且branch true开启分支覆盖率if TYPE_CHECKING:、abstractmethod、pragma: no cover不计入。死代码通常意味着低覆盖或不可达分支80% 的门槛从测试侧压制了死代码的生存空间。lint 门禁链make lint中check_file_sizes.py文件体积上限、check_deprecated_names.py废弃产品名、check_repo_assets.py禁止提交图片/视频等资产进仓库等自研脚本把仓库卫生作为与静态检查同级的 HARD gate。有意思的是测试套件对无死代码也有反向印证scripts/下的check_deprecated_names.py、check_file_sizes.py、check_datetime_discipline.py等脚本在 tests/unit/test_scripts/ 中都有对应的单元测试如test_check_file_sizes.py、test_check_deprecated_names.py说明这些门禁自身也被测试守护——门禁代码不允许变成无人维护的死代码。七、实战落地将这套规范复制到你的项目结合上文将 EverOS 的代码风格规范迁移到其他 Python 工程时推荐按以下步骤进行在 pyproject.toml 中声明 Ruff 配置关键参数照抄line-length 88、target-version py312select从E F I N UP B SIM ASYNC起步需要更严可加RUF。全局启用未来注解在新模块顶部统一加from __future__ import annotations并在 Review 中将其设为强制项对存量代码可分批补上。制定命名对照表参照 *Manager / *Provider / *Reader / *Writer / *Recaller 后缀为团队项目建立职责后缀字典新代码按表命名。签名类型化作为 Definition of Done公共函数缺返回注解、参数注解不完整视为未完成优先使用Sequence/Mapping与Protocol。把门禁接入 CI仿照 Makefile 的lint目标将ruff check --fixruff format --check与团队自研检查脚本串联作为合并前的强制门槛如项目有分层架构用 import-linter 声明层间依赖契约。结语EverOS 的代码风格规范并不追求花哨它的核心是单一工具 强类型纪律 命名即职责 门禁自动化四件事的组合。Ruff 统一了格式与静态检查入口from __future__ import annotations与全量注解让代码库的契约在编译期即可验证后缀命名让十万行级代码的职责一目了然而make lint链上的自研脚本与 import-linter 契约则把规范从文档变成了机器可执行的硬约束。对于任何正在或将要构建长生命周期 AI 工程团队的开发者这套组合都值得直接借鉴——规范的终点不是写出来而是让每个 PR 都无法绕过。【免费下载链接】EverOSOne portable memory layer for every AI agent: local-first, Markdown-native, user-owned, and self-evolving across apps, tools, and workflows.项目地址: https://gitcode.com/gh_mirrors/ev/EverOS创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考