编写基于 AST 的自定义 Linter

要实现"将架构约束写成自定义 Lint 规则,并将错误信息转化为 AI 的修复指南(Prompt)",你需要完成三个核心步骤:编写静态分析脚本 、设计面向 AI 的报错信息 、将其接入 CI/CD 流水线。

以下是具体的落地实现方案:

第一步:编写基于 AST 的自定义 Linter

Python 内置的 ast(抽象语法树)模块是进行静态代码分析的最佳工具。它可以在不执行代码的情况下,精准扫描 import 语句并检查架构违规。

以下是一个检查"领域层(domain)禁止依赖基础设施层(infrastructure)"的自定义 Linter 示例:

python 复制代码
# scripts/lint_architecture.py
import ast
import sys
from pathlib import Path

# 定义架构约束规则
FORBIDDEN_IMPORTS = {
    "src/domain": ["src.infrastructure", "src.interfaces"],
}

def check_architecture(filepath: Path) -> list[str]:
    errors = []
    # 检查当前文件是否命中了约束规则
    for restricted_dir, forbidden_modules in FORBIDDEN_IMPORTS.items():
        if str(filepath).startswith(restricted_dir):
            with open(filepath, encoding="utf-8") as f:
                tree = ast.parse(f.read())
            
            for node in ast.walk(tree):
                if isinstance(node, ast.ImportFrom) and node.module:
                    for forbidden in forbidden_modules:
                        if node.module.startswith(forbidden):
                            # 核心:构造面向 AI 的错误信息
                            errors.append(
                                f"❌ [架构违规] {filepath} 第 {node.lineno} 行: "
                                f"领域层禁止直接导入基础设施层模块 '{node.module}'。\n"
                                f"💡 [修复建议] 请遵循依赖倒置原则。在 domain 层定义抽象接口(如 Repository),"
                                f"在 infrastructure 层实现该接口,并通过依赖注入传入。\n"
                                f"📚 [参考文档] 请查阅 docs/architecture.md#dependency-rules 了解详细规范。"
                            )
    return errors

if __name__ == "__main__":
    all_errors = []
    for pyfile in Path("src").rglob("*.py"):
        all_errors.extend(check_architecture(pyfile))
    
    if all_errors:
        print("\n".join(all_errors))
        sys.exit(1)  # 返回非零退出码,阻断流水线
    print("✅ 架构规则检查通过")

第二步:掌握"错误信息即 Prompt"的设计原则

传统的 Linter 报错是给人看的(例如 ImportError 或 Architecture violation),但 AI 需要的是结构化的上下文。在设计报错信息时,必须包含以下三要素:

  1. 为什么不能这么做(Rationale):解释规则背后的架构意图,帮助 AI 理解上下文。
  2. 应该用什么替代(Actionable Fix):提供具体的重构方向或代码模式(如"使用依赖注入")。
  3. 去哪里看正确的例子 (Reference):指向项目中的深度文档(如 docs/ 目录下的 Markdown 文件),让 AI 能够按需检索。

这种设计将 Linter 的报错变成了一个"现场教学时刻(Teaching Moment)",AI 在读取到报错后,可以直接将其作为下一轮 Prompt 的输入,自行完成修复闭环。

第三步:接入 CI/CD 与 Harness 流水线

将编写好的 Linter 脚本集成到自动化流程中,使其成为 AI 无法绕过的"机械护栏":

  1. 配置 CI 门禁:在 GitHub Actions 或 GitLab CI 中添加执行该脚本的步骤。只要 AI 生成的代码触发了违规,CI 就会失败并返回上述详细的错误日志。
  2. 结合 LLM 驱动的代理审查:在 AI 提交 PR 之前,先运行此 Linter。如果失败,AI 会自动读取错误信息并修改代码,直到 Linter 通过后才允许进入人工或语义层面的审查。
  3. 使用专业工具替代手写(进阶) :如果项目规模较大,手写 AST 维护成本较高,可以引入 import-linter 等开源工具。通过在 .importlinter 配置文件中定义"契约(Contracts)",工具会自动扫描依赖图,你只需专注于配置契约和优化报错输出即可。

💡 最佳实践建议

  • 渐进式引入:不要一开始就开启所有规则。可以先将违规项记录为 Warning,让 AI 和团队适应一段时间,再转为强制阻断(Error)。
  • A/B 测试 Harness 规则:每增加一条 Linter 规则,对比 AI 任务的成功率。如果某条规则没有明显改善 AI 的产出质量,或者导致 AI 陷入无限修复循环,应果断移除,防止 Harness 膨胀。
  • 定期清理:随着项目演进,某些架构约束可能不再适用。可以部署专门的"垃圾回收 Agent"定期扫描过时的 Linter 规则并发起重构 PR。
相关推荐
Martina_03214 小时前
AI生成的海岸城市一移动镜头,水面反射就跳?用6步统一反射探针、SSR与平面反射
图像处理·人工智能·平面·3d·ai·自然语言处理·游戏策划
tianyatest5 小时前
给 AI Agent 写了个 Skill:扫描版电子书自动解压合并 + 加书签(附 PDG 格式逆向)
ai·pdf·电子书
风花一世月5 小时前
[特殊字符] 我把一套分布式消防方案做成了能跑的 3D 沙盘(三架无人机共用一根水带,在线直接玩)
分布式·3d·ai·无人机
GalaxyMeteor5 小时前
Windows 本地部署 Sam3 模型笔记(含Demo)
ai
秋饼6 小时前
Java 后端企业级 LLM 网关实战:Spring Cloud Gateway 构建统一大模型接入层
java·ai·技术分享·后端开发
赛博仓鼠7 小时前
Vidu Q4 Preview实测:15张参考图+3段音频驱动,2K/4K输出,国产视频生成新标杆
ai·aigc·音视频
粥里有勺糖7 小时前
Windows 搭建 ComfyUI 环境 | 小白也能直接上手
ai·经验总结·comfyui
袖清暮雨9 小时前
机器学习之其他聚类(层次聚类+DBSCAN算法)
人工智能·机器学习·ai·聚类
ofoxcoding9 小时前
Gemini TTS 与 ElevenLabs 语音合成实测:同一段视频旁白效果对比
ai·ffmpeg·音视频
谢亮_vipxieliang9 小时前
多智能体系统的“TCP/IP时刻”:MCP与A2A协议如何定义Agent时代
网络·tcp/ip·ai·php