# Langchain

> LangChain Framework

- Skill: `muhammederem/langchain` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add muhammederem/langchain`
- Raw SKILL.md: https://api.skillmd.com/api/skills/muhammederem/langchain/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: muhammederem (https://skillmd.com/u/muhammederem)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/muhammederem/langchain

---

# LangChain Framework

## Overview
LangChain is a framework for developing applications powered by language models. It provides interfaces for LLMs, prompt management, memory, chains, agents, and tools.

## Installation
```bash
pip install langchain langchain-openai langchain-community
pip install chromadb  # For vector store
```

## Core Components

### Language Models
```python
from langchain_openai import ChatOpenAI
from langchain_community.llms import HuggingFacePipeline

# OpenAI
llm = ChatOpenAI(
    model="gpt-4",
    temperature=0.7,
    api_key="your-api-key"
)

# Hugging Face
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
model = AutoModelForCausalLM.from_pretrained("gpt2")
tokenizer = AutoTokenizer.from_pretrained("gpt2")
pipe = pipeline("text-generation", model=model, tokenizer=tokenizer)
llm = HuggingFacePipeline(pipeline=pipe)
```

### Prompts
```python
from langchain.prompts import PromptTemplate, ChatPromptTemplate

# Simple prompt
prompt = PromptTemplate(
    input_variables=["product"],
    template="What is a good name for a company that makes {product}?"
)

# Chat prompt
prompt = ChatPromptTemplate.from_messages([
    ("system", "You are a helpful assistant."),
    ("human", "{input}")
])
```

### Chains
```python
from langchain.chains import LLMChain

# Basic chain
chain = LLMChain(llm=llm, prompt=prompt)
result = chain.run(product="colorful socks")

# Sequential chain
from langchain.chains import SimpleSequentialChain

chain1 = LLMChain(llm=llm, prompt=prompt1)
chain2 = LLMChain(llm=llm, prompt=prompt2)
combined_chain = SimpleSequentialChain(chains=[chain1, chain2])
```

## RAG (Retrieval Augmented Generation)

### Basic RAG Pipeline
```python
from langchain_community.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
from langchain.chains import RetrievalQA

# Load documents
loader = TextLoader("document.txt")
documents = loader.load()

# Split documents
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000,
    chunk_overlap=200
)
splits = text_splitter.split_documents(documents)

# Create vector store
vectorstore = Chroma.from_documents(
    documents=splits,
    embedding=OpenAIEmbeddings()
)

# Create RAG chain
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",
    retriever=retriever
)

# Query
result = qa_chain.run("What is the document about?")
```

### Custom RAG with Prompts
```python
from langchain.prompts import PromptTemplate

prompt_template = """
Use the following pieces of context to answer the question at the end.
If you don't know the answer, just say that you don't know, don't try to make up an answer.

Context: {context}

Question: {question}

Answer:
"""

PROMPT = PromptTemplate(
    template=prompt_template,
    input_variables=["context", "question"]
)

qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",
    retriever=retriever,
    chain_type_kwargs={"prompt": PROMPT}
)
```

## Memory

### Conversation Memory
```python
from langchain.memory import ConversationBufferMemory

memory = ConversationBufferMemory()

memory.save_context({"input": "Hi"}, {"output": "Hello"})
memory.load_memory_variables({})
```

### Memory in Chains
```python
from langchain.chains import ConversationChain

conversation = ConversationChain(
    llm=llm,
    memory=ConversationBufferMemory()
)

response = conversation.run("Hi, I'm John")
response = conversation.run("What's my name?")
```

### Memory Types
- **ConversationBufferMemory**: Stores all conversation history
- **ConversationBufferWindowMemory**: Keeps last k exchanges
- **ConversationSummaryMemory**: Summarizes conversation
- **ConversationKGMemory**: Uses knowledge graph

## Agents

### ReAct Agent
```python
from langchain.agents import AgentExecutor, create_openai_functions_agent
from langchain.tools import Tool
from langchain_openai import ChatOpenAI

# Define tools
def calculator(input_str):
    return eval(input_str)

tools = [
    Tool(
        name="Calculator",
        func=calculator,
        description="Useful for math calculations"
    )
]

# Create agent
llm = ChatOpenAI(model="gpt-4")
agent = create_openai_functions_agent(llm, tools, prompt)

# Create executor
agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    verbose=True
)

# Run
result = agent_executor.invoke({"input": "What is 2 + 2?"})
```

### Custom Tools
```python
from langchain.tools import StructuredTool
from pydantic import BaseModel, Field

class SearchInput(BaseModel):
    query: str = Field(description="Search query")

def search_func(query: str) -> str:
    # Implement search
    return f"Results for {query}"

search_tool = StructuredTool.from_function(
    func=search_func,
    name="Search",
    description="Search the web",
    args_schema=SearchInput
)
```

## Document Loaders

### Common Loaders
```python
from langchain_community.document_loaders import (
    TextLoader,
    PyPDFLoader,
    WebBaseLoader,
    GitHubLoader,
    YoutubeLoader
)

# Text
loader = TextLoader("file.txt")

# PDF
loader = PyPDFLoader("document.pdf")

# Web
loader = WebBaseLoader("https://example.com")

# GitHub
loader = GitHubLoader(
    repo="username/repo",
    branch="main",
    folder_path="src"
)

# YouTube
loader = YoutubeLoader.from_youtube_url(
    "https://youtube.com/watch?v=xxx",
    add_video_info=True
)
```

### Custom Loader
```python
from langchain.schema import Document

class CustomLoader:
    def load(self) -> list[Document]:
        # Load data
        data = self._fetch_data()

        # Convert to documents
        documents = [
            Document(page_content=item["text"], metadata=item["meta"])
            for item in data
        ]
        return documents
```

## Text Splitters

### Character Text Splitter
```python
from langchain.text_splitter import CharacterTextSplitter

splitter = CharacterTextSplitter(
    separator="\n\n",
    chunk_size=1000,
    chunk_overlap=200,
    length_function=len
)
```

### Recursive Character Splitter
```python
from langchain.text_splitter import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000,
    chunk_overlap=200,
    separators=["\n\n", "\n", " ", ""]
)
```

### Code Splitter
```python
from langchain.text_splitter import RecursiveCharacterTextSplitter, Language

splitter = RecursiveCharacterTextSplitter.from_language(
    language=Language.PYTHON,
    chunk_size=1000,
    chunk_overlap=200
)
```

## Vector Stores

### Pinecone
```python
from langchain_community.vectorstores import Pinecone
from langchain_openai import OpenAIEmbeddings

vectorstore = Pinecone.from_documents(
    documents=documents,
    embedding=OpenAIEmbeddings(),
    index_name="my-index"
)
```

### ChromaDB
```python
from langchain_community.vectorstores import Chroma

vectorstore = Chroma.from_documents(
    documents=documents,
    embedding=OpenAIEmbeddings(),
    persist_directory="./chroma_db"
)
```

### Weaviate
```python
from langchain_community.vectorstores import Weaviate

vectorstore = Weaviate.from_documents(
    documents=documents,
    embedding=OpenAIEmbeddings(),
    index_name="MyIndex"
)
```

## Output Parsers

### Structured Output
```python
from langchain.output_parsers import StructuredOutputParser, ResponseSchema
from langchain.prompts import PromptTemplate

# Define schema
schemas = [
    ResponseSchema(name="name", description="The person's name"),
    ResponseSchema(name="age", description="The person's age")
]

output_parser = StructuredOutputParser.from_response_schemas(schemas)

# Use in prompt
format_instructions = output_parser.get_format_instructions()
prompt = PromptTemplate(
    template="Answer the user question.\n{format_instructions}\n{question}",
    input_variables=["question"],
    partial_variables={"format_instructions": format_instructions}
)
```

## Best Practices

### 1. Prompt Engineering
- Be specific and clear
- Provide examples (few-shot)
- Use appropriate delimiters
- Specify output format

### 2. Chain Design
- Keep chains simple and focused
- Use appropriate chain type
- Handle errors gracefully
- Add validation

### 3. RAG Optimization
- Chunk size: 500-1500 tokens
- Overlap: 10-20% of chunk size
- Use appropriate embeddings
- Tune retrieval (k value, search type)

### 4. Agent Design
- Provide clear tool descriptions
- Limit tool set to essentials
- Add error handling
- Monitor and log agent actions

### 5. Performance
- Cache embeddings
- Use batch processing
- Stream responses for long text
- Optimize vector store queries

## Integration

- **Vector Databases**: Pinecone, Weaviate, Qdrant, Chroma
- **LLMs**: OpenAI, Anthropic, Hugging Face, Cohere
- **Tools**: Web search, databases, APIs, file systems
- **Deployment**: FastAPI, Streamlit, AWS Lambda

