Pythonを"理解"しているコーディングエージェントが欲しい!!
デモ準備
/plugin disable (/hooks ローカルだけに)
過去に作ったスクリプトは消す
PS1
tree -a
Pythonを"理解"しているコーディングエージェントが欲しい!!
- Event:
YAPC::Fukuoka 企画LT「あなたが本気で欲しいAI Agent」
- Presented:
2025/11/14 nikkie
コーディングエージェント
Claude Code(本LTの主役)
Codex CLI
Gemini CLI
etc. etc. [1]
君たちは圧倒的に 速い 🚄
人件費に比べて 安い 💰
私は Python を書かせることが多いです
でも、Pythonのこと分かってます?
ClaudeがPythonを 理解しているようには見えない んです
分かっていない一例:f-string
フォーマット済み文字列リテラル
式 を含められる
>>> name = "りせ"
>>> f"こんにちは、{name}さん!"
'こんにちは、りせさん!'
>>> print(f"2 + 3 = {2 + 3}")
2 + 3 = 5
🤖「全部f-stringでええやろ!」
logger.info(f"{user} - Something happened")
logger.error(f"Python version: {sys.version}")
違う、そうじゃない
logger.info("%s - Something happened", user)
logger.error("Python version: %s", sys.version)
📣私が決して書かないPythonを、私の名前でコミットしないで!
💡そうだ、リンタで指摘しよう
例:Ruff
-
Logging statement uses f-string
Claude Codeの フック を設定
Pythonを書いたときにリンタを実行する(ロギングのf-stringを含む 600超 のルール)
リンタのエラー出力を繰り返しClaudeに見せる(逃 し ま せ ん)
デモ
エラトステネスの篩をPythonで書いて
Claude Code v2.0.37
追記:応援ありがとうございました
> エラトステネスの篩をPythonで書いて
⏺ エラトステネスの篩をPythonで実装します。
> いいね、ファイルに書いてみよっか
⏺ ファイルに書き込みます。どのファイル名にしますか?例えば sieve_of_eratosthenes.py などでしょうか?
> それで
⏺ わかりました。sieve_of_eratosthenes.py として保存します。
セッション全体 https://gist.github.com/ftnext/58d17133b3b282831f136864ac770c28
追記:フックの様子
⎿ PostToolUse:Write hook returned blocking error: [jq -r '.tool_input.file_path' | { read file_path; if echo "$file_path" | grep -q
'\.py$'; then "$CLAUDE_PROJECT_DIR"/.claude/hooks/python_format.sh "$file_path"; fi; }]: cmd [1] | ruff check --config
'/.../hatch/env/.internal/hatch-static-analysis/.config/ukmfGEkg/ruff_defaults.toml' --fix
/.../2025-slides/samplecode/claude-code-harness/sieve_of_eratosthenes.py
sieve_of_eratosthenes.py:11:12: PLR2004 Magic value used in comparison, consider replacing `2` with a constant variable
sieve_of_eratosthenes.py:14:20: RUF003 Comment contains ambiguous `(` (FULLWIDTH LEFT PARENTHESIS). Did you mean `(` (LEFT
PARENTHESIS)?
sieve_of_eratosthenes.py:14:25: RUF003 Comment contains ambiguous `)` (FULLWIDTH RIGHT PARENTHESIS). Did you mean `)` (RIGHT
PARENTHESIS)?
sieve_of_eratosthenes.py:27:12: RET504 Unnecessary assignment to `primes` before `return` statement
sieve_of_eratosthenes.py:34:5: T201 `print` found
sieve_of_eratosthenes.py:35:5: T201 `print` found
Found 6 errors.
No fixes available (3 hidden fixes can be enabled with the `--unsafe-fixes` option).
⏺ ruffのチェックでいくつかエラーが出ているので、修正します。
追記:リントをパスしたエラトステネスの篩
MIN_PRIME = 2
def sieve_of_eratosthenes(n):
"""
エラトステネスの篩を使ってn以下の素数を求める
Args:
n: 素数を求める上限値
Returns:
n以下の素数のリスト
"""
if n < MIN_PRIME:
return []
# 最初は全てTrueで初期化(素数候補)
is_prime = [True] * (n + 1)
is_prime[0] = is_prime[1] = False # 0と1は素数ではない
# 2からsqrt(n)まで処理
for i in range(MIN_PRIME, int(n**0.5) + 1):
if is_prime[i]:
# iの倍数を全て合成数としてマーク
for j in range(i * i, n + 1, i):
is_prime[j] = False
# 素数のリストを生成
return [i for i in range(n + 1) if is_prime[i]]
# 使用例
if __name__ == "__main__":
import sys
n = 100
primes = sieve_of_eratosthenes(n)
sys.stdout.write(f"{n}以下の素数: {primes}\n")
sys.stdout.write(f"個数: {len(primes)}\n")
配布しています [2]
/plugin marketplace add https://github.com/ftnext/claude-code
/plugin install opinionated-python-hook@nikkie-marketplace
https://github.com/ftnext/claude-code
uvが必要です https://docs.astral.sh/uv/getting-started/installation/
💡サブエージェントの出番では
Pythonを書くサブエージェント を用意した(設定例)
メインの Claude Code のコンテキストにリントエラーとその修正過程は不要
サブエージェントがPythonを書いた後、フックのリントエラーを見て修正していって そう [3]
動作の様子からの判断です。ドキュメントの裏とり間に合わず🙏
まとめ🌯 Pythonを"理解"しているコーディングエージェントが欲しい!!
私の名前でコミットするからには、Pythonを理解して書いてもらおう
Claude Codeのフックにリンタを設定して 逃 が さ な い(自走 させる)
ご清聴ありがとうございました
nikkie(にっきー)・Python使い・ @ftnext sphinx-deck など
機械学習エンジニア。 Speeda AI Agent 開発(We're hiring!)
Appendix
逃がさないフック設定詳細
自走について先行発表
Claude Codeのフック設定
概要
Pythonを書いたら=PostToolUse
フックの終了コードは2、標準エラー出力へ
ローカル のプロジェクトに設定
.claude/
├── hooks/
│ └── python_format.sh
└── settings.local.json
PostToolUseフック
EditまたはWriteでPythonファイルを書いたら
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | { read file_path; if echo \"$file_path\" | grep -q '\\.py$'; then \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/python_format.sh \"$file_path\"; fi; }"
}
]
}
]
}
}
python_format.sh
#!/usr/bin/env bash
set -u
uvx hatch fmt "$1" 1>&2
exit_code=$?
if [ $exit_code -eq 1 ]; then
exit 2
else
exit $exit_code
fi
フックのエラーメッセージをClaudeに見せるために
python_format.shの終了コードを 2 にする(Claude Codeをブロック)hatch fmtの出力を stderr へ(Claudeが見る)
拙ブログ フックでリンタ(hatch fmt)のエラーを Claude Code に見せて、Python を理解している実装をさせる
コーディングエージェントの自走
先行する発表