AGENTS.mdだけじゃない!LLM時代に必須となる『AIのためのドキュメント』まとめ

Generative AI
この記事は約68分で読めます。

こんにちは、JS2IIUです。

ソフトウェア開発の現場で、ドキュメントの役割が根本的に変化しています。従来、ドキュメントは「人間の開発者が読んで理解するもの」でした。しかし、GitHub CopilotやCursor、Windsurfといった生成AI搭載のコーディングアシスタントの登場により、ドキュメントは「LLMに読ませて、プロジェクトの文脈を理解させるもの」としての役割が急速に重要になっています。

考えてみてください。新しいプロジェクトにジョインした開発者は、README.mdやCONTRIBUTING.mdを読んで、プロジェクトの構造やコーディング規約を理解します。実は、AIコーディングアシスタントも同じことをしています。違いは、AIは毎回セッションごとに「記憶をリセット」されるため、毎回同じ説明を受ける必要があるという点です。

「このプロジェクトではTypeScriptを使っています」「importは相対パスではなく絶対パスで」「テストはJestで書いてください」——こうした指示を毎回プロンプトで伝えるのは非効率的です。そこで登場したのが、「AI向けドキュメント」という新しいカテゴリのファイル群です。

本記事では、AGENTS.md.cursorrulesllms.txtai.txtなど、最近標準化されつつある「AIのためのドキュメント」について、その種類、役割、具体的な書き方を体系的に解説します。これらを適切に配置することで、RAGの精度向上、コーディングアシスタントの品質改善、そして開発チーム全体のDXが劇的に向上します。今回もよろしくお願いします。

AI向けドキュメントの全体像

AI向けドキュメントは、大きく分けて4つのカテゴリに分類できます。

  1. Web/RAG向け:Webサイトやドキュメントサイト全体の構造をLLMに理解させる
  2. IDE/コーディング向け:IDEに統合されたAIアシスタントに開発規約を守らせる
  3. エージェント向け:自律的に動作するAIエージェントに行動指針を与える
  4. 許可制御向け:AIによる学習やクローリングの可否を明示する

それぞれ見ていきましょう。

カテゴリ1:Web/RAG向け — llms.txt

llms.txtとは何か

llms.txtは、Webサイト全体の構造と重要なコンテンツをLLMに効率的に伝えるためのプレーンテキストファイルです。ルートディレクトリの/llms.txtに配置することで、RAGシステムやAIエージェントがサイトを巡回する際の「地図」として機能します。

なぜllms.txtが必要なのか

従来、Webサイトの情報をAIに理解させるには、すべてのページをクローリングしてベクトル化する必要がありました。しかし、これには以下の問題があります。

  • HTMLタグやナビゲーション要素などのノイズが含まれる
  • ページ間の関係性が不明瞭
  • 重要なページと補助的なページの区別がつかない
  • クローリングに時間とコストがかかる

llms.txtは、これらの問題を解決します。サイト運営者が「AIに読んでほしい情報」を構造化して提供することで、LLMはサイト全体を瞬時に理解できます。

llms.txtの書き方

llms.txtの基本的な構造は、Markdownライクなシンプルな形式です。

Markdown
# MyProject Documentation

> This is the official documentation for MyProject, a Python framework for building scalable web applications.

## Getting Started
/docs/quickstart: Quick start guide with installation instructions
/docs/tutorial: Step-by-step tutorial for beginners

## API Reference
/docs/api/models: Database model definitions and ORM usage
/docs/api/views: View classes and request handling
/docs/api/serializers: Data serialization and validation

## Guides
/docs/guides/authentication: User authentication and authorization
/docs/guides/deployment: Production deployment best practices
/docs/guides/testing: Testing strategies and tools

## FAQ
/docs/faq: Frequently asked questions

このファイルをプロジェクトのルートまたはドキュメントディレクトリに配置します。重要なのは、各リンクに「何が書かれているか」を短く説明することです。これにより、LLMは質問に応じて適切なページを参照できます。

実装例:llms.txtの自動生成

Pythonで既存のドキュメント構造からllms.txtを自動生成するスクリプトを作ってみましょう。

Python
import os
from pathlib import Path
from typing import List, Dict

class LLMSTxtGenerator:
    """
    ドキュメントディレクトリを走査して、llms.txtを自動生成するクラス
    """
    def __init__(self, docs_dir: str, base_url: str = ""):
        self.docs_dir = Path(docs_dir)
        self.base_url = base_url
        self.structure: Dict[str, List[Dict[str, str]]] = {}

    def scan_directory(self, directory: Path = None, category: str = "Documentation"):
        """
        ディレクトリを再帰的にスキャンし、Markdownファイルを収集
        """
        if directory is None:
            directory = self.docs_dir

        if category not in self.structure:
            self.structure[category] = []

        for item in sorted(directory.iterdir()):
            if item.is_file() and item.suffix in ['.md', '.mdx']:
                # ファイルの最初の数行から説明を抽出
                description = self._extract_description(item)
                relative_path = item.relative_to(self.docs_dir)
                url_path = str(relative_path).replace('\\', '/').replace('.md', '')

                self.structure[category].append({
                    'path': f"/{url_path}",
                    'description': description
                })

            elif item.is_dir() and not item.name.startswith('.'):
                # サブディレクトリは新しいカテゴリとして扱う
                subcategory = item.name.replace('-', ' ').replace('_', ' ').title()
                self.scan_directory(item, subcategory)

    def _extract_description(self, filepath: Path) -> str:
        """
        Markdownファイルから説明文を抽出(最初の段落を使用)
        """
        try:
            with open(filepath, 'r', encoding='utf-8') as f:
                lines = f.readlines()

            # タイトル(# で始まる行)をスキップして、最初の段落を取得
            description = ""
            in_paragraph = False

            for line in lines:
                line = line.strip()
                if line.startswith('#'):
                    continue
                if line and not in_paragraph:
                    in_paragraph = True
                    description = line
                    break

            # 説明が長すぎる場合は切り詰める
            if len(description) > 100:
                description = description[:97] + "..."

            return description or "Documentation page"
        except Exception as e:
            return "Documentation page"

    def generate_llms_txt(self, project_name: str, project_description: str) -> str:
        """
        収集した情報からllms.txtの内容を生成
        """
        output = [f"# {project_name}\n"]
        output.append(f"> {project_description}\n")

        for category, pages in self.structure.items():
            if pages:
                output.append(f"\n## {category}")
                for page in pages:
                    url = f"{self.base_url}{page['path']}" if self.base_url else page['path']
                    output.append(f"{url}: {page['description']}")

        return "\n".join(output)

    def save(self, output_path: str = "llms.txt"):
        """
        生成したllms.txtをファイルに保存
        """
        content = self.generate_llms_txt(
            project_name="MyProject",
            project_description="A comprehensive guide to MyProject features and APIs"
        )

        with open(output_path, 'w', encoding='utf-8') as f:
            f.write(content)

        print(f"llms.txt generated successfully at {output_path}")

# 使用例
if __name__ == "__main__":
    generator = LLMSTxtGenerator(
        docs_dir="./docs",
        base_url="https://myproject.com"
    )
    generator.scan_directory()
    generator.save("llms.txt")

このスクリプトは、ドキュメントディレクトリを走査し、各Markdownファイルの最初の段落を説明文として抽出します。実行すると、構造化されたllms.txtが自動生成されます。

実例:有名プロジェクトのllms.txt

実際に、Anthropic社が提供するClaudeのドキュメントサイトでは、以下のようなllms.txtが公開されています(簡略化版)。

Markdown
# Claude API Documentation

> Official documentation for Claude, Anthropic's large language model API

## API Reference
/api/reference: Complete API endpoint reference
/api/authentication: API key management and authentication
/api/messages: Send messages to Claude and receive responses

## Guides
/guides/prompt-engineering: Best practices for prompt design
/guides/safety: Content moderation and safety features

参考URL: https://docs.anthropic.com/llms.txt(実際の形式は異なる場合があります)

カテゴリ2:IDE/コーディング向け — .cursorrules

.cursorrulesとは

.cursorrulesは、Cursor IDEに特化したAIコーディングアシスタント向けの設定ファイルです。プロジェクトのルートディレクトリに配置することで、Cursorの動作をカスタマイズし、プロジェクト固有のコーディング規約やベストプラクティスを強制できます。

.cursorrulesの威力

AIコーディングアシスタントは非常に強力ですが、プロジェクトごとの「お作法」を知りません。例えば:

  • 「TypeScriptではなくPythonを使う」
  • 「クラス名はPascalCase、関数名はsnake_caseで」
  • 「日付処理はmomentではなくdate-fnsを使う」
  • 「エラーハンドリングは必ずtry-exceptで囲む」

こうしたルールを.cursorrulesに記述しておくと、Cursorが生成するコードは自動的にこれらのルールに従います。毎回プロンプトで指示する必要がなくなり、開発効率が劇的に向上します。

.cursorrulesの書き方

.cursorrulesはMarkdown形式のテキストファイルです。以下は実践的な例です。

Markdown
# Project Coding Rules

## Language and Framework
- Use Python 3.11+ exclusively
- Use PyTorch for all machine learning tasks
- Use FastAPI for API development

## Code Style
- Follow PEP 8 for Python code style
- Use type hints for all function signatures
- Maximum line length: 100 characters
- Use docstrings in Google style for all public functions and classes

## Naming Conventions
- Classes: PascalCase (e.g., `DataLoader`, `TransformerModel`)
- Functions and methods: snake_case (e.g., `load_data`, `train_model`)
- Constants: UPPER_SNAKE_CASE (e.g., `MAX_EPOCHS`, `LEARNING_RATE`)
- Private methods: prefix with underscore (e.g., `_internal_method`)

## Error Handling
- Always use try-except blocks for operations that might fail
- Use specific exception types rather than bare except
- Log errors using the logging module, not print statements

## Testing
- Write unit tests for all public functions
- Use pytest as the testing framework
- Test file names should match the module: `test_<module_name>.py`
- Aim for at least 80% code coverage

## Documentation
- All public APIs must have comprehensive docstrings
- Include parameter types, return types, and example usage
- Update README.md when adding new features

## Dependencies
- Add all new dependencies to requirements.txt with version pins
- Prefer well-maintained libraries with active communities
- Avoid dependencies with known security vulnerabilities

## Code Generation Preferences
- When suggesting code, always include error handling
- Provide complete, runnable examples rather than snippets
- Add comments explaining complex logic
- Suggest refactoring opportunities when code becomes complex

このファイルをプロジェクトルートに.cursorrulesとして保存すると、Cursorは自動的にこれらのルールを読み込み、コード生成時に適用します。

実装例:.cursorrulesの動的生成

既存のプロジェクト設定から.cursorrulesを自動生成するツールを作成してみましょう。

Python
import ast
import json
from pathlib import Path
from typing import Dict, List, Set

class CursorRulesGenerator:
    """
    プロジェクトの構造を分析して.cursorrulesを生成
    """
    def __init__(self, project_dir: str):
        self.project_dir = Path(project_dir)
        self.languages: Set[str] = set()
        self.frameworks: Set[str] = set()
        self.conventions: Dict[str, List[str]] = {}

    def analyze_project(self):
        """
        プロジェクトディレクトリを分析して、使用言語とフレームワークを検出
        """
        # requirements.txtから依存関係を取得
        req_file = self.project_dir / "requirements.txt"
        if req_file.exists():
            self._analyze_requirements(req_file)

        # package.jsonから依存関係を取得(TypeScriptプロジェクトの場合)
        pkg_file = self.project_dir / "package.json"
        if pkg_file.exists():
            self._analyze_package_json(pkg_file)

        # Pythonファイルを分析してコーディングスタイルを推測
        python_files = list(self.project_dir.rglob("*.py"))
        if python_files:
            self.languages.add("Python")
            self._analyze_python_style(python_files[:10])  # 最初の10ファイルをサンプル

    def _analyze_requirements(self, req_file: Path):
        """
        requirements.txtから主要なフレームワークを検出
        """
        framework_keywords = {
            'torch': 'PyTorch',
            'tensorflow': 'TensorFlow',
            'fastapi': 'FastAPI',
            'flask': 'Flask',
            'django': 'Django',
            'pandas': 'Pandas',
            'numpy': 'NumPy',
            'scikit-learn': 'Scikit-learn'
        }

        with open(req_file, 'r') as f:
            for line in f:
                line = line.strip().lower()
                for keyword, framework in framework_keywords.items():
                    if keyword in line:
                        self.frameworks.add(framework)

    def _analyze_package_json(self, pkg_file: Path):
        """
        package.jsonから依存関係を分析
        """
        with open(pkg_file, 'r') as f:
            data = json.load(f)

        dependencies = {**data.get('dependencies', {}), **data.get('devDependencies', {})}

        if 'react' in dependencies:
            self.frameworks.add('React')
            self.languages.add('TypeScript/JavaScript')
        if 'vue' in dependencies:
            self.frameworks.add('Vue')
            self.languages.add('TypeScript/JavaScript')
        if 'typescript' in dependencies:
            self.languages.add('TypeScript')

    def _analyze_python_style(self, python_files: List[Path]):
        """
        Pythonファイルからコーディングスタイルを推測
        """
        class_names = []
        function_names = []

        for file_path in python_files:
            try:
                with open(file_path, 'r', encoding='utf-8') as f:
                    tree = ast.parse(f.read())

                for node in ast.walk(tree):
                    if isinstance(node, ast.ClassDef):
                        class_names.append(node.name)
                    elif isinstance(node, ast.FunctionDef):
                        function_names.append(node.name)
            except:
                continue

        # 命名規則の推測
        if class_names:
            # PascalCaseが使われているか確認
            pascal_case = sum(1 for name in class_names if name[0].isupper())
            if pascal_case / len(class_names) > 0.8:
                self.conventions['class_naming'] = ['PascalCase']

        if function_names:
            # snake_caseが使われているか確認
            snake_case = sum(1 for name in function_names if '_' in name)
            if snake_case / len(function_names) > 0.6:
                self.conventions['function_naming'] = ['snake_case']

    def generate_cursorrules(self) -> str:
        """
        分析結果から.cursorrulesの内容を生成
        """
        output = ["# Project Coding Rules\n", "## Language and Framework"]

        if self.languages:
            for lang in sorted(self.languages):
                output.append(f"- Use {lang}")

        if self.frameworks:
            for fw in sorted(self.frameworks):
                output.append(f"- Use {fw} for applicable tasks")

        output.append("\n## Code Style")

        if 'Python' in self.languages:
            output.append("- Follow PEP 8 for Python code style")
            output.append("- Use type hints for function signatures")
            output.append("- Maximum line length: 100 characters")

        if self.conventions.get('class_naming'):
            output.append(f"\n## Naming Conventions")
            output.append(f"- Classes: {self.conventions['class_naming'][0]}")

        if self.conventions.get('function_naming'):
            output.append(f"- Functions: {self.conventions['function_naming'][0]}")

        output.append("\n## Error Handling")
        output.append("- Always use appropriate error handling")
        output.append("- Log errors properly")

        output.append("\n## Testing")
        output.append("- Write unit tests for all public functions")
        output.append("- Aim for high code coverage")

        return "\n".join(output)

    def save(self, output_path: str = ".cursorrules"):
        """
        生成した.cursorrulesをファイルに保存
        """
        content = self.generate_cursorrules()
        output_file = self.project_dir / output_path

        with open(output_file, 'w', encoding='utf-8') as f:
            f.write(content)

        print(f".cursorrules generated at {output_file}")

# 使用例
if __name__ == "__main__":
    generator = CursorRulesGenerator(project_dir=".")
    generator.analyze_project()
    generator.save()

このスクリプトは、プロジェクトの依存関係ファイル(requirements.txtpackage.json)とコードファイルを分析し、プロジェクトで使用されている言語、フレームワーク、命名規則を自動検出して.cursorrulesを生成します。

カテゴリ3:エージェント向け — AGENTS.md

AGENTS.mdの役割

AGENTS.mdは、自律的に動作するAIエージェントに対して、プロジェクト固有の行動指針や制約を伝えるためのファイルです。これは、OpenAI Assistants、AutoGPT、LangChainのエージェントなど、複数のステップを経て自律的にタスクを実行するAIシステムに特に有効です。

AGENTS.mdが解決する問題

自律型エージェントは強力ですが、適切な制約がないと予期しない動作をすることがあります。

  • 本番環境のデータベースに直接接続してしまう
  • コストの高いAPIを無制限に呼び出す
  • セキュリティ上重要なファイルを変更する

AGENTS.mdでは、「何をしてよいか」「何をしてはいけないか」を明確に定義します。

AGENTS.mdの書き方

Markdown
# Agent Guidelines for MyProject

## Purpose
This document provides guidelines for AI agents operating within the MyProject codebase.

## Allowed Actions
- Read any file in the `src/` and `tests/` directories
- Create new Python files in `src/` following naming conventions
- Run unit tests using `pytest`
- Query the development database (not production)
- Make API calls to external services with rate limiting (max 10/minute)

## Prohibited Actions
- NEVER modify files in the `migrations/` directory
- NEVER connect to the production database
- NEVER delete files without explicit user confirmation
- NEVER commit directly to the `main` branch
- NEVER expose API keys or credentials in logs or responses

## Code Modification Guidelines
When modifying code:
1. Always run existing tests before making changes
2. Write new tests for new functionality
3. Follow the code style defined in .cursorrules
4. Create a feature branch, never commit to main
5. Add descriptive commit messages

## API Usage
- Development API: `https://api-dev.myproject.com` (OK to use)
- Production API: `https://api.myproject.com` (FORBIDDEN)
- API rate limit: 10 requests per minute
- Always handle API errors gracefully

## Database Access
- Development DB: `postgresql://localhost:5432/myproject_dev` (OK)
- Production DB: NEVER ACCESS DIRECTLY
- Always use ORM (SQLAlchemy) rather than raw SQL
- Wrap database operations in transactions

## Escalation Rules
If uncertain about any action, especially:
- Deleting or renaming existing functions/classes
- Modifying authentication or security code
- Making changes that affect multiple modules
→ ASK the user before proceeding

## Output Format
- Provide clear explanations for all actions taken
- Show diffs for code changes
- List all files modified
- Explain potential side effects

このファイルをリポジトリルートに配置することで、エージェントは自律動作の際にこれらのガイドラインを参照できます。

実装例:AGENTS.mdのバリデータ

エージェントの動作がAGENTS.mdのルールに従っているかをチェックするバリデータを作成できます。

Python
import re
from pathlib import Path
from typing import List, Dict, Tuple

class AgentActionValidator:
    """
    エージェントの動作がAGENTS.mdのルールに従っているかを検証
    """
    def __init__(self, agents_md_path: str = "AGENTS.md"):
        self.rules = self._parse_agents_md(agents_md_path)

    def _parse_agents_md(self, path: str) -> Dict[str, List[str]]:
        """
        AGENTS.mdから許可・禁止ルールを抽出
        """
        rules = {
            'allowed': [],
            'prohibited': []
        }

        try:
            with open(path, 'r', encoding='utf-8') as f:
                content = f.read()

            # 許可されたアクションを抽出
            allowed_section = re.search(
                r'## Allowed Actions\s*\n((?:- .+\n?)+)',
                content,
                re.MULTILINE
            )
            if allowed_section:
                rules['allowed'] = re.findall(r'- (.+)', allowed_section.group(1))

            # 禁止されたアクションを抽出
            prohibited_section = re.search(
                r'## Prohibited Actions\s*\n((?:- .+\n?)+)',
                content,
                re.MULTILINE
            )
            if prohibited_section:
                rules['prohibited'] = re.findall(r'- (?:NEVER )?(.+)', prohibited_section.group(1))

        except FileNotFoundError:
            print(f"Warning: {path} not found")

        return rules

    def validate_action(self, action: str, details: Dict = None) -> Tuple[bool, str]:
        """
        特定のアクションが許可されているかを検証

        Args:
            action: 実行しようとしているアクション
            details: アクションの詳細情報

        Returns:
            (is_valid, message)のタプル
        """
        action_lower = action.lower()
        details = details or {}

        # 禁止ルールのチェック(優先度高)
        for prohibited_rule in self.rules['prohibited']:
            if self._matches_rule(action_lower, prohibited_rule.lower(), details):
                return False, f"Action prohibited by rule: {prohibited_rule}"

        # 許可ルールのチェック
        for allowed_rule in self.rules['allowed']:
            if self._matches_rule(action_lower, allowed_rule.lower(), details):
                return True, "Action allowed"

        # どちらにも該当しない場合は確認を求める
        return None, "Action not explicitly allowed or prohibited. User confirmation recommended."

    def _matches_rule(self, action: str, rule: str, details: Dict) -> bool:
        """
        アクションがルールに一致するかを判定
        """
        # キーワードマッチング
        keywords = re.findall(r'\w+', rule)
        matches = sum(1 for keyword in keywords if keyword in action)

        # 閾値以上のキーワードが一致した場合はマッチとみなす
        if len(keywords) > 0 and matches / len(keywords) > 0.5:
            return True

        # 詳細情報からの判定
        if 'file_path' in details:
            if 'migrations' in rule and 'migrations' in details['file_path']:
                return True
            if 'production' in rule and 'production' in details.get('environment', ''):
                return True

        return False

# 使用例
if __name__ == "__main__":
    validator = AgentActionValidator()

    # テストケース
    test_cases = [
        ("read file in src directory", {'file_path': 'src/main.py'}),
        ("modify migrations file", {'file_path': 'migrations/001_initial.py'}),
        ("connect to production database", {'environment': 'production'}),
        ("run unit tests", {}),
    ]

    for action, details in test_cases:
        is_valid, message = validator.validate_action(action, details)
        status = "" if is_valid else "" if is_valid is False else "?"
        print(f"{status} {action}: {message}")

このバリデータは、エージェントが実行しようとしているアクションをAGENTS.mdのルールと照合し、許可・禁止・要確認のいずれかを判定します。

カテゴリ4:許可制御向け — ai.txtとrobots.txt

ai.txtの登場背景

2024年から2025年にかけて、AIによるWebクローリングとデータ学習の是非が議論されています。多くのWebサイト運営者が「自分のコンテンツをAIの学習に使ってほしくない」と考える一方、明示的にオプトアウトする仕組みが不足していました。

ai.txtは、この問題に対する標準化の試みです。Webサイトのルートディレクトリに配置することで、AIクローラーに対する許可・禁止を明示的に示せます。

ai.txtの書き方

ai.txtの形式はrobots.txtに似ていますが、AI特有の指示を含みます。

Markdown
# ai.txt for MyProject

# AIによる学習を禁止
User-agent: *
Disallow: /

# ただしドキュメントページは許可
User-agent: *
Allow: /docs/

# 特定のAIクローラーのみ許可
User-agent: GPTBot
Allow: /

User-agent: ClaudeBot
Allow: /

# データセット作成を禁止
ai-dataset: disallow

# 商用利用を禁止
ai-commercial: disallow

# 学習は許可するが、著作権表示を要求
ai-attribution: required

robots.txtとの併用

従来のrobots.txtも、AIクローラーの制御に有効です。最近のAIクローラーは独自のUser-agentを持っています。

Markdown
# robots.txt

# OpenAI GPTBot
User-agent: GPTBot
Disallow: /

# Anthropic Claude
User-agent: ClaudeBot
Disallow: /

# Google Bard/Gemini
User-agent: Google-Extended
Disallow: /

# Common Crawl (多くのAIデータセットのソース)
User-agent: CCBot
Disallow: /

なぜAI向けドキュメントが必要なのか

ここまで4つのカテゴリのファイルを紹介しました。これらを導入することで得られる具体的なメリットを整理しましょう。

1. トークン効率の向上

LLMのAPIは、入力トークン数に応じて課金されます。プロジェクトの文脈を毎回プロンプトで説明すると、数百〜数千トークンが消費されます。AI向けドキュメントを使えば、必要な情報をLLMが自動的に参照するため、プロンプトは短く、トークン消費は最小限になります。

例えば、「このプロジェクトはPyTorchを使っています。テストはpytestで書いてください。クラス名はPascalCaseで…」といった指示が不要になります。

2. ハルシネーション(幻覚)の低減

LLMは不確実な情報を「それらしく」生成してしまうことがあります。しかし、プロジェクト固有の正確な情報を明示的に提供すれば、LLMはそれに基づいて回答します。特に、APIの正確なエンドポイント、関数のシグネチャ、設定パラメータなどは、ドキュメントで明示することで正確性が大幅に向上します。

3. 一貫性の担保

チーム開発では、コーディングスタイルやベストプラクティスの統一が重要です。人間の開発者にはコードレビューで指摘できますが、AIアシスタントが生成したコードもチェックが必要です。.cursorrulesAGENTS.mdがあれば、AIは最初から規約に従ったコードを生成するため、レビューの手間が削減されます。

4. オンボーディングの自動化

新しいメンバーがプロジェクトに参加する際、README.mdやCONTRIBUTING.mdを読んで理解する必要があります。AIアシスタントも同様です。適切なAI向けドキュメントがあれば、AIは「新メンバー」として即座にプロジェクトを理解し、初日から生産的なサポートを提供できます。

今日から始められること

ステップ1:まずは.cursorrulesから

最も効果を実感しやすいのは.cursorrulesです。プロジェクトルートに.cursorrulesファイルを作成し、以下の内容から始めましょう。

Markdown
# Basic Project Rules

## Language
- Use Python 3.10+

## Style
- Follow PEP 8
- Use type hints

## Testing
- Use pytest
- Write tests for new features

Cursorを再起動すれば、即座に効果が現れます。

ステップ2:llms.txtでドキュメントを整理

ドキュメントサイトやREADMEが充実しているプロジェクトなら、llms.txtを追加しましょう。手動で作成しても良いですし、前述のPythonスクリプトで自動生成しても構いません。

ステップ3:既存ドキュメントをAI視点で見直す

README.mdCONTRIBUTING.mdは人間向けに書かれています。これらを「AIが読んでも理解できるか」という視点で見直しましょう。

  • 曖昧な表現を避ける(「適宜」「なるべく」→具体的な条件に)
  • 例外ケースを明示する
  • コマンドや設定は完全な形式で記載する

ステップ4:AGENTS.mdで安全性を確保

自律エージェントを使用している、または使用を検討しているなら、AGENTS.mdを作成して安全な動作範囲を定義しましょう。

AI向けドキュメント一覧表

最後に、本記事で紹介したファイルの特徴を一覧表にまとめます。

ファイル名用途対象配置場所形式
llms.txtWebサイト全体の構造をLLMに提供RAGシステム、Webエージェントルートまたは/docs/プレーンテキスト
.cursorrulesIDEのAIアシスタントの動作を制御Cursor, Windsurf等のIDEプロジェクトルートMarkdown
AGENTS.md自律エージェントへの行動指針AutoGPT, LangChain等のエージェントプロジェクトルートMarkdown
ai.txtAIによる学習・クローリングの許可制御AIクローラー全般Webサイトルートプレーンテキスト
robots.txtAIクローラーのアクセス制御(従来型)WebクローラーWebサイトルートプレーンテキスト

まとめ

ソフトウェア開発におけるドキュメントの役割は、「人間が読むもの」から「AIが読むもの」へと拡張されています。llms.txt.cursorrulesAGENTS.mdai.txtといったAI向けドキュメントを適切に配置することで、以下のメリットが得られます。

  • 開発効率の向上:AIアシスタントが即座にプロジェクトを理解し、的確な支援を提供
  • コスト削減:トークン消費の最適化とハルシネーションの低減
  • 品質の向上:一貫したコーディングスタイルと安全な動作の担保
  • スケーラビリティ:新メンバー(人間もAIも)のオンボーディング自動化

2025年現在、これらのファイルはまだ標準化の途上にありますが、Cursor、Windsurf、GitHub Copilotなどの主要ツールは既にこれらをサポートし始めています。今後、「AIフレンドリー」なリポジトリ構造は、オープンソースプロジェクトでも企業の内部プロジェクトでも、デフォルトの標準になっていくでしょう。

まずは小さく始めましょう。.cursorrulesを一つ作るだけでも、日々のコーディング体験は大きく変わります。そして徐々に、プロジェクト全体を「AIが理解しやすい」構造に進化させていく——それが、LLM時代の開発者に求められる新しいスキルセットです。

皆さんのプロジェクトでも、ぜひAI向けドキュメントの導入を検討してみてください。AIとの協働がより効率的で快適になることを保証します。

コメント

タイトルとURLをコピーしました