Skip to main content
PraisonAI auto-discovers per-project instruction files (AGENTS.md, CLAUDE.md, .praisonai/rules/*.md) and injects them into every agent run — CLI and direct Agent(...) from Python. Opt out with rules=False when you need a sandboxed / reproducible run. The user works in a repo with instruction files; the agent discovers them and injects the rules into the system prompt on every run.

How It Works

Supported Instruction Files

PraisonAI automatically loads these files from your project root and git root:
FileDescriptionPriority
PRAISON.mdPraisonAI native instructionsHigh (500)
PRAISON.local.mdLocal overrides (gitignored)Higher (600)
CLAUDE.mdClaude Code memory fileHigh (500)
CLAUDE.local.mdLocal overrides (gitignored)Higher (600)
AGENTS.mdOpenAI Codex CLI instructionsHigh (500)
GEMINI.mdGemini CLI memory fileHigh (500)
.cursorrulesCursor IDE rules (legacy)High (500)
.windsurfrulesWindsurf IDE rules (legacy)High (500)
.claude/rules/*.mdClaude Code modular rulesMedium (50)
.windsurf/rules/*.mdWindsurf modular rulesMedium (50)
.cursor/rules/*.mdcCursor modular rulesMedium (50)
.praisonai/rules/*.mdWorkspace rulesMedium (0)
~/.praisonai/rules/*.mdGlobal modular rulesLow (-1000)
~/.praisonai/AGENTS.mdGlobal single-file instructionsLowest (loaded by load_context_files())
~/.praisonai/AGENTS.md is the global single-file layer used by load_context_files(). It is separate from the modular ~/.praisonai/rules/*.md files managed by RulesManager and has the lowest precedence — project-level files always override it.
Local Override Files: CLAUDE.local.md and PRAISON.local.md are personal overrides that should be gitignored. They have higher priority than the main files, allowing you to customize rules without affecting the shared project configuration.

Quick Start

1

Simple

Drop an instruction file in your project — the agent picks it up automatically.
from praisonaiagents import Agent

agent = Agent(
    name="Assistant",
    instructions="You help users with Python.",
    rules=True,          # same as omitting — auto-discover + apply
)
agent.start("Sort a list of dicts by the 'priority' key.")
2

With Configuration

Use RulesConfig when you need a character budget, extra rule files, or a different workspace root.
from praisonaiagents import Agent, RulesConfig

agent = Agent(
    name="Assistant",
    instructions="You help users with Python.",
    rules=RulesConfig(
        char_budget=6000,
        files=["docs/CONVENTIONS.md"],
    ),
)
agent.start("Refactor this module in line with our conventions.")
Opt out: pass rules=False for sandboxed / reproducible runs where project files must not leak into the prompt.
from praisonaiagents import Agent

agent = Agent(name="Sandbox", instructions="You are helpful.", rules=False)
agent.start("Explain closures.")

Precedence

rules= climbs the ladder from simplest to most explicit — Bool then RulesConfig — with rules=False as a standalone opt-out.
You passWhat happens
Nothing (omit rules=)Auto-discover and apply if files exist
rules=NoneSame as omitting — auto-discover and apply
rules=TrueSame as above — auto-discover and apply
rules=RulesConfig(...)Full control (custom budget / files / workspace)
rules=FalseOff — no discovery, no injection, sandboxed run

CLI Usage

Project instruction files are auto-injected into praisonai run, chat, and code — no Python required.
# 1. Create an instruction file in your project
echo "Always use type hints" > AGENTS.md

# 2. Run any CLI command — instructions load automatically
praisonai run "Help me with Python"

Rule File Format

Rules support YAML frontmatter for advanced configuration:
# Project Guidelines

- Always use type hints for functions
- Follow PEP 8 style guide
- Write docstrings for public APIs
- Prefer async when possible
---
description: Python coding guidelines
globs: ["**/*.py", "**/*.pyx"]
activation: always
priority: 10
---

# Python Guidelines

- Use type hints for all functions
- Follow PEP 8 style guide
- Write docstrings for public APIs
- Prefer composition over inheritance
---
description: Testing guidelines
globs: ["**/*.test.*", "**/test_*.py", "**/*_test.py"]
activation: glob
priority: 20
---

# Testing Guidelines

- Use pytest for all tests
- Aim for 80% code coverage
- Mock external dependencies
- Use fixtures for common setup
---
description: Security review checklist
activation: manual
priority: 100
---

# Security Checklist

- [ ] Validate all user inputs
- [ ] Use parameterized queries
- [ ] Implement rate limiting
- [ ] Check for SQL injection
- [ ] Verify authentication

Activation Modes

ModeDescriptionUse Case
alwaysAlways applied (default)General guidelines
globApplied when file matches patternLanguage-specific rules
manualOnly via @mentionSecurity checklists, special procedures
ai_decisionAI decides when to applyContext-dependent rules

Configuration (RulesConfig)

Pass a RulesConfig when you need more than the default zero-config behaviour.
from praisonaiagents import Agent, RulesConfig

agent = Agent(
    name="Assistant",
    instructions="You are helpful.",
    rules=RulesConfig(
        char_budget=6000,
        files=["docs/CONVENTIONS.md"],
        workspace_path="/path/to/project",
    ),
)
agent.start("Summarise the project conventions.")
OptionTypeDefaultDescription
char_budgetOptional[int]NoneCharacter budget for injected rules context. None = RulesManager default.
filesOptional[List[str]]NoneExtra instruction file paths / globs registered with high priority beyond auto-discovery.
workspace_pathOptional[str]NoneWorkspace path override. Defaults to os.getcwd().
Discovery gate: the first time the agent runs, the workspace is scanned; if no instruction file is found, the RulesManager is dropped and every later run pays zero cost. Extra files are registered before the gate, so a workspace whose only rules are explicit files=[...] is never dropped. Programmatic equivalent: call RulesManager.add_rule_file(path) — the same machinery RulesConfig(files=[...]) uses under the hood.

Choose an option

@Import Syntax (like Claude Code)

Include other files in your rules using the @path/to/file syntax:
# CLAUDE.md
See @README for project overview
See @docs/architecture.md for system design

# Additional Instructions
- Follow the patterns in @src/examples/
# CLAUDE.md
# Import personal preferences from home directory
@~/.praisonai/my-preferences.md

# Project-specific rules
- Use TypeScript for all new code
# .praisonai/rules/python.md
# Import shared guidelines
@./shared/code-style.md

# Python-specific additions
- Use type hints
- Follow PEP 8
Import Depth Limit: Imports are limited to 5 levels deep to prevent circular dependencies. Code spans like `@org/package` are not treated as imports.

Git Root Discovery

PraisonAI automatically discovers rules from the git repository root, enabling monorepo support:
monorepo/                    # Git root
├── .git/
├── CLAUDE.md               # Discovered for all subdirs
├── .praisonai/rules/       # Discovered for all subdirs
├── packages/
│   ├── frontend/
│   │   ├── CLAUDE.md       # Higher priority for frontend
│   │   └── .praisonai/rules/
│   └── backend/
│       └── CLAUDE.md       # Higher priority for backend
Rules closer to the current working directory have higher priority than rules at the git root. The wrapper-layer load_context_files() (used by configure_host / context_paths) uses the same git-root walk-up and adds layered merge semantics — collecting AGENTS.md, CLAUDE.md, agents.md, and .agents/AGENTS.md at every directory level from ~/.praisonai/AGENTS.md (lowest) up through the git root to cwd (highest). See Context Files → CLI auto-loading for how chat, run, code, and tui automatically inject this context into the agent system prompt. Monorepos with per-subtree instruction files: see On-demand Subtree Attachment for how a sibling package’s AGENTS.md attaches the moment the agent opens a file inside it.

Storage Structure

project/
├── CLAUDE.md              # Auto-loaded (Claude Code compatible)
├── CLAUDE.local.md        # Local overrides (gitignored)
├── AGENTS.md              # Auto-loaded (Codex CLI compatible)
├── GEMINI.md              # Auto-loaded (Gemini CLI compatible)
├── PRAISON.md             # Auto-loaded (PraisonAI native)
├── PRAISON.local.md       # Local overrides (gitignored)
├── .cursorrules           # Auto-loaded (Cursor legacy)
├── .windsurfrules         # Auto-loaded (Windsurf legacy)
├── .claude/
│   └── rules/             # Claude Code modular rules
│       ├── code-style.md
│       └── testing.md
├── .windsurf/
│   └── rules/             # Windsurf modular rules
├── .cursor/
│   └── rules/             # Cursor modular rules
├── .praisonai/
│   ├── rules/             # Workspace rules
│   │   ├── python.md      # globs: ["**/*.py"]
│   │   ├── testing.md     # globs: ["**/*.test.*"]
│   │   └── security.md    # activation: manual
│   ├── workflows/         # Reusable workflows
│   └── hooks.json         # Pre/post operation hooks
└── ~/.praisonai/
    └── rules/             # Global rules (all projects)
        └── global.md

Security & Path Safety

Enhanced in PR #1597: MCP praisonai.rules.* tools now validate rule_name against path traversal attacks.
The praisonai.rules.show, create, and delete MCP tools validate rule names to prevent path traversal: Rejected inputs:
  • Contains /, \, or \x00 (NUL byte)
  • Starts with . (blocks hidden files and ..)
  • Equals . or ..
  • The resolved path escapes ~/.praisonai/rules/ (symlink-safe)
Allowed pattern: Single filename with alphanumerics, underscores, hyphens, and dots (not leading), located strictly inside ~/.praisonai/rules/. Error format: Error: invalid rule_name: '<value>'

Programmatic Rules Management

from praisonaiagents.memory import RulesManager

# Create manager for your workspace
rules = RulesManager(workspace_path="/path/to/project")

# Get all loaded rules
all_rules = rules.get_all_rules()
for rule in all_rules:
    print(f"{rule.name}: {rule.description} (priority: {rule.priority})")

# Get active rules (always + ai_decision)
active = rules.get_active_rules()

# Get rules for a specific file (includes glob matches)
python_rules = rules.get_rules_for_file("src/main.py")

# Get a specific rule by name (for @mention)
security_rule = rules.get_rule_by_name("security")

# Build context string for LLM
context = rules.build_rules_context(
    file_path="src/main.py",
    include_manual=["security"]  # Include manual rules via @mention
)

# Register extra instruction files beyond auto-discovery.
# Accepts a concrete path OR a glob; each match wins over auto-discovered
# rules via a +200 priority bump. Returns the number of files added.
added = rules.add_rule_file("docs/CONVENTIONS.md")            # concrete path
added = rules.add_rule_file(".praisonai/team-rules/*.md")     # glob

Creating Rules Programmatically

from praisonaiagents.memory import RulesManager

rules = RulesManager(workspace_path="/path/to/project")

# Create a new rule
rules.create_rule(
    name="api_guidelines",
    content="""# API Guidelines
- Use RESTful conventions
- Version all endpoints
- Return proper status codes
- Document with OpenAPI
""",
    description="REST API development guidelines",
    globs=["**/api/**/*.py", "**/routes/**/*.py"],
    activation="glob",
    priority=15,
    scope="workspace"  # or "global"
)

# Delete a rule
rules.delete_rule("old_rule")

# Reload rules from disk
rules.reload()

# Get statistics
stats = rules.get_stats()
print(stats)
# {
#   'total_rules': 8,
#   'always_rules': 3,
#   'glob_rules': 2,
#   'manual_rules': 1,
#   'ai_decision_rules': 2,
#   'root_rules': 3,
#   'gitroot_rules': 1,
#   'workspace_rules': 2,
#   'claude_rules': 1,
#   'windsurf_rules': 1,
#   'global_rules': 0,
#   'sources': {'root': 3, 'workspace': 2, 'claude': 1, ...}
# }

AI Decision Activation

For ai_decision rules, PraisonAI can use an LLM to decide if a rule should be applied:
from praisonaiagents.memory import RulesManager

rules = RulesManager(workspace_path="/path/to/project")

# Get an ai_decision rule
rule = rules.get_rule_by_name("security")

# Evaluate if it should be applied to current context
def llm_func(prompt):
    return agent.chat(prompt)

should_apply = rules.evaluate_ai_decision(
    rule=rule,
    context="User is asking about database queries",
    llm_func=llm_func
)

if should_apply:
    print("Security rule should be applied")
Without an LLM function, ai_decision rules default to being included. This ensures rules are not accidentally skipped.

Agent Integration

Rules are auto-applied on every .start() / .chat() / .run() call — no manual wiring needed.
from praisonaiagents import Agent, RulesConfig

# Default: auto-discover + apply (equivalent to rules=True or omitting the param)
agent = Agent(name="Coder", instructions="Help with code")

# Opt out for a reproducible sandbox run
sandbox = Agent(name="Sandbox", rules=False)

# Full control
strict = Agent(
    name="Strict",
    rules=RulesConfig(char_budget=4000, files=["docs/CONVENTIONS.md"]),
)

Inspect what was loaded

from praisonaiagents import Agent

agent = Agent(name="Assistant", instructions="You are helpful.")
agent.start("hello")   # triggers discovery on first run

if agent.rules_manager:
    stats = agent.rules_manager.get_stats()
    print(f"Loaded {stats['total_rules']} rules from {list(stats['sources'].keys())}")

    # Preview the exact string injected into the system prompt
    context = agent.get_rules_context(
        file_path="src/main.py",
        include_manual=["security"]
    )
    print(context)

CLI Integration

Project instruction files are auto-injected into praisonai run, praisonai chat, and praisonai code runs — no Python required.

CLI flags

FlagEffect
(default)Auto-inject all discovered instruction files
--no-rulesSkip auto-injection for this run
--include-rules <names>Force-include named rules (comma-separated)
--include-rules autoExplicitly enable auto (same as default)
--verbosePrint loaded files: Loaded project instructions: AGENTS.md, CLAUDE.md

Configuration

Global opt-out via ~/.praisonai/config.toml:
[rules]
auto = false        # Disable everywhere
max_chars = 16000   # Or shrink the budget
See CLI Config for the full TOML reference.

Cross-Tool Compatibility

PraisonAI rules are compatible with other AI coding assistants:
ToolFileCompatibility
Claude CodeCLAUDE.md✅ Full
Codex CLIAGENTS.md✅ Full
Gemini CLIGEMINI.md✅ Full
Cursor.cursorrules, .cursor/rules/*.mdc✅ Partial
Windsurf.windsurfrules, .windsurf/rules/*.md✅ Partial
PraisonAI reads the same instruction files used by other AI coding assistants, making it easy to switch between tools while maintaining consistent behavior.

Best Practices

Create a PRAISON.md file in your project root with guidelines specific to your project. This file is automatically loaded with high priority.
Put language-specific rules in .praisonai/rules/ with appropriate glob patterns. For example, python.md with globs: ["**/*.py"].
Security checklists, deployment procedures, and other special rules should use activation: manual and be invoked via @mention when needed.
Use higher priority (50+) for critical rules that should override others. Default priority is 0 for workspace rules, -1000 for global rules.
Rules are injected into the system prompt, consuming context window. Keep rules focused and concise to leave room for conversation.

Context Files

CLI auto-loading of AGENTS.md and CLAUDE.md

Hooks

Pre/post operation hooks for custom actions