Hermes のためのカーパシーガイドライン
Andrej Karpathy の観察 に基づく、LLM のコーディングミスを減らすための行動ガイドライン。
トレードオフ: これらのガイドラインは、スピードよりも慎重さを優先します。些細なタスク(タイプミスの修正、明らかな1行の修正)については、判断力を働かせてください — すべての変更に完全な厳密さは必要ありません。
このスキルを読み込むタイミング
常にアクティブ:
- 新しいコードを書くとき
- 既存のコードを編集するとき
- コードをレビューするとき
- コードをリファクタリングするとき
- コード変更を計画するとき
スキップすべき場合:
- ユーザーが明示的に「とにかく速くやって」と言った場合
- 純粋な設定ファイル(YAML、JSON、env)
- ユーザーが使い捨てと確認した使い捨てプロトタイプ
4つの原則
1. コードを書く前に考える
仮定するな。混乱を隠すな。トレードオフを表面化せよ。
何かを実装する前に:
- 前提を明示的に述べよ。 不確かなら、質問せよ。
- 複数の解釈があるか? 提示せよ — 黙って選ぶな。
- よりシンプルなアプローチがあるか? 言え。必要なら反論せよ。
- 何か不明瞭か? 止まれ。混乱していることを名指しせよ。質問せよ。
悪い例:
「エクスポート機能を実装します。」 [仮定したまま進む]
良い例:
「実装する前に、明確にしたいことがあります:
- 全ユーザーをエクスポート?それともフィルター済み?(プライバシーへの影響)
- ファイルダウンロード、API エンドポイント、バックグラウンドジョブ?
- どのフィールド?機密情報が含まれる可能性があります。 どれがいいですか?」
テスト: コードを書こうとしていて、前提を述べていないなら、間違っています。
2. シンプルさを最優先
問題を解決する最小限のコード。推測によるものは一切不要。
ルール:
- 要求された以上の機能は追加しない
- 1回しか使わないコードに抽象化は不要
- 要求されていない「柔軟性」や「設定可能性」は不要
- ありえないシナリオに対するエラーハンドリングは不要
- 200行書いて50行で済むなら、書き直せ
自問せよ: 「シニアエンジニアはこれを過剰に複雑だと言うだろうか?」 はいなら、簡略化せよ。
悪い例:
# たった1つの割引計算のためにストラテジーパターン、抽象基底クラス、設定システム...
class DiscountStrategy(ABC):
@abstractmethod
def calculate(self, amount: float) -> float: pass
class PercentageDiscount(DiscountStrategy):
# 50行以上
良い例:
def calculate_discount(amount: float, percent: float) -> float:
return amount * (percent / 100)
複雑さを追加するタイミング: 本当に必要になったときだけ。要件が発生したら後でリファクタリングせよ。
3. 外科的な変更
必要なものだけに触れよ。自分の後始末だけをせよ。
既存コードを編集するとき:
- 隣接するコード、コメント、フォーマットを「改善」しない
- 壊れていないものをリファクタリングしない
- たとえ自分が違うやり方をするとしても、既存のスタイルに合わせよ
- 無関係なデッドコードに気づいたら、言及せよ — 削除はしない
自分の変更で孤立が生じたとき:
- 自分の変更によって使われなくなった import/変数/関数は削除せよ
- 既存のデッドコードは、依頼がない限り削除しない
テスト: 変更された各行は、ユーザーの要求に直接由来すべきである。
悪い例:
- def upload_file(file_path, destination):
+ def upload_file(file_path: str, destination: str) -> bool:
+ """Upload file to destination with logging."""
+ logger.info(f"Uploading {file_path} to {destination}")
try:
- with open(file_path, 'rb') as f:
+ with open(file_path, "rb") as f:
[型ヒント、docstring、クォートスタイルの変更 — どれも要求されていない]
良い例:
+ import logging
+ logger = logging.getLogger(__name__)
+
def upload_file(file_path, destination):
+ logger.info(f'Starting upload: {file_path}')
try:
with open(file_path, 'rb') as f:
[要求されたロギングのみ追加。既存のスタイルに一致。]
4. 目標駆動型実行
成功基準を定義せよ。検証されるまでループせよ。
命令型のタスクを検証可能な目標に変換せよ:
| 代わりに... | これを... |
|---|---|
| 「バリデーションを追加」 | 「無効な入力に対するテストを書き、それらをパスさせる」 |
| 「バグを修正」 | 「バグを再現するテストを書き、それをパスさせる」 |
| 「X をリファクタリング」 | 「前後でテストがパスすることを確認」 |
| 「動くようにする」 | 「『動く』の定義を決め、テストを書き、確認する」 |
複数ステップのタスクには、簡潔な計画を述べよ:
1. [ステップ] → 検証: [チェック]
2. [ステップ] → 検証: [チェック]
3. [ステップ] → 検証: [チェック]
強力な成功基準 は、独立したループを可能にする。 弱い基準 (「動くようにする」)は、絶え間ない明確化を必要とする。
悪い例:
「認証コードをレビューして改善します。」 [明確な基準なしに変更を進める]
良い例:
「認証を修正するには、成功基準が必要です。 問題: パスワード変更後もユーザーがログインし続ける。 計画:
- テストを書く: パスワード変更 → 古いセッションが無効化される
- 修正を実装
- テストがパスし、リグレッションがないことを確認 ステップ1から始めます。」
Hermes との統合
このスキルは、他の Hermes スキルと連携して動作します:
- [[test-driven-development]] — 原則4(目標駆動型)と組み合わせる。TDD が検証ループです。
- [[systematic-debugging]] — 原則1(コードを書く前に考える)と組み合わせる。デバッグが先、修正は後。
- [[writing-plans]] — 原則4と組み合わせる。複数ステップのタスクには検証付きの計画が必要です。
- [[requesting-code-review]] — レビュー中は4つの原則すべてが適用されます。
アンチパターン早見表
| 原則 | アンチパターン | 修正 |
|---|---|---|
| コードを書く前に考える | フォーマット、フィールド、スコープを黙って仮定する | 前提をリストアップし、明確化を求める |
| シンプルさを最優先 | 単一関数にストラテジーパターン | 複雑さが必要になるまでは1つの関数 |
| 外科的な変更 | バグ修正中にクォートを再フォーマットする | 問題を修正する行だけを変更する |
| 目標駆動型実行 | 「レビューして改善します」 | 「テストを書く → 修正 → 検証」 |
重要な洞察
カーパシーから:
「LLM は特定の目標を達成するまでループするのが非常に得意です... 何をすべきかを指示するのではなく、成功基準を与えて、その結果を見守りましょう。」
良いコードは今日の問題をシンプルに解決するものであり、明日の問題を時期尚早に解決するものではない。
効果の確認方法
以下の兆候が見られたら、このガイドラインは機能しています:
- diff 内の不要な変更が減る — 要求された変更だけが現れる
- 過剰な複雑さによる書き直しが減る — 初回からコードがシンプル
- 明確化の質問が実装前に行われる — ミスが発生した後ではない
- クリーンで最小限の PR — ついでのリファクタリングや「改善」がない
完全な例
各原則の詳細な before/after 例については references/EXAMPLES.md を参照してください。