<?php
require_once "admin/config.php";
require_once "admin/includes/track_visitor.php";
trackVisitor($conn);

$anchorify = static function (string $text): string {
    $text = html_entity_decode(strip_tags($text), ENT_QUOTES | ENT_HTML5, 'UTF-8');
    $text = strtolower($text);
    $text = preg_replace('/[^a-z0-9]+/i', '-', $text);
    $text = trim((string) $text, '-');
    return $text !== '' ? $text : 'section';
};

$pageTitle = "Md Bazlur Rahman Likhon | Best RAG Framework Comparison";
$pageDesc = "Compare LangChain, LlamaIndex, and Haystack for production RAG delivery across orchestration flexibility, retrieval quality controls, and operational complexity.";
$pageCanonical = "https://brlikhon.engineer/rag-framework-comparison";
$pageImage = "https://brlikhon.engineer/image/profile.png";
$pageKeywords = "LangChain vs LlamaIndex, Haystack comparison, RAG framework selection";
$breadcrumbs = [['name' => 'Comparison Hub', 'url' => 'https://brlikhon.engineer/comparisons'], ['name' => 'RAG Framework Comparison', 'url' => 'https://brlikhon.engineer/rag-framework-comparison']];
$skipHomepageFAQ = true;

$faqItems = [
    ['q' => 'Which framework is best for fast MVP delivery?', 'a' => 'LangChain is frequently chosen for fast MVP iteration due to ecosystem breadth and orchestration flexibility. Teams should still validate observability and maintenance costs before scaling.'],
    ['q' => 'When is LlamaIndex the better option?', 'a' => 'LlamaIndex is often strong when retrieval and data connector depth are the primary challenge, especially for document-heavy workflows that need cleaner indexing and retrieval abstractions.'],
    ['q' => 'Why choose Haystack for enterprise deployments?', 'a' => 'Haystack is attractive for enterprise teams that prioritize modular retrieval pipelines, clear component boundaries, and production-grade search integration with explicit control over ranking and evaluation.'],
    ['q' => 'Can teams mix frameworks in one architecture?', 'a' => 'Yes. It is common to combine components, such as using one framework for retrieval pipelines and another for orchestration. The key is standardized observability and interface contracts.']
];

$articleSchema = [
    '@context' => 'https://schema.org',
    '@type' => 'TechArticle',
    'headline' => 'LangChain vs LlamaIndex vs Haystack: RAG Framework Comparison',
    'description' => $pageDesc,
    'url' => $pageCanonical,
    'datePublished' => date('Y-m-d'),
    'dateModified' => date('Y-m-d'),
    'author' => [
        '@type' => 'Person',
        '@id' => 'https://brlikhon.engineer/#person',
        'name' => 'Md Bazlur Rahman Likhon'
    ],
    'publisher' => [
        '@id' => 'https://brlikhon.engineer/#organization'
    ],
    'about' => [
        ['@type' => 'Thing', 'name' => 'RAG Systems'],
        ['@type' => 'Thing', 'name' => 'Framework Selection']
    ]
];

$faqSchema = [
    '@context' => 'https://schema.org',
    '@type' => 'FAQPage',
    'mainEntity' => array_map(static function ($item) {
        return [
            '@type' => 'Question',
            'name' => $item['q'],
            'acceptedAnswer' => ['@type' => 'Answer', 'text' => $item['a']]
        ];
    }, $faqItems)
];

// Comparison schema — RAG frameworks.
$compSchemaItems = [
    [
        'name'    => 'LangChain',
        'url'     => 'https://www.langchain.com/',
        'sameAs'  => ['https://en.wikipedia.org/wiki/LangChain', 'https://pypi.org/project/langchain/'],
        'tagline' => 'Broadest RAG/LLM orchestration framework with LangGraph and LangSmith',
        'description' => 'LangChain — the largest and most flexible RAG framework, with LangGraph for stateful agents and LangSmith for production observability.',
        'applicationSubCategory' => 'RAG Framework',
        'datePublished' => '2022-10-01',
    ],
    [
        'name'    => 'LlamaIndex',
        'url'     => 'https://www.llamaindex.ai/',
        'sameAs'  => ['https://en.wikipedia.org/wiki/LlamaIndex', 'https://pypi.org/project/llama-index/'],
        'tagline' => 'Data connector + retrieval abstractions for document-heavy workflows',
        'description' => 'LlamaIndex — focused on ingestion, indexing, and retrieval for documents-heavy RAG pipelines, with the cleanest data connector library.',
        'applicationSubCategory' => 'RAG Framework',
        'datePublished' => '2022-11-01',
    ],
    [
        'name'    => 'Haystack (deepset)',
        'url'     => 'https://haystack.deepset.ai/',
        'sameAs'  => ['https://github.com/deepset-ai/haystack'],
        'tagline' => 'Modular pipelines for production-grade search and RAG systems',
        'description' => 'Haystack by deepset — production-grade modular RAG/QA pipelines with first-class support for hybrid retrieval, ranking, and evaluation.',
        'applicationSubCategory' => 'RAG Framework',
        'datePublished' => '2021-01-01',
    ],
];

$compSchemaAbout = ['@type' => 'Thing', 'name' => 'RAG Frameworks'];
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <?php include 'includes/seo_head.php'; ?>
    <script type="application/ld+json"><?php echo json_encode($articleSchema, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_QUOT | JSON_HEX_APOS); ?></script>
    <?php include 'includes/comparison_schema.php'; ?>
    <script type="application/ld+json"><?php echo json_encode($faqSchema, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_QUOT | JSON_HEX_APOS); ?></script>
    <link rel="stylesheet" href="/css/style.css?v=18.0">
    <link rel="stylesheet" href="/css/prisma-noir.css?v=1.2">
    <link rel="stylesheet" href="/css/responsive-polish.css?v=1.0">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" media="print" onload="this.media='all'">
    <noscript><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css"></noscript>
    <meta name="theme-color" content="#030509">
</head>
<body class="pn-page">
<?php include 'includes/header.php'; ?>

<main>
    <section class="pn-hero">
        <div class="pn-container">
            <div class="pn-hero__content" style="max-width: 800px; margin: 0 auto; text-align: center;">
                <span class="pn-badge"><i class="fas fa-diagram-project"></i> RAG Framework Guide</span>
                <h1 class="pn-display pn-display--lg" style="margin: 24px 0">LangChain vs LlamaIndex vs <span class="pn-gradient-text">Haystack</span></h1>
                <p class="pn-hero__subtitle" style="margin: 0 auto 36px;">A production-focused comparison to help teams choose a framework that balances speed, retrieval quality, observability, and long-term maintainability.</p>
                
                <div class="pn-btn-group" style="justify-content:center;">
                    <a href="/comparisons" class="pn-btn pn-btn--primary"><i class="fas fa-scale-balanced"></i> All Comparisons</a>
                    <a href="/rag-system-developer" class="pn-btn pn-btn--ghost"><i class="fas fa-database"></i> RAG Delivery Services</a>
                </div>
            </div>
        </div>
    </section>

    <section class="pn-section pn-section--surface">
        <div class="pn-container">
            <div class="pn-card pn-reveal" style="max-width: 980px; margin: 0 auto; border-color: var(--pn-accent);">
                <h2 class="pn-heading pn-heading--md" style="margin:0 0 16px"><i class="fas fa-lightbulb" style="color: var(--pn-gold)"></i> Key Takeaways</h2>
                <ul class="pn-text" style="margin:0; padding-left:1.5rem; display: grid; gap: 12px;">
                    <li><strong>Choose the framework your team can own</strong> (observability, evaluation, and maintenance).</li>
                    <li><strong>Retrieval evaluation beats prompt tweaks</strong>—measure chunking, ranking, and recall early.</li>
                    <li><strong>Start simple</strong>, then add routing/agents only when metrics justify it.</li>
                </ul>
            </div>
        </div>
    </section>

    <section class="pn-section pn-section--void">
        <div class="pn-container">
            <div class="pn-section-header pn-reveal">
                <span class="pn-label">Comparison</span>
                <h2 class="pn-display pn-display--md">Selection Matrix</h2>
                <p>Use this table to shortlist architecture candidates before prototyping and evaluation testing.</p>
            </div>
            
            <div class="pn-reveal" style="overflow-x: auto; margin-bottom: 80px;">
                <table style="width: 100%; border-collapse: collapse; border-radius: 16px; overflow: hidden; background: rgba(255, 255, 255, 0.03);">
                    <thead>
                        <tr>
                            <th style="border: 1px solid rgba(255, 255, 255, 0.1); padding: 16px 20px; text-align: left; font-size: 0.95rem; background: rgba(232, 184, 91, 0.08); color: #ffffff; font-family: var(--pn-font-display);">Evaluation Dimension</th>
                            <th style="border: 1px solid rgba(255, 255, 255, 0.1); padding: 16px 20px; text-align: left; font-size: 0.95rem; background: rgba(232, 184, 91, 0.08); color: #ffffff; font-family: var(--pn-font-display);">LangChain</th>
                            <th style="border: 1px solid rgba(255, 255, 255, 0.1); padding: 16px 20px; text-align: left; font-size: 0.95rem; background: rgba(232, 184, 91, 0.08); color: #ffffff; font-family: var(--pn-font-display);">LlamaIndex</th>
                            <th style="border: 1px solid rgba(255, 255, 255, 0.1); padding: 16px 20px; text-align: left; font-size: 0.95rem; background: rgba(232, 184, 91, 0.08); color: #ffffff; font-family: var(--pn-font-display);">Haystack</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td style="border: 1px solid rgba(255, 255, 255, 0.1); padding: 16px 20px; color: var(--pn-text-secondary); line-height: 1.6; font-size: 0.95rem;"><strong>Best fit</strong></td>
                            <td style="border: 1px solid rgba(255, 255, 255, 0.1); padding: 16px 20px; color: var(--pn-text-secondary); line-height: 1.6; font-size: 0.95rem;">Rapid orchestration and broad agent ecosystem experiments</td>
                            <td style="border: 1px solid rgba(255, 255, 255, 0.1); padding: 16px 20px; color: var(--pn-text-secondary); line-height: 1.6; font-size: 0.95rem;">Retrieval-centric document workflows and indexing abstractions</td>
                            <td style="border: 1px solid rgba(255, 255, 255, 0.1); padding: 16px 20px; color: var(--pn-text-secondary); line-height: 1.6; font-size: 0.95rem;">Enterprise search pipelines with modular retrieval components</td>
                        </tr>
                        <tr>
                            <td style="border: 1px solid rgba(255, 255, 255, 0.1); padding: 16px 20px; color: var(--pn-text-secondary); line-height: 1.6; font-size: 0.95rem;"><strong>Learning curve</strong></td>
                            <td style="border: 1px solid rgba(255, 255, 255, 0.1); padding: 16px 20px; color: var(--pn-text-secondary); line-height: 1.6; font-size: 0.95rem;">Moderate. Fast start, but architecture discipline is needed at scale</td>
                            <td style="border: 1px solid rgba(255, 255, 255, 0.1); padding: 16px 20px; color: var(--pn-text-secondary); line-height: 1.6; font-size: 0.95rem;">Moderate. Clear retrieval focus but still requires tuning depth</td>
                            <td style="border: 1px solid rgba(255, 255, 255, 0.1); padding: 16px 20px; color: var(--pn-text-secondary); line-height: 1.6; font-size: 0.95rem;">Moderate to high depending on pipeline sophistication</td>
                        </tr>
                        <tr>
                            <td style="border: 1px solid rgba(255, 255, 255, 0.1); padding: 16px 20px; color: var(--pn-text-secondary); line-height: 1.6; font-size: 0.95rem;"><strong>Operational maturity focus</strong></td>
                            <td style="border: 1px solid rgba(255, 255, 255, 0.1); padding: 16px 20px; color: var(--pn-text-secondary); line-height: 1.6; font-size: 0.95rem;">Strong ecosystem breadth with evolving production patterns</td>
                            <td style="border: 1px solid rgba(255, 255, 255, 0.1); padding: 16px 20px; color: var(--pn-text-secondary); line-height: 1.6; font-size: 0.95rem;">Strong retrieval primitives with practical connector options</td>
                            <td style="border: 1px solid rgba(255, 255, 255, 0.1); padding: 16px 20px; color: var(--pn-text-secondary); line-height: 1.6; font-size: 0.95rem;">Strong pipeline modularity and controlled enterprise integration</td>
                        </tr>
                        <tr>
                            <td style="border: 1px solid rgba(255, 255, 255, 0.1); padding: 16px 20px; color: var(--pn-text-secondary); line-height: 1.6; font-size: 0.95rem;"><strong>Where teams struggle</strong></td>
                            <td style="border: 1px solid rgba(255, 255, 255, 0.1); padding: 16px 20px; color: var(--pn-text-secondary); line-height: 1.6; font-size: 0.95rem;">Over-complex chain graphs and prompt dependency sprawl</td>
                            <td style="border: 1px solid rgba(255, 255, 255, 0.1); padding: 16px 20px; color: var(--pn-text-secondary); line-height: 1.6; font-size: 0.95rem;">Insufficient retrieval evaluation before launch</td>
                            <td style="border: 1px solid rgba(255, 255, 255, 0.1); padding: 16px 20px; color: var(--pn-text-secondary); line-height: 1.6; font-size: 0.95rem;">Longer setup cycles if requirements are unclear</td>
                        </tr>
                        <tr>
                            <td style="border: 1px solid rgba(255, 255, 255, 0.1); padding: 16px 20px; color: var(--pn-text-secondary); line-height: 1.6; font-size: 0.95rem;"><strong>Recommended adoption path</strong></td>
                            <td style="border: 1px solid rgba(255, 255, 255, 0.1); padding: 16px 20px; color: var(--pn-text-secondary); line-height: 1.6; font-size: 0.95rem;">Start simple, measure rigorously, then evolve to router patterns</td>
                            <td style="border: 1px solid rgba(255, 255, 255, 0.1); padding: 16px 20px; color: var(--pn-text-secondary); line-height: 1.6; font-size: 0.95rem;">Prioritize chunking and retrieval quality benchmarks first</td>
                            <td style="border: 1px solid rgba(255, 255, 255, 0.1); padding: 16px 20px; color: var(--pn-text-secondary); line-height: 1.6; font-size: 0.95rem;">Design pipeline ownership and observability from day one</td>
                        </tr>
                    </tbody>
                </table>
            </div>

            <div class="pn-section-header pn-reveal">
                <span class="pn-label">FAQ</span>
                <h2 class="pn-display pn-display--md">Frequently Asked Questions</h2>
                <p>Framework decisions should be evidence-driven. Start with these high-impact questions.</p>
            </div>
            
            <div class="pn-faq pn-reveal">
                <?php foreach ($faqItems as $item): ?>
                    <?php $qid = $anchorify((string) $item['q']); ?>
                    <div class="pn-faq__item" id="<?php echo htmlspecialchars($qid, ENT_QUOTES, 'UTF-8'); ?>" itemscope itemtype="https://schema.org/Question">
                        <button class="pn-faq__question">
                            <span itemprop="name"><?php echo htmlspecialchars($item['q'], ENT_QUOTES, 'UTF-8'); ?></span>
                            <a href="#<?php echo htmlspecialchars($qid, ENT_QUOTES, 'UTF-8'); ?>" aria-label="Copy link to this question" style="margin-left:auto;text-decoration:none;color:var(--pn-text-muted);padding:0 8px; font-size: 0.85rem;"><i class="fas fa-link" aria-hidden="true"></i></a>
                            <i class="fas fa-chevron-down"></i>
                        </button>
                        <div class="pn-faq__answer" itemscope itemprop="acceptedAnswer" itemtype="https://schema.org/Answer">
                            <p itemprop="text"><?php echo htmlspecialchars($item['a'], ENT_QUOTES, 'UTF-8'); ?></p>
                        </div>
                    </div>
                <?php endforeach; ?>
            </div>

            <hr class="pn-rule" style="margin: 80px 0;">

            <div class="pn-grid pn-grid--2">
                <a href="/faqs" class="pn-card pn-reveal" style="text-decoration: none; display: block;">
                    <div class="pn-card__icon"><i class="fas fa-circle-question"></i></div>
                    <h3 class="pn-card__title">FAQ Hub</h3>
                    <p class="pn-card__text">Implementation and delivery questions (RAG, governance, ROI).</p>
                </a>
                <a href="/glossary" class="pn-card pn-reveal" style="text-decoration: none; display: block;">
                    <div class="pn-card__icon"><i class="fas fa-book-open"></i></div>
                    <h3 class="pn-card__title">Glossary</h3>
                    <p class="pn-card__text">Shared definitions used across these comparison pages.</p>
                </a>
            </div>
        </div>
    </section>
</main>

<?php include 'includes/footer.php'; ?>
<script>
document.addEventListener('DOMContentLoaded',function(){
    document.querySelectorAll('.pn-reveal').forEach(el=>{el.style.opacity=1;el.style.transform='translateY(0)';});
    
    document.querySelectorAll('.pn-faq__question').forEach(btn=>{
        btn.addEventListener('click',(e)=>{
            if(e.target.closest('a')) return;
            const item=btn.parentElement;
            const answer=item.querySelector('.pn-faq__answer');
            const icon=btn.querySelector('.fa-chevron-down');
            document.querySelectorAll('.pn-faq__item').forEach(other=>{
                if(other!==item){
                    other.querySelector('.pn-faq__answer').style.maxHeight='0';
                    const otherIcon = other.querySelector('.fa-chevron-down');
                    if(otherIcon) otherIcon.style.transform='rotate(0)';
                }
            });
            const isOpen=answer.style.maxHeight&&answer.style.maxHeight!=='0px';
            answer.style.maxHeight=isOpen?'0':answer.scrollHeight+'px';
            if(icon) icon.style.transform=isOpen?'rotate(0)':'rotate(180deg)';
        });
    });
});
</script>
</body>
</html>
