PHPackages                             nomanur/laravel-markdown-rag - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Parsing &amp; Serialization](/categories/parsing)
4. /
5. nomanur/laravel-markdown-rag

ActiveLibrary[Parsing &amp; Serialization](/categories/parsing)

nomanur/laravel-markdown-rag
============================

Transform Markdown files into AI-ready context with smart chunking and RAG capabilities for Laravel

0.2.5(1mo ago)0108MITPHPPHP ^8.2

Since Mar 2Pushed 1mo agoCompare

[ Source](https://github.com/nomanur/laravel-markdown-rag)[ Packagist](https://packagist.org/packages/nomanur/laravel-markdown-rag)[ Docs](https://github.com/nomanur/laravel-markdown-rag)[ RSS](/packages/nomanur-laravel-markdown-rag/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (10)Versions (26)Used By (0)

Laravel Markdown RAG
====================

[](#laravel-markdown-rag)

[![Latest Version on Packagist](https://camo.githubusercontent.com/2ec2047a8f352045bb2dbe320060fdac0fd35c7e4182afd44568e70698b5e1b6/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6e6f6d616e75722f6c61726176656c2d6d61726b646f776e2d7261672e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/nomanur/laravel-markdown-rag)[![Total Downloads](https://camo.githubusercontent.com/a8bd7a82f9ea47eebfbcbc5f37ffd6959f987586211827c6059d4fe3f35b5979/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6e6f6d616e75722f6c61726176656c2d6d61726b646f776e2d7261672e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/nomanur/laravel-markdown-rag)

Laravel Markdown RAG is a package that allows you to build a Retrieval-Augmented Generation (RAG) system using Markdown files as your knowledge base, powered by Gemini AI.

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require nomanur/laravel-markdown-rag
```

Publish the package assets and configuration:

```
php artisan vendor:publish --provider="Nomanur\LaravelMarkdownRAGServiceProvider"
php artisan vendor:publish --provider="Laravel\Ai\AiServiceProvider"
```

Run the migrations:

```
php artisan migrate
```

Configuration
-------------

[](#configuration)

Add the following environment variables to your `.env` file:

```
GEMINI_API_KEY=
GEMINI_MODEL=gemini-2.5-flash
AI_EMBEDDING_PROVIDER=gemini
AI_DEFAULT_PROVIDER=gemini
MARKDOWN_INFO_PATH=knowledge-base
MARKDOWN_EMBEDDING_BATCH_SIZE=50
MARKDOWN_AI_RETRY_MAX_ATTEMPTS=3
MARKDOWN_QUERY_REWRITE=false
MARKDOWN_RERANKING=false
```

- `MARKDOWN_CHAT_RATE_LIMIT`: 5 (optional) if you want to rate the limit for the chat.
- `MARKDOWN_INFO_PATH`: (optional) the path to the markdown files in the public directory.
- `MARKDOWN_EMBEDDING_BATCH_SIZE`: (optional) the number of chunks to process in a single embedding request (default: 50).
- `MARKDOWN_AI_RETRY_MAX_ATTEMPTS`: (optional) the maximum number of retry attempts for AI requests (default: 3).
- `MARKDOWN_QUERY_REWRITE`: (optional) whether to enable query rewriting for better retrieval (default: false).
- `MARKDOWN_RERANKING`: (optional) whether to enable reranking of search results (default: false).

To use the configuration, update the code in `config/ai.php` with:

```
'default' => env('AI_DEFAULT_PROVIDER', 'ollama'),
'default_for_images' => env('AI_IMAGE_PROVIDER', 'gemini'),
'default_for_audio' => env('AI_AUDIO_PROVIDER', 'openai'),
'default_for_transcription' => env('AI_TRANSCRIPTION_PROVIDER', 'openai'),
'default_for_embeddings' => env('AI_EMBEDDING_PROVIDER', 'openai'),
'default_for_reranking' => env('AI_RERANKING_PROVIDER', 'cohere'),

'providers' => [
    'gemini' => [
        'driver' => 'gemini',
        'key' => env('GEMINI_API_KEY'),
        'models' => [
            'text' => [
                'default' => env('GEMINI_MODEL', 'gemini-1.5-flash'),
                'cheapest' => env('GEMINI_MODEL_CHEAPEST', 'gemini-1.5-flash'),
                'smartest' => env('GEMINI_MODEL_SMARTEST', 'gemini-2.0-pro-exp-02-05'),
            ],
        ],
    ],
],
```

Usage
-----

[](#usage)

### 1. Register Routes

[](#1-register-routes)

Run the following command to register the necessary routes:

```
php artisan markdownrag:route
```

### 2. Setup Knowledge Base

[](#2-setup-knowledge-base)

Create a folder for your markdown files within the `public` directory. By default, this is `public/knowledge-base`, but you can change it using the `MARKDOWN_INFO_PATH` environment variable. Add your `.md` files there.

Example:

```
public/
└── knowledge-base/
    ├── company/
    │   ├── file1.md
    │   ├── file2.md
    │   └── file3.md
    └── product/
        ├── file1.md
        ├── file2.md
        └── file3.md

```

### 3. Indexing

[](#3-indexing)

Index your markdown files to make them searchable:

```
php artisan markdownrag:index
```

### 4. Accessing the Interface

[](#4-accessing-the-interface)

You can access the chat interface at the following URL: `your-domain.com/markdownrag`

### 5. Customizing Message History

[](#5-customizing-message-history)

By default, `KnowledgeAgent` retrieves messages from the `History` model. You can customize how messages are resolved using one of the following options:

#### Option 1: Global override in `AppServiceProvider`

[](#option-1-global-override-in-appserviceprovider)

Use the `resolveMessagesUsing` static method to customize message resolution globally:

```
use Nomanur\Ai\Agents\KnowledgeAgent;
use Nomanur\Models\History;
use Laravel\Ai\Messages\Message;

KnowledgeAgent::resolveMessagesUsing(function ($agent) {
    return History::where('user_id', $agent->user->id)
        ->where('agent', 'knowledge')
        ->latest()
        ->skip(1) // Your custom skip logic
        ->when(config('laravel-markdown-rag.markdown_chat_rate_limit'), fn($query, $limit) => $query->limit($limit))
        ->get()
        ->reverse()
        ->map(fn($message) => new Message($message->role, $message->content))
        ->all();
});
```

#### Option 2: Inheritance in another project

[](#option-2-inheritance-in-another-project)

If you are extending the agent in another project, you can override the `messages()` method directly:

```
use Nomanur\Ai\Agents\KnowledgeAgent;
use Nomanur\Models\History;
use Laravel\Ai\Messages\Message;

class ExtendedKnowledgeAgent extends KnowledgeAgent
{
    public function messages(): iterable
    {
        // Custom implementation with skip(1)
        return History::where('user_id', $this->user->id)
            ->where('agent', 'knowledge')
            ->latest()
            ->skip(1)
            ->when(config('laravel-markdown-rag.markdown_chat_rate_limit'), fn($query, $limit) => $query->limit($limit))
            ->get()
            ->reverse()
            ->map(fn($message) => new Message($message->role, $message->content))
            ->all();
    }
}
```

### 6. Customizing Instructions

[](#6-customizing-instructions)

By default, `KnowledgeAgent` retrieves its instructions from the associated document's `system_prompt` or falls back to a default prompt. You can customize the agent's instructions using one of the following options:

#### Option 1: Global override in `AppServiceProvider`

[](#option-1-global-override-in-appserviceprovider-1)

Use the `resolveInstructionsUsing` static method to customize instructions globally:

```
use Nomanur\Ai\Agents\KnowledgeAgent;

KnowledgeAgent::resolveInstructionsUsing(function (KnowledgeAgent $agent) {
    if ($agent->document) {
        return "You are an expert on {$agent->document->name}. Answer questions strictly based on it.";
    }

    return "You are a helpful AI assistant.";
});
```

#### Option 2: Inheritance in another project

[](#option-2-inheritance-in-another-project-1)

You can also override the `instructions()` method directly by extending the agent:

```
use Nomanur\Ai\Agents\KnowledgeAgent;
use Stringable;

class ExtendedKnowledgeAgent extends KnowledgeAgent
{
    public function instructions(): Stringable|string
    {
        return "You are a highly capable and friendly assistant.";
    }
}
```

### 7. Customizing Tool Descriptions

[](#7-customizing-tool-descriptions)

You can also override the description of the `KnowledgeSearchTool` globally. This is useful if you want to give the AI more specific instructions about when to use the search tool:

```
use Nomanur\Ai\Tools\KnowledgeSearchTool;

KnowledgeSearchTool::resolveDescriptionUsing(function (KnowledgeSearchTool $tool) {
    return "Search the internal knowledge base for company policies and HR documents only.";
});
```

### Testing

[](#testing)

```
composer test
```

### Changelog

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

### Security

[](#security)

If you discover any security related issues, please email  instead of using the issue tracker.

Credits
-------

[](#credits)

- [nomanur rahman](https://github.com/nomanur)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

41

—

FairBetter than 89% of packages

Maintenance89

Actively maintained with recent releases

Popularity14

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

25

Last Release

56d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/8c11c7eb3a08494bec414a2528da1f645eb80999cb0842343f2d870f4766a5ea?d=identicon)[nomanur](/maintainers/nomanur)

---

Top Contributors

[![nomanur](https://avatars.githubusercontent.com/u/29956256?v=4)](https://github.com/nomanur "nomanur (50 commits)")

---

Tags

phplaravelaimarkdownragnomanurlaravel-markdown-rag

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/nomanur-laravel-markdown-rag/health.svg)

```
[![Health](https://phpackages.com/badges/nomanur-laravel-markdown-rag/health.svg)](https://phpackages.com/packages/nomanur-laravel-markdown-rag)
```

###  Alternatives

[sbsaga/toon

🧠 TOON for Laravel — a compact, human-readable, and token-efficient data format for AI prompts &amp; LLM contexts. Perfect for ChatGPT, Gemini, Claude, Mistral, and OpenAI integrations (JSON ⇄ TOON).

6115.6k](/packages/sbsaga-toon)[ultrono/laravel-sitemap

Sitemap generator for Laravel 11, 12 and 13

36412.6k6](/packages/ultrono-laravel-sitemap)[mischasigtermans/laravel-toon

Token-Optimized Object Notation encoder/decoder for Laravel with intelligent nested object handling

13113.1k](/packages/mischasigtermans-laravel-toon)[dniccum/nova-documentation

A Laravel Nova tool that allows you to add markdown-based documentation to your administrator's dashboard.

37116.4k](/packages/dniccum-nova-documentation)[spatie/laravel-markdown-response

Serve markdown versions of your HTML pages to AI agents and bots

6512.6k](/packages/spatie-laravel-markdown-response)[cartalyst/interpret

A driver-based content rendering package, with support for HTML, Markdown &amp; plain text. You can register custom drivers for custom content types.

1914.7k](/packages/cartalyst-interpret)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
