はじめに
最近は Codex や Claude Code などのAIエージェントを使ってPython開発をする機会が増えてきました。
実際に使ってみると、AIは驚くほど高速にコードを書いてくれます。
設計書を読ませれば数分でAPIを実装し、テストコードまで生成してくれることも珍しくありません。
しかし、運用していく中で次のような課題が見えてきました。
- 型ヒントを書き忘れる
- Docstringを書かない
- Repository Patternを無視する
- PromptをPythonコードへ直接書く
- APIからSQLを書いてしまう
- 設定ファイルを勝手に追加する
- テストを実行せずに終了する
つまり、
「動くコード」は作れるが、「品質ルール」は守ってくれない
という問題です。
そこで今回は、AIが迷わず品質を守れる開発標準を作成しました。
現在は次の3つを中心に運用しています。
| ファイル | 役割 |
|---|---|
pyproject.toml |
Build・依存管理・品質ツール設定 |
Makefile |
品質チェック・開発コマンドの標準化 |
AGENT.md |
AIへ守らせる設計ルール |
全体構成
今回の構成は以下のようになっています。
ポイントは、
品質ルール・実行方法・設計思想
をそれぞれ独立させていることです。
pyproject.tomlで品質ルールを一元管理する
まず最初に行ったのは、
品質ツールをすべて pyproject.toml に集約すること
でした。
以前は
- requirements.txt
- setup.py
- setup.cfg
- pytest.ini
- mypy.ini
- .flake8
など設定ファイルが散らばっていました。
AIは設定ファイルが複数あると、新しい設定ファイルを作ったり、違う場所を書き換えたりしてしまいます。
そこで Single Source of Truth として pyproject.toml のみを利用することにしました。
Build・Package管理
[build-system]
requires = ["setuptools>=75", "wheel"]
build-backend = "setuptools.build_meta"
[project]
requires-python = ">=3.12,<3.13"
この設定の目的
- PEP517準拠のBuildを利用する
- Pythonバージョンを固定する
-
setup.pyを不要にする
AIが古いBuild方法を書かないようにしています。
Optional Dependencies
[project.optional-dependencies]
dev = [
...
]
docs = [
...
]
この設定の目的
依存ライブラリを
- Runtime
- Development
- Documentation
に分離しています。
例えば
- pytest
- mypy
- black
は本番では不要なので dev
MkDocsは
docs
へ追加しています。
AIに
pytestを追加してください
と依頼しても、
適切な場所へ追加できるようになります。
Ruff
[tool.ruff]
line-length = 88
target-version = "py312"
[tool.ruff.lint]
select = ["B","D","F","I","SIM","UP","RUF"]
この設定の目的
LintはRuffへ統一しています。
主なルールは
| Rule | 内容 |
|---|---|
| B | Bugbear(バグになりやすいコード) |
| D | Docstring |
| I | Import Sort |
| SIM | コード簡略化 |
| UP | Python Upgrade |
| RUF | Ruff独自ルール |
Blackと責務を分離することで
- Ruff = 品質
- Black = 整形
としています。
Black
[tool.black]
line-length = 88
target-version = ["py312"]
この設定の目的
Blackはコードフォーマット専用です。
AIはスペースや改行が毎回変わるため、フォーマットを完全に自動化しています。
Mypy
[tool.mypy]
check_untyped_defs = true
disallow_untyped_defs = true
disallow_any_generics = true
no_implicit_optional = true
この設定の目的
AIは
def create(data):
のようなコードを書きがちです。
Mypyを利用することで
- 型ヒントなし
- Anyの多用
- Optionalの暗黙変換
を防止しています。
Pytest
[tool.pytest.ini_options]
この設定の目的
pytest.ini を作成せず、設定を pyproject.toml に集約しています。
AIが設定ファイルを増やさないためです。
Docstring
[tool.pydocstyle]
convention = "numpy"
[tool.interrogate]
fail-under = 95
この設定の目的
DocstringはNumPy形式へ統一しています。
さらにDocstring記載率95%以上を品質ゲートにしています。
AIは実装を優先するため、Docstringを書き忘れることが多く、この設定は非常に効果がありました。
Coverage
[tool.coverage.report]
fail_under = 80
この設定の目的
テストカバレッジ80%以上を維持します。
100%を目指すより、継続して80%以上を維持する方が現実的だと考えています。
Makefileで品質チェックを標準化する
品質ツールを導入しても、
毎回コマンドを覚えるのは面倒です。
そこで
make check
だけで品質確認が終わるようにしました。
Docker操作
make up
make down
make rebuild
Docker操作を統一しています。
開発者もAIもDocker Composeの細かいオプションを覚える必要がありません。
Migration
make migrate
make revision name=create_users
Alembic Migrationも標準化しています。
AIがMigrationコマンドを毎回調べる必要がありません。
品質チェック
品質確認は個別にも実行できます。
make lint
Ruff
make format
Black
make typecheck
Mypy
make docstyle
Docstring
make coverage
Coverage
用途に応じて個別実行できます。
make check
最終的には
check:
lint
format-check
typecheck
docstyle
doc-coverage
coverage
docs-build
だけ実行します。
つまり
make check
だけで
- Ruff
- Black
- Mypy
- Pytest
- Coverage
- Docstring
- MkDocs
まで一括で品質確認できます。
AIへの指示も
実装後に
make checkを実行してください
だけで済むようになりました。
AGENT.mdでAIへ設計思想を教える
今回一番効果があったのが
AGENT.md
です。
品質ツールでは Repository Pattern や Service Layer などの
アーキテクチャまでは保証できません。
そこでAIへ守ってほしいルールを文章として定義しました。
必須ルール
例えば
・Type Hint
・NumPy形式Docstring
・Pydantic
・SQLAlchemy ORM
・Repository Pattern
・Service Layer
・HTTP通信は clients/ に集約
・Promptは prompts/ に集約
・設定は pyproject.toml で管理
・実装後は make check を実行
この設定の目的
AIが
- APIへSQLを書く
- PromptをPythonコードへ書く
- HTTP通信をServiceへ書く
などを防止しています。
禁止ルール
逆に
APIからSQLを書かない
ServiceからSessionを直接操作しない
Promptをコードへ書かない
requirements.txtを追加しない
も定義しています。
この設定の目的
実際に一番効果があったのは 禁止事項 でした。
AIは「何を書くか」より「何を書いてはいけないか」を明示した方が、
設計ルールを守る傾向がありました。
AIがコードを書く流れ
実際には次のような流れで開発しています。
今後追加したいもの
現在は
- Ruff
- Black
- Mypy
- Coverage
- Docstring
までですが、
今後は
- pre-commit
- Bandit
- pip-audit
- deptry
- import-linter
- vulture
- radon
なども追加したいと考えています。
特に import-linter を利用すれば
API
↓
Service
↓
Repository
以外の依存関係を禁止できるため、AIによるアーキテクチャ崩壊をさらに防げると考えています。
おわりに
今回構築した品質ゲートは
- pyproject.toml:品質ルール
- Makefile:品質チェックの標準化
- AGENT.md:AIへ守らせる設計ルール
という3層構造になっています。
AIコーディングでは 「どのAIを使うか」 よりも 「AIが迷わない開発標準を用意すること」 の方が、長期的にはコード品質へ大きく影響すると感じています。
まだ試行錯誤中ですが、同じようにAIを活用してPython開発をしている方の参考になれば幸いです。
もし「こういう品質ゲートも入れた方がいい」「うちはこんな運用をしている」というものがあれば、ぜひコメントで教えてください。