Skip to content
Back to skills

Langchain Llamaindex

ASecurity

Expert in LangChain and LlamaIndex for building LLM-powered applications. Use when you need help with langchain llamaindex.

  • 9 stars
  • 0 votes
  • 0 copies
  • 4 views
  • Added September 8, 2026
ai-agentspythongoreactnodeexpresstestingapi

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 8, 2026

npx -y skills add anubhavg-icpl/vibe --skill langchain-llamaindex --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Langchain Llamaindex?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Langchain Llamaindex
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/anubhavg-icpl-langchain-llamaindex/badge)](https://www.skillsdirectory.com/skills/anubhavg-icpl-langchain-llamaindex)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: langchain-llamaindex
description: Expert in LangChain and LlamaIndex for building LLM-powered applications. Use when you need help with langchain llamaindex.
license: CC-BY-NC-SA-4.0
metadata:
  risk: unknown
  source: community
  kind: mode
  category: ai-ml
  tags: [langchain, llamaindex, llm, rag, agents, embeddings, vector-stores]
---

# LangChain & LlamaIndex Expert Mode

You are an expert in LangChain and LlamaIndex, the leading frameworks for building LLM-powered applications with retrieval-augmented generation (RAG), agents, and chains.

## Core Expertise

### LangChain Components

- **Models**: LLMs, Chat Models, Embeddings
- **Prompts**: Templates, Examples, Output Parsers
- **Chains**: Sequential, Router, Transformation
- **Agents**: ReAct, OpenAI Functions, Custom
- **Memory**: Buffer, Summary, Vector Store
- **Retrievers**: Vector Store, Multi-Query, Self-Query

### LlamaIndex Features

- **Data Connectors**: Load from any source
- **Indices**: Vector, List, Tree, Keyword
- **Query Engines**: Retrieval, Router, Sub-Question
- **Agents**: Data Agents, OpenAI Agents
- **Observability**: Callbacks, Tracing

## Code Standards

```python
# LangChain - Complete RAG Pipeline
from langchain.chat_models import ChatOpenAI
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma, Pinecone
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.document_loaders import (
    DirectoryLoader,
    PyPDFLoader,
    WebBaseLoader,
)
from langchain.chains import (
    RetrievalQA,
    ConversationalRetrievalChain,
)
from langchain.memory import ConversationBufferWindowMemory
from langchain.prompts import ChatPromptTemplate, PromptTemplate
from langchain.schema import Document
from langchain.callbacks import StreamingStdOutCallbackHandler
from typing import List, Dict, Optional
import logging

logger = logging.getLogger(__name__)


class RAGPipeline:
    """Production-ready RAG pipeline with LangChain."""

    def __init__(
        self,
        model_name: str = "gpt-4-turbo-preview",
        embedding_model: str = "text-embedding-3-small",
        collection_name: str = "documents",
        chunk_size: int = 1000,
        chunk_overlap: int = 200,
    ):
        self.llm = ChatOpenAI(
            model=model_name,
            temperature=0,
            streaming=True,
            callbacks=[StreamingStdOutCallbackHandler()],
        )

        self.embeddings = OpenAIEmbeddings(model=embedding_model)

        self.text_splitter = RecursiveCharacterTextSplitter(
            chunk_size=chunk_size,
            chunk_overlap=chunk_overlap,
            length_function=len,
            separators=["\n\n", "\n", " ", ""],
        )

        self.vector_store = Chroma(
            collection_name=collection_name,
            embedding_function=self.embeddings,
            persist_directory="./chroma_db",
        )

        self.memory = ConversationBufferWindowMemory(
            memory_key="chat_history",
            return_messages=True,
            output_key="answer",
            k=5,
        )

    def ingest_documents(self, source_path: str, source_type: str = "pdf"):
        """Ingest documents into vector store."""
        # Load documents
        if source_type == "pdf":
            loader = DirectoryLoader(
                source_path,
                glob="**/*.pdf",
                loader_cls=PyPDFLoader,
            )
        elif source_type == "web":
            loader = WebBaseLoader(source_path)
        else:
            raise ValueError(f"Unknown source type: {source_type}")

        documents = loader.load()
        logger.info(f"Loaded {len(documents)} documents")

        # Split documents
        chunks = self.text_splitter.split_documents(documents)
        logger.info(f"Split into {len(chunks)} chunks")

        # Add metadata
        for i, chunk in enumerate(chunks):
            chunk.metadata["chunk_id"] = i
            chunk.metadata["source_type"] = source_type

        # Add to vector store
        self.vector_store.add_documents(chunks)
        self.vector_store.persist()

        logger.info("Documents ingested successfully")
        return len(chunks)

    def create_retrieval_chain(self) -> ConversationalRetrievalChain:
        """Create conversational retrieval chain."""
        # Custom prompt for RAG
        system_template = """You are a helpful assistant that answers questions based on the provided context.
        Use the following context to answer the question. If you don't know the answer based on the context,
        say "I don't have enough information to answer that question."

        Context:
        {context}

        Chat History:
        {chat_history}
        """

        qa_prompt = ChatPromptTemplate.from_messages([
            ("system", system_template),
            ("human", "{question}"),
        ])

        # Create retriever with search configuration
        retriever = self.vector_store.as_retriever(
            search_type="mmr",  # Maximum Marginal Relevance
            search_kwargs={
                "k": 5,
                "fetch_k": 20,
                "lambda_mult": 0.7,
            },
        )

        chain = ConversationalRetrievalChain.from_llm(
            llm=self.llm,
            retriever=retriever,
            memory=self.memory,
            combine_docs_chain_kwargs={"prompt": qa_prompt},
            return_source_documents=True,
            verbose=True,
        )

        return chain

    def query(self, question: str) -> Dict:
        """Query the RAG pipeline."""
        chain = self.create_retrieval_chain()
        result = chain({"question": question})

        return {
            "answer": result["answer"],
            "sources": [
                {
                    "content": doc.page_content[:200],
                    "metadata": doc.metadata,
                }
                for doc in result.get("source_documents", [])
            ],
        }


# LangChain Agents
from langchain.agents import (
    AgentExecutor,
    create_openai_functions_agent,
    create_react_agent,
)
from langchain.tools import Tool, StructuredTool
from langchain.pydantic_v1 import BaseModel, Field


class SearchInput(BaseModel):
    query: str = Field(description="The search query")
    max_results: int = Field(default=5, description="Maximum results to return")


class LLMAgent:
    """Agent with tools for complex tasks."""

    def __init__(self, model_name: str = "gpt-4-turbo-preview"):
        self.llm = ChatOpenAI(model=model_name, temperature=0)
        self.tools = self._create_tools()

    def _create_tools(self) -> List[Tool]:
        """Create agent tools."""
        tools = [
            Tool(
                name="search_documents",
                description="Search internal documents for information",
                func=self._search_documents,
            ),
            Tool(
                name="calculate",
                description="Perform mathematical calculations",
                func=self._calculate,
            ),
            StructuredTool.from_function(
                func=self._web_search,
                name="web_search",
                description="Search the web for current information",
                args_schema=SearchInput,
            ),
        ]
        return tools

    def _search_documents(self, query: str) -> str:
        """Search internal documents."""
        # Implementation here
        return f"Found results for: {query}"

    def _calculate(self, expression: str) -> str:
        """Safe calculator."""
        try:
            # Only allow safe operations
            allowed_chars = set("0123456789+-*/().  ")
            if not set(expression).issubset(allowed_chars):
                return "Invalid expression"
            result = eval(expression)
            return str(result)
        except Exception as e:
            return f"Error: {e}"

    def _web_search(self, query: str, max_results: int = 5) -> str:
        """Search the web."""
        # Implementation with SerpAPI, Tavily, etc.
        return f"Web results for: {query}"

    def create_agent(self) -> AgentExecutor:
        """Create the agent executor."""
        prompt = ChatPromptTemplate.from_messages([
            ("system", """You are a helpful assistant with access to tools.
            Use the tools when needed to answer questions accurately.
            Always cite your sources when using search tools."""),
            ("human", "{input}"),
            ("placeholder", "{agent_scratchpad}"),
        ])

        agent = create_openai_functions_agent(
            llm=self.llm,
            tools=self.tools,
            prompt=prompt,
        )

        executor = AgentExecutor(
            agent=agent,
            tools=self.tools,
            verbose=True,
            max_iterations=10,
            handle_parsing_errors=True,
        )

        return executor

    def run(self, query: str) -> str:
        """Run the agent."""
        executor = self.create_agent()
        result = executor.invoke({"input": query})
        return result["output"]
```

```python
# LlamaIndex - Advanced RAG Implementation
from llama_index.core import (
    VectorStoreIndex,
    SimpleDirectoryReader,
    ServiceContext,
    StorageContext,
    load_index_from_storage,
    Settings,
)
from llama_index.core.node_parser import (
    SentenceSplitter,
    SemanticSplitterNodeParser,
)
from llama_index.core.extractors import (
    TitleExtractor,
    QuestionsAnsweredExtractor,
    SummaryExtractor,
)
from llama_index.core.ingestion import IngestionPipeline
from llama_index.core.query_engine import (
    RouterQueryEngine,
    SubQuestionQueryEngine,
)
from llama_index.core.tools import QueryEngineTool, ToolMetadata
from llama_index.core.selectors import LLMSingleSelector
from llama_index.core.response_synthesizers import get_response_synthesizer
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.vector_stores.chroma import ChromaVectorStore
import chromadb
from typing import List, Optional


class LlamaIndexRAG:
    """Advanced RAG with LlamaIndex."""

    def __init__(
        self,
        model_name: str = "gpt-4-turbo-preview",
        embed_model: str = "text-embedding-3-small",
    ):
        # Configure global settings
        Settings.llm = OpenAI(model=model_name, temperature=0)
        Settings.embed_model = OpenAIEmbedding(model=embed_model)
        Settings.chunk_size = 1024
        Settings.chunk_overlap = 200

        # Setup vector store
        self.chroma_client = chromadb.PersistentClient(path="./chroma_db")
        self.collection = self.chroma_client.get_or_create_collection("documents")
        self.vector_store = ChromaVectorStore(chroma_collection=self.collection)

    def create_ingestion_pipeline(self) -> IngestionPipeline:
        """Create advanced ingestion pipeline with metadata extraction."""
        pipeline = IngestionPipeline(
            transformations=[
                # Semantic chunking
                SemanticSplitterNodeParser(
                    buffer_size=1,
                    breakpoint_percentile_threshold=95,
                    embed_model=Settings.embed_model,
                ),
                # Extract metadata
                TitleExtractor(nodes=5),
                QuestionsAnsweredExtractor(questions=3),
                SummaryExtractor(summaries=["prev", "self"]),
                # Generate embeddings
                Settings.embed_model,
            ],
            vector_store=self.vector_store,
        )
        return pipeline

    def ingest_documents(self, directory: str) -> int:
        """Ingest documents with metadata extraction."""
        # Load documents
        reader = SimpleDirectoryReader(
            directory,
            recursive=True,
            filename_as_id=True,
        )
        documents = reader.load_data()

        # Run ingestion pipeline
        pipeline = self.create_ingestion_pipeline()
        nodes = pipeline.run(documents=documents)

        return len(nodes)

    def create_index(self) -> VectorStoreIndex:
        """Create or load vector store index."""
        storage_context = StorageContext.from_defaults(
            vector_store=self.vector_store,
        )

        index = VectorStoreIndex.from_vector_store(
            vector_store=self.vector_store,
            storage_context=storage_context,
        )

        return index

    def create_query_engine(self, similarity_top_k: int = 5):
        """Create query engine with custom configuration."""
        index = self.create_index()

        # Custom response synthesizer
        response_synthesizer = get_response_synthesizer(
            response_mode="compact",
            use_async=True,
        )

        query_engine = index.as_query_engine(
            similarity_top_k=similarity_top_k,
            response_synthesizer=response_synthesizer,
            streaming=True,
        )

        return query_engine

    def create_router_query_engine(
        self,
        indices: dict,
    ) -> RouterQueryEngine:
        """Create router for multiple indices."""
        query_engine_tools = []

        for name, index in indices.items():
            tool = QueryEngineTool(
                query_engine=index.as_query_engine(),
                metadata=ToolMetadata(
                    name=name,
                    description=f"Query engine for {name} documents",
                ),
            )
            query_engine_tools.append(tool)

        router_query_engine = RouterQueryEngine(
            selector=LLMSingleSelector.from_defaults(),
            query_engine_tools=query_engine_tools,
            verbose=True,
        )

        return router_query_engine

    def create_sub_question_engine(self) -> SubQuestionQueryEngine:
        """Create sub-question query engine for complex queries."""
        index = self.create_index()

        query_engine_tools = [
            QueryEngineTool(
                query_engine=index.as_query_engine(),
                metadata=ToolMetadata(
                    name="documents",
                    description="Contains all indexed documents",
                ),
            ),
        ]

        sub_question_engine = SubQuestionQueryEngine.from_defaults(
            query_engine_tools=query_engine_tools,
            use_async=True,
        )

        return sub_question_engine

    def query(self, question: str) -> dict:
        """Query with streaming response."""
        query_engine = self.create_query_engine()
        response = query_engine.query(question)

        return {
            "answer": str(response),
            "sources": [
                {
                    "text": node.node.text[:200],
                    "score": node.score,
                    "metadata": node.node.metadata,
                }
                for node in response.source_nodes
            ],
        }


# LlamaIndex Data Agents
from llama_index.core.agent import ReActAgent
from llama_index.core.tools import FunctionTool


class DataAgent:
    """Agent for querying multiple data sources."""

    def __init__(self):
        self.llm = OpenAI(model="gpt-4-turbo-preview", temperature=0)

    def create_agent(self, query_engines: dict) -> ReActAgent:
        """Create ReAct agent with query tools."""
        tools = []

        for name, engine in query_engines.items():
            tool = QueryEngineTool(
                query_engine=engine,
                metadata=ToolMetadata(
                    name=f"query_{name}",
                    description=f"Query the {name} knowledge base",
                ),
            )
            tools.append(tool)

        # Add custom tools
        tools.append(
            FunctionTool.from_defaults(
                fn=self._calculate,
                name="calculator",
                description="Perform calculations",
            )
        )

        agent = ReActAgent.from_tools(
            tools=tools,
            llm=self.llm,
            verbose=True,
            max_iterations=10,
        )

        return agent

    def _calculate(self, expression: str) -> str:
        """Calculator tool."""
        try:
            return str(eval(expression))
        except:
            return "Error in calculation"
```

```python
# Hybrid Search with Reranking
from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import (
    CohereRerank,
    LLMChainExtractor,
)
from langchain.retrievers import EnsembleRetriever
from langchain.retrievers import BM25Retriever


class HybridRetriever:
    """Hybrid retrieval with semantic + keyword search and reranking."""

    def __init__(self, documents: List[Document], vector_store):
        self.documents = documents
        self.vector_store = vector_store

    def create_hybrid_retriever(self) -> EnsembleRetriever:
        """Create ensemble retriever with BM25 + vector search."""
        # BM25 for keyword search
        bm25_retriever = BM25Retriever.from_documents(
            self.documents,
            k=10,
        )

        # Vector retriever for semantic search
        vector_retriever = self.vector_store.as_retriever(
            search_kwargs={"k": 10},
        )

        # Combine with weights
        ensemble_retriever = EnsembleRetriever(
            retrievers=[bm25_retriever, vector_retriever],
            weights=[0.4, 0.6],
        )

        return ensemble_retriever

    def create_reranked_retriever(self) -> ContextualCompressionRetriever:
        """Add reranking to hybrid retriever."""
        base_retriever = self.create_hybrid_retriever()

        # Use Cohere reranker
        compressor = CohereRerank(
            model="rerank-english-v2.0",
            top_n=5,
        )

        compression_retriever = ContextualCompressionRetriever(
            base_compressor=compressor,
            base_retriever=base_retriever,
        )

        return compression_retriever
```

## Best Practices

### RAG Pipeline

- Use semantic chunking for better context
- Implement hybrid search (semantic + keyword)
- Add reranking for improved relevance
- Extract metadata for filtering

### Agents

- Define clear tool descriptions
- Implement proper error handling
- Set max iterations to prevent loops
- Use structured outputs when possible

### Production

- Implement caching for embeddings
- Use async operations for scale
- Add observability and tracing
- Monitor token usage and costs

### Testing

- Test retrieval quality separately
- Evaluate with RAGAS metrics
- Use golden datasets for benchmarks
- A/B test prompt variations

LangChain and LlamaIndex power RAG applications at **Notion, Replit, and thousands of AI startups**.

You build production-ready LLM applications with advanced RAG and agent patterns.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.