Generative AI Guide
Overview of Generative AI, LLMs, LangChain, RAG, and agents. Treat demos as demos until you add eval and monitoring.
Table of Contents
- Introduction to Generative AI
- Large Language Models (LLMs)
- Capabilities & Limitations
- Prompt Engineering
- LangChain & LangGraph
- AI Agents
- Vector Databases
- RAG (Retrieval-Augmented Generation)
- Multi-Agent Systems
- Building Generative AI Apps
- Resources
Introduction to Generative AI
What is Generative AI?
Generative AI refers to models that create new content rather than just analyzing or classifying existing data.
Core Idea: Learn data patterns → Generate similar outputs
Key Characteristics:
- Creates new, original content
- Learns from training data patterns
- Generates text, images, code, audio, video, etc.
- Uses advanced neural network architectures
Examples of Generative AI
Text Generation:
- ChatGPT (OpenAI): Conversational AI
- Gemini (Google): Multimodal AI
- Claude (Anthropic): Helpful AI assistant
- Mistral - Open-source LLM
Image Generation:
- DALL·E (OpenAI): Text-to-image
- Midjourney - Artistic image generation
- Stable Diffusion - Open-source image generation
Code Generation:
- GitHub Copilot - Code completion
- CodeT5 - Code generation models
Audio Generation:
- MusicLM - Music generation
- ElevenLabs - Voice synthesis
How Generative AI Works
Two Main Approaches:
Large Language Models (LLMs):
- Trained on massive text datasets
- Predict next word/token in sequence
- Examples: GPT, Gemini, Claude
Diffusion Models:
- Generate images by iteratively denoising
- Start with noise, gradually refine to image
- Examples: DALL·E, Midjourney, Stable Diffusion
Training Process:
Massive Dataset → Neural Network Training → Learned Patterns → Generate New Content
Large Language Models (LLMs)
What are LLMs?
Large Language Models (LLMs) are AI systems trained on massive amounts of text data to understand and generate human-like text.
Key Characteristics:
- Trained on billions/trillions of tokens
- Predict the next word/token in a sequence
- Understand context and relationships
- Generate coherent, contextually relevant text
Popular LLMs
Open-Source:
- Llama 2/3 (Meta): Open-source, powerful
- Mistral - Efficient, open-source
- Falcon - High-performance open model
- MosaicML - Training infrastructure
Commercial:
- GPT-4 (OpenAI): Most capable, multimodal
- Gemini (Google): Multimodal, large context
- Claude (Anthropic): Helpful, safe AI
- GPT-3.5 (OpenAI): Fast, cost-effective
Key Concepts
Tokenization
Convert words into numerical form that models can process.
Process:
Text → Tokens → Numerical IDs → Model Input
Example:
# Text
"Hello, how are you?"
# Tokens (simplified)
["Hello", ",", " how", " are", " you", "?"]
# Numerical IDs
[15496, 11, 389, 527, 499, 30]
Tokenization Methods:
- Word-level: Each word is a token
- Subword-level: Words split into parts (BPE, SentencePiece)
- Character-level: Each character is a token
Python Example:
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("gpt2")
text = "Hello, how are you?"
tokens = tokenizer.encode(text)
print(tokens) # [15496, 11, 389, 527, 499, 30]
# Decode back
decoded = tokenizer.decode(tokens)
print(decoded) # "Hello, how are you?"
Embeddings
Vector representation of meaning. Captures semantic relationships.
What Embeddings Do:
- Convert text to numerical vectors
- Similar words have similar vectors
- Capture semantic meaning
- Enable similarity search
Example:
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('all-MiniLM-L6-v2')
# Generate embeddings
text1 = "machine learning"
text2 = "artificial intelligence"
text3 = "cooking recipes"
emb1 = model.encode(text1)
emb2 = model.encode(text2)
emb3 = model.encode(text3)
# Calculate similarity
from sklearn.metrics.pairwise import cosine_similarity
similarity_12 = cosine_similarity([emb1], [emb2])[0][0] # High (related)
similarity_13 = cosine_similarity([emb1], [emb3])[0][0] # Low (unrelated)
print(f"ML vs AI: {similarity_12:.3f}") # ~0.75
print(f"ML vs Cooking: {similarity_13:.3f}") # ~0.15
Embedding Dimensions:
- Small models: 128-384 dimensions
- Medium models: 512-768 dimensions
- Large models: 1024-4096 dimensions
Transformers
Neural network architecture that uses self-attention for context understanding.
Key Components:
- Self-Attention: Weighs importance of different words
- Multi-Head Attention: Multiple attention mechanisms
- Feed-Forward Networks: Process attended information
- Layer Normalization: Stabilizes training
How Self-Attention Works:
For each word, compute attention to all other words:
- Query (Q): What am I looking for?
- Key (K): What do I offer?
- Value (V): What information do I contain?
Attention = softmax(Q × K^T / √d) × V
Why Transformers?
- Understand long-range dependencies
- Parallel processing (faster training)
- Better context understanding
- Strong performance on many public benchmarks (task-dependent)
Capabilities & Limitations
What LLMs Can Do
Text Generation:
- Creative writing
- Code generation
- Content creation
- Storytelling
Summarization:
- Long documents → concise summaries
- Meeting notes → key points
- Articles → bullet points
Question Answering:
- Answer questions based on knowledge
- Explain concepts
- Provide information
Translation:
- Translate between languages
- Preserve context and meaning
Code Writing:
- Generate code from descriptions
- Debug code
- Explain code functionality
Conversation:
- Chatbots
- Virtual assistants
- Customer support
Limitations
Hallucination:
- May generate incorrect information
- Can make up facts that sound plausible
- Not always factually accurate
Training Data Bias:
- Reflects biases in training data
- May perpetuate stereotypes
- Can be unfair or discriminatory
No Real-World Understanding:
- Doesn't truly "understand" like humans
- Statistical pattern matching
- No real-world experience
Context Limitations:
- Limited context window (though improving)
- May forget earlier parts of long conversations
- Token limits
Outdated Information:
- Training data has cutoff date
- Doesn't know recent events
- May provide outdated information
Cost:
- API calls can be expensive
- Large models require significant compute
- Scaling can be costly
Mitigation Strategies:
- Use RAG for up-to-date information
- Fine-tune for specific domains
- Implement fact-checking
- Use human-in-the-loop validation
Prompt Engineering
What is Prompt Engineering?
Prompt Engineering is the art and science of crafting effective prompts (instructions) to get the best results from Large Language Models (LLMs).
Why It Matters:
- Better Results: Well-crafted prompts produce more accurate, relevant outputs
- Cost Efficiency: Fewer API calls needed when prompts work well
- Consistency: Reliable outputs for production applications
- Control: Guide model behavior and style
Core Principle: LLMs are instruction-following systems. The quality of your instructions directly impacts the quality of outputs.
Understanding Language Models
How LLMs Work:
- Pattern Matching: Trained on vast text data to predict next tokens
- Context Understanding: Use surrounding text to understand meaning
- Statistical Generation: Generate text based on learned patterns
- No True Understanding: They don't "know" facts, they predict likely continuations
Implications for Prompting:
- Be explicit and clear
- Provide context
- Use examples when helpful
- Structure prompts logically
Prompt Engineering Mindset
Key Principles:
Clarity Over Cleverness
- Clear, direct instructions work better than clever tricks
- Be explicit about what you want
Iterative Refinement
- Start simple, then refine
- Test and improve based on results
- Document what works
Context is King
- Provide relevant background
- Include necessary information
- Set the right tone and style
Think Like the Model
- Consider how the model processes your prompt
- Structure information logically
- Use formatting that helps parsing
Best Practices
1. Be Specific and Clear
# Bad: Vague prompt
prompt = "Write about AI"
# Good: Specific prompt
prompt = """
Write a 300-word article about artificial intelligence for a general audience.
Focus on:
- What AI is in simple terms
- Common applications people encounter daily
- Future potential and concerns
Use a friendly, accessible tone.
"""
2. Use Role-Playing
# Set a role for the model
prompt = """
You are an expert data scientist with 10 years of experience in machine learning.
Explain gradient descent as if you're teaching a beginner, using simple analogies.
Keep it under 200 words.
"""
3. Structure with Formatting
# Use clear structure
prompt = """
Task: Summarize the following article
Article:
{article_text}
Requirements:
- Length: 3-5 sentences
- Include main points
- Use professional tone
- Avoid personal opinions
Summary:
"""
4. Provide Examples (Few-Shot Learning)
# Zero-shot (no examples)
prompt = "Classify this sentiment: 'I love this product!'"
# Few-shot (with examples)
prompt = """
Classify the sentiment of these texts:
Text: "This is amazing!"
Sentiment: Positive
Text: "I hate waiting."
Sentiment: Negative
Text: "It's okay, nothing special."
Sentiment: Neutral
Text: "I love this product!"
Sentiment:
"""
5. Use Step-by-Step Instructions
prompt = """
Analyze this code for potential bugs. Follow these steps:
Step 1: Identify the function's purpose
Step 2: Check for syntax errors
Step 3: Look for logic errors
Step 4: Check edge cases
Step 5: Suggest improvements
Code:
{code}
"""
6. Set Constraints and Boundaries
prompt = """
Write a product description for a smartphone.
Constraints:
- Maximum 150 words
- Focus on key features only
- Use professional marketing tone
- Avoid technical jargon
- Include: battery life, camera quality, display
Product: {product_name}
"""
7. Use Delimiters for Clarity
prompt = """
<context>
You are a helpful coding assistant. You help developers write clean, efficient code.
</context>
<task>
Explain the following Python concept: {concept}
</task>
<requirements>
- Use code examples
- Explain in simple terms
- Include common use cases
</requirements>
<output_format>
1. Definition
2. Code Example
3. Explanation
4. Use Cases
</output_format>
"""
Zero-Shot vs Few-Shot Prompting
Zero-Shot Prompting:
- No examples provided
- Model relies on pre-training knowledge
- Good for general tasks
- Faster and simpler
# Zero-shot
prompt = "Translate this to French: Hello, how are you?"
Few-Shot Prompting:
- Provide examples in the prompt
- Helps model understand pattern
- Better for specific formats or styles
- More tokens used
# Few-shot
prompt = """
Translate English to French:
English: Hello
French: Bonjour
English: Good morning
French: Bonjour
English: How are you?
French: Comment allez-vous?
English: Thank you
French:
"""
When to Use Each:
- Zero-shot: General tasks, simple instructions
- Few-shot: Complex patterns, specific formats, style transfer
Handling AI Hallucinations
What are Hallucinations?
- Model generates plausible-sounding but incorrect information
- Makes up facts, citations, or details
- Can be very convincing
Why They Happen:
- Model predicts likely text, not verified facts
- Training data may contain errors
- No real-world knowledge verification
Mitigation Strategies:
1. Request Citations
prompt = """
Answer the question and cite your sources.
Question: {question}
Format:
Answer: [your answer]
Sources: [list sources or state if you're not certain]
"""
2. Ask for Confidence Levels
prompt = """
Answer the question and indicate your confidence level.
Question: {question}
Format:
Answer: [your answer]
Confidence: High/Medium/Low
Reason: [why you're confident or uncertain]
"""
3. Request Fact-Checking
prompt = """
Answer the question, then fact-check your answer.
Question: {question}
Format:
Initial Answer: [your answer]
Fact-Check: [verify if information is accurate]
Verified Answer: [corrected answer if needed]
"""
4. Use RAG for Grounded Responses
# Combine with RAG for fact-based answers
prompt = """
Use the following context to answer the question.
If the context doesn't contain the answer, say "I don't have enough information."
Context: {retrieved_context}
Question: {question}
Answer:
"""
Understanding Vectors and Text Embeddings
What are Embeddings?
- Dense vector representations of text
- Capture semantic meaning
- Similar texts have similar vectors
- Enable semantic search
How They Work:
from openai import OpenAI
import numpy as np
client = OpenAI()
# Generate embeddings
text1 = "Machine learning is a subset of AI"
text2 = "AI includes machine learning techniques"
text3 = "The weather is sunny today"
# Get embeddings
embedding1 = client.embeddings.create(
input=text1,
model="text-embedding-3-small"
).data[0].embedding
embedding2 = client.embeddings.create(
input=text2,
model="text-embedding-3-small"
).data[0].embedding
embedding3 = client.embeddings.create(
input=text3,
model="text-embedding-3-small"
).data[0].embedding
# Calculate similarity (cosine similarity)
def cosine_similarity(a, b):
return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
# Similar texts have high similarity
similarity_1_2 = cosine_similarity(embedding1, embedding2) # High (~0.8-0.9)
similarity_1_3 = cosine_similarity(embedding1, embedding3) # Low (~0.1-0.2)
Applications:
- Semantic Search: Find similar documents
- Clustering: Group similar texts
- Recommendations: Find similar content
- RAG: Retrieve relevant context
Advanced Prompting Techniques
1. Chain-of-Thought (CoT) Prompting
# Encourage step-by-step reasoning
prompt = """
Solve this math problem step by step.
Problem: If a train travels 120 miles in 2 hours, how fast is it going?
Let's think through this step by step:
1. First, identify what we know
2. Then, identify what we need to find
3. Finally, apply the formula
Solution:
"""
2. Self-Consistency
# Ask model to verify its own answer
prompt = """
Answer the question, then check if your answer makes sense.
Question: {question}
Format:
Initial Answer: [your answer]
Verification: [check if answer is logical]
Final Answer: [verified answer]
"""
3. Iterative Refinement
# Refine based on feedback
prompt_v1 = "Write a blog post about Python"
# Get output, then refine:
prompt_v2 = """
Write a blog post about Python for beginners.
The previous version was too technical. Make it more accessible.
Focus on why Python is good for beginners, not advanced features.
"""
4. Template-Based Prompting
# Create reusable templates
PROMPT_TEMPLATE = """
You are a {role} helping with {task}.
Context: {context}
Task: {specific_task}
Requirements:
{requirements}
Output Format: {format}
"""
# Use template
prompt = PROMPT_TEMPLATE.format(
role="data analyst",
task="data analysis",
context="Sales data for Q4",
specific_task="Identify top 3 products by revenue",
requirements="- Use exact numbers\n- Include percentages\n- Provide insights",
format="Bullet points"
)
5. Prompt Chaining
# Break complex tasks into steps
step1_prompt = "Extract key facts from this article: {article}"
# Use step1 output in step2
step2_prompt = "Based on these facts: {facts}, write a summary"
# Use step2 output in step3
step3_prompt = "Review this summary for accuracy: {summary}"
Prompt Engineering for Different Tasks
1. Text Classification
prompt = """
Classify the sentiment of this review as Positive, Negative, or Neutral.
Review: "{review_text}"
Consider:
- Overall tone
- Specific complaints or praises
- Emotional language
Sentiment:
"""
2. Text Summarization
prompt = """
Summarize the following article in 3-5 bullet points.
Article:
{article}
Requirements:
- Capture main ideas
- Use concise language
- Maintain factual accuracy
Summary:
"""
3. Code Generation
prompt = """
Write a Python function that {task_description}.
Requirements:
- Use type hints
- Include docstring
- Handle edge cases
- Add error handling
- Follow PEP 8 style
Function:
"""
4. Question Answering
prompt = """
Answer the question based on the provided context.
If the answer is not in the context, say "I don't have enough information."
Context: {context}
Question: {question}
Answer:
"""
5. Data Extraction
prompt = """
Extract the following information from the text and format as JSON:
- Name
- Email
- Phone number
- Company
Text: {text}
JSON:
"""
Using GPT-4 and Modern LLMs
GPT-4 Capabilities:
- Multimodal: Can process text and images
- Long Context: Handles longer prompts (up to 128k tokens)
- Better Reasoning: Improved logical reasoning
- Code Understanding: Better at code tasks
Best Practices for GPT-4:
from openai import OpenAI
client = OpenAI()
# Use system message for role-setting
resp>
model="gpt-4",
messages=[
{
"role": "system",
"content": "You are a helpful data science tutor. Explain concepts clearly and provide examples."
},
{
"role": "user",
"content": "Explain gradient descent"
}
],
temperature=0.7, # Control randomness (0-2)
max_tokens=500 # Limit response length
)
Temperature Settings:
- 0.0-0.3: Deterministic, factual (good for data extraction)
- 0.4-0.7: Balanced (good for most tasks)
- 0.8-1.2: Creative (good for writing, brainstorming)
- 1.3-2.0: Very creative (may be less coherent)
Top-p (Nucleus Sampling):
resp>
model="gpt-4",
messages=[...],
temperature=0.7,
top_p=0.9 # Consider top 90% of probability mass
)
Top-k Sampling:
resp>
model="gpt-4",
messages=[...],
temperature=0.7,
top_k=50 # Consider only top 50 most likely tokens
)
Repetition Penalty:
resp>
model="gpt-4",
messages=[...],
temperature=0.7,
frequency_penalty=0.5, # Reduce repetition (0.0 to 2.0)
presence_penalty=0.3 # Encourage new topics (0.0 to 2.0)
)
Generative Configuration Parameters
Understanding Generation Parameters:
Temperature (0.0 to 2.0)
- Controls randomness in token selection
- Lower = more deterministic, higher = more creative
- Scientific Insight: Temperature scales the logits before softmax:
P(token) = softmax(logits / temperature) - Use Cases:
- 0.0-0.3: Factual tasks, data extraction, code generation
- 0.4-0.7: Balanced tasks, general Q&A, summarization
- 0.8-1.2: Creative writing, brainstorming, ideation
- 1.3-2.0: Experimental, may produce less coherent outputs
Top-p (Nucleus Sampling) (0.0 to 1.0)
- Considers tokens whose cumulative probability mass reaches the threshold
- More dynamic than top-k: adapts to probability distribution
- Scientific Insight: Filters tokens until cumulative probability ≥ top_p
- Example: If top_p=0.9, includes tokens until their cumulative probability reaches 90%
- Use Cases: Better for diverse outputs while maintaining quality
Top-k Sampling (integer)
- Considers only the k most likely tokens
- Fixed number regardless of probability distribution
- Scientific Insight: Filters to top k tokens by probability, then samples
- Use Cases: When you want to limit to most probable tokens
Repetition Penalty (frequency_penalty, presence_penalty)
- Frequency Penalty: Reduces probability of tokens that have appeared frequently
- Presence Penalty: Reduces probability of tokens that have appeared at all
- Scientific Insight: Modifies logits:
logits[token] -= penalty * count(token) - Use Cases: Preventing repetitive outputs, encouraging diversity
Max Tokens
- Limits the maximum number of tokens in the response
- Important for cost control and response length
- Use Cases: Budget management, ensuring concise responses
Parameter Interaction:
- Temperature and top-p/top-k work together
- Lower temperature + lower top-p = more focused, deterministic outputs
- Higher temperature + higher top-p = more diverse, creative outputs
- Repetition penalties help maintain quality in longer generations
Best Practices:
# Factual, deterministic (code, data extraction)
c>
"temperature": 0.0,
"top_p": 0.1,
"max_tokens": 500
}
# Balanced (general Q&A, summarization)
c>
"temperature": 0.7,
"top_p": 0.9,
"max_tokens": 1000
}
# Creative (writing, brainstorming)
c>
"temperature": 1.0,
"top_p": 0.95,
"frequency_penalty": 0.5,
"max_tokens": 2000
}
Prompt Engineering Checklist
Before Sending:
- Is the task clearly defined?
- Are requirements specific?
- Is the output format specified?
- Is context provided if needed?
- Are examples included (if helpful)?
- Is the role/tone set appropriately?
- Are constraints and boundaries clear?
After Getting Response:
- Does it meet requirements?
- Is it accurate and relevant?
- Can it be improved with refinement?
- Should I add more context?
- Should I adjust temperature/parameters?
Common Mistakes to Avoid
1. Being Too Vague
# Bad
"Write something about data"
# Good
"Write a 200-word introduction to data science for beginners"
2. Overloading with Information
# Bad: Too much at once
"Analyze this data, create visualizations, write a report, and suggest improvements"
# Good: Break into steps
"Step 1: Analyze this data and identify key trends"
3. Not Providing Context
# Bad
"Summarize this"
# Good
"Summarize this research paper in 3 paragraphs for a general audience"
4. Ignoring Output Format
# Bad
"List the features"
# Good
"List the top 5 features as a numbered list with brief descriptions"
5. Not Testing and Iterating
- Always test prompts with sample inputs
- Refine based on results
- Document what works
Prompt Engineering Resources
Practice Platforms:
- OpenAI Playground
- Hugging Face Spaces
- LangChain Playground
- Anthropic Console
Learning Resources:
- OpenAI Prompt Engineering Guide
- Anthropic Prompt Engineering Guide
- LangChain Prompt Templates
- Prompt Engineering GitHub Repositories
LangChain & LangGraph
JavaScript / TypeScript: Application examples for Node and Next.js live in the LangChain.js / TypeScript docs. The sections below focus on Python patterns.
LangChain
LangChain is a framework for building LLM-powered applications.
Purpose:
- Connect LLMs with tools, memory, and APIs
- Build complex AI applications
- Rapid development of GenAI apps
Core Components:
1. LLMs
Core language model interface.
from langchain_openai import ChatOpenAI
# Chat models are the current OpenAI integration path
chat = ChatOpenAI(model="gpt-4o-mini", temperature=0.7)
# Stronger option when needed: ChatOpenAI(model="gpt-4o", temperature=0.7)
2. Prompt Templates
Reusable input formats.
from langchain.prompts import PromptTemplate
template = "Write a {style} article about {topic}"
prompt = PromptTemplate(
input_variables=["style", "topic"],
template=template
)
formatted = prompt.format(style="technical", topic="AI")
3. Chains
Sequential workflows combining multiple components.
from langchain.chains import LLMChain
chain = LLMChain(llm=llm, prompt=prompt)
result = chain.run(style="technical", topic="AI")
4. Agents
Make dynamic decisions using tools.
from langchain.agents import initialize_agent, Tool
tools = [
Tool(
name="Search",
func=search_function,
description="Search the web"
)
]
agent = initialize_agent(
tools, llm, agent="zero-shot-react-description", verbose=True
)
agent.run("What is the weather in New York?")
5. Memory
Retain conversation history.
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory()
chain = ConversationChain(llm=llm, memory=memory)
chain.run("My name is Alice")
chain.run("What is my name?") # Remembers: "Alice"
6. Tools
APIs, functions, or databases that agents can use.
from langchain.tools import Tool
def calculator(expression):
return eval(expression)
tool = Tool(
name="Calculator",
func=calculator,
description="Performs mathematical calculations"
)
LangGraph (Advanced LangChain)
LangGraph provides graph-based orchestration of LLM workflows.
Key Features:
- Branching: Conditional logic in workflows
- Looping: Iterative processes
- Multi-Agent Coordination: Multiple agents working together
- State Management: Complex state handling
Use Cases:
- Complex, dynamic AI systems
- Multi-step reasoning
- Agent collaboration
- Workflow orchestration
Example:
from langgraph.graph import StateGraph, END
# Define state
class AgentState(TypedDict):
query: str
research: str
draft: str
final: str
# Create graph
workflow = StateGraph(AgentState)
# Add nodes
workflow.add_node("research", research_agent)
workflow.add_node("draft", draft_agent)
workflow.add_node("review", review_agent)
# Add edges
workflow.add_edge("research", "draft")
workflow.add_conditional_edges(
"draft",
should_review,
{"yes": "review", "no": END}
)
workflow.add_edge("review", "draft") # Loop back if needed
# Compile and run
app = workflow.compile()
result = app.invoke({"query": "Write about AI"})
When to Use LangGraph:
- Complex workflows with branching
- Multi-agent systems
- Iterative refinement processes
- Stateful applications
AI Agents
What are AI Agents?
AI Agents are autonomous systems that combine:
- LLMs (reasoning and decision-making)
- Tools (actions and capabilities)
- Memory (context and history)
- Logic (rules and constraints)
Purpose: Perform tasks autonomously without constant human intervention.
Types of AI Agents
1. Reactive Agents
Respond based on current input without memory.
Characteristics:
- No memory of past interactions
- Decision based on current state only
- Fast and simple
- Limited context
Example:
# Simple reactive agent
def reactive_agent(user_input):
# Analyze current input
intent = classify_intent(user_input)
# Choose action
if intent == "search":
return search_tool(user_input)
elif intent == "calculate":
return calculator(user_input)
else:
return llm.generate(user_input)
2. Proactive Agents
Plan and execute multi-step tasks.
Characteristics:
- Can plan ahead
- Multi-step reasoning
- Goal-oriented
- Can adapt plans
Example:
# Proactive agent with planning
def proactive_agent(goal):
# Create plan
plan = llm.create_plan(goal)
# Execute steps
for step in plan:
result = execute_step(step)
if not result.success:
# Replan if needed
plan = llm.replan(goal, plan, result)
return final_result
Agent Examples
Research Agent
from langchain.agents import initialize_agent, Tool
research_tools = [
Tool(name="WebSearch", func=web_search, description="Search the web"),
Tool(name="Database", func=db_query, description="Query database"),
Tool(name="Summarize", func=summarize, description="Summarize text")
]
research_agent = initialize_agent(
research_tools, llm, agent="zero-shot-react-description"
)
result = research_agent.run("Research the latest AI trends")
Personal Assistant Agent
assistant_tools = [
Tool(name="Calendar", func=check_calendar, description="Check calendar"),
Tool(name="Email", func=send_email, description="Send email"),
Tool(name="Weather", func=get_weather, description="Get weather"),
Tool(name="Reminder", func=set_reminder, description="Set reminder")
]
assistant = initialize_agent(assistant_tools, llm, agent="conversational-react-description")
Task Planner Agent
def task_planner_agent(goal):
# Break down goal into tasks
tasks = llm.break_down_tasks(goal)
# Prioritize tasks
prioritized = llm.prioritize(tasks)
# Execute in order
results = []
for task in prioritized:
result = execute_task(task)
results.append(result)
return compile_results(results)
Vector Databases
What are Vector Databases?
Vector Databases (VectorDBs) store embeddings for semantic search and similarity matching.
Purpose:
- Store high-dimensional vectors (embeddings)
- Perform fast similarity search
- Enable context-aware AI
- Support memory-based AI systems
Popular Vector Databases
1. Pinecone:
- Managed cloud service
- Easy to use
- Scalable
- Good for production
2. Weaviate:
- Open-source
- GraphQL API
- Built-in ML models
- Self-hosted or cloud
3. FAISS (Facebook AI Similarity Search):
- Library by Meta
- Fast similarity search
- In-memory or on-disk
- Good for research
4. ChromaDB:
- Open-source
- Python-first
- Easy to use
- Good for prototyping
5. Qdrant:
- Open-source
- High performance
- REST API
- Commonly used in production stacks
Functions of Vector Databases
1. Store Embeddings
import chromadb
client = chromadb.Client()
collection = client.create_collection("documents")
# Add documents with embeddings
collection.add(
documents=["Document 1 text", "Document 2 text"],
ids=["doc1", "doc2"],
embeddings=embeddings # Pre-computed embeddings
)
2. Perform Similarity Search
# Query embedding
query_embedding = model.encode("What is machine learning?")
# Search for similar documents
results = collection.query(
query_embeddings=[query_embedding],
n_results=5 # Top 5 most similar
)
print(results['documents'])
3. Retrieve Relevant Context
def retrieve_context(query, vector_db, top_k=3):
# Generate query embedding
query_embedding = embedding_model.encode(query)
# Search vector database
results = vector_db.query(
query_embeddings=[query_embedding],
n_results=top_k
)
# Return relevant documents
return results['documents']
Use Cases
Semantic Search:
- Find documents by meaning, not keywords
- Better than traditional keyword search
- Understands context and synonyms
Context-Aware AI:
- Provide relevant context to LLMs
- Improve response quality
- Reduce hallucination
Memory-Based Systems:
- Store conversation history
- Retrieve relevant past interactions
- Build long-term memory
RAG (Retrieval-Augmented Generation)
What is RAG?
RAG (Retrieval-Augmented Generation) combines LLMs + Vector Databases for contextual output.
Core Idea: Enhance LLM responses by retrieving relevant information from external knowledge bases.
RAG Steps
1. Convert User Query → Embedding
query = "What is machine learning?"
query_embedding = embedding_model.encode(query)
2. Search VectorDB → Retrieve Similar Documents
results = vector_db.query(
query_embeddings=[query_embedding],
n_results=3
)
relevant_docs = results['documents']
3. Combine Retrieved Data → Feed to LLM
# Build augmented prompt
c>"\n".join(relevant_docs)
prompt = f"""
Context:
{context}
Question: {query}
Answer based on the context above:
"""
# Generate response
resp>
RAG Architecture
Use Cases
Document Q&A:
- Answer questions about documents
- Cite sources
- Provide accurate information
Knowledge Assistants:
- Company knowledge base
- Technical documentation
- Internal wikis
Custom Chatbots:
- Domain-specific chatbots
- Customer support
- Educational assistants
RAG Implementation Example
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_openai import ChatOpenAI
from langchain.chains import RetrievalQA
# 1. Load and split documents
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200
)
documents = text_splitter.split_documents(your_documents)
# 2. Create embeddings
embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-MiniLM-L6-v2"
)
# 3. Create vector store
vectorstore = FAISS.from_documents(documents, embeddings)
# 4. Create retriever
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
# 5. Create LLM (temperature=0 lowers randomness; not a correctness guarantee)
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
# 6. Create RAG chain
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=retriever,
return_source_documents=True
)
# 7. Query
query = "What is machine learning?"
result = qa_chain({"query": query})
print(result["result"])
print("\nSources:")
for doc in result["source_documents"]:
print(f"- {doc.page_content[:100]}...")
Multi-Agent Systems
What are Multi-Agent Systems?
Multi-Agent Systems involve multiple AI agents collaborating to complete tasks.
Key Characteristics:
- Each agent has a dedicated role
- Agents communicate and coordinate
- Distributed problem-solving
- Specialized capabilities
Example: Content Creation System
Agents:
- Planner Agent → Defines workflow and tasks
- Research Agent → Gathers information
- Writer Agent → Generates content
- Reviewer Agent → Reviews and improves
Workflow:
from crewai import Agent, Task, Crew
# Define agents
planner = Agent(
role="Content Planner",
goal="Plan content structure and outline",
backstory="Expert in content strategy"
)
researcher = Agent(
role="Research Analyst",
goal="Gather relevant information",
backstory="Expert researcher"
)
writer = Agent(
role="Content Writer",
goal="Write engaging content",
backstory="Skilled writer"
)
reviewer = Agent(
role="Content Reviewer",
goal="Review and improve content",
backstory="Expert editor"
)
# Define tasks
plan_task = Task(
description="Create content plan for topic: AI trends",
agent=planner
)
research_task = Task(
description="Research latest AI trends",
agent=researcher
)
write_task = Task(
description="Write article based on research",
agent=writer
)
review_task = Task(
description="Review and improve the article",
agent=reviewer
)
# Create crew
crew = Crew(
agents=[planner, researcher, writer, reviewer],
tasks=[plan_task, research_task, write_task, review_task],
verbose=True
)
# Execute
result = crew.kickoff()
print(result)
Benefits of Multi-Agent Systems
Specialization:
- Each agent excels at specific tasks
- Better overall performance
- Clear division of labor
Scalability:
- Add more agents for complex tasks
- Parallel processing
- Handle larger workloads
Robustness:
- If one agent fails, others continue
- Distributed system
- Fault tolerance
Flexibility:
- Easy to add/remove agents
- Adapt to different tasks
- Modular architecture
Generative AI Project Lifecycle
Overview
The Generative AI project lifecycle is a systematic approach to building, deploying, and maintaining GenAI applications. Understanding this lifecycle is crucial for successful project delivery.
Lifecycle Stages
1. Problem Definition & Use Case Selection
- Identify Problem: What problem does GenAI solve?
- Define Success Metrics: How will you measure success?
- Assess Feasibility: Is GenAI the right solution?
- Resource Planning: Budget, timeline, team
2. Data Preparation
- Data Collection: Gather relevant datasets
- Data Quality: Ensure high-quality, representative data
- Data Preprocessing: Clean, format, structure data
- Data Validation: Verify data quality and completeness
3. Model Selection
- Pre-trained vs Fine-tuned: Choose base model
- Model Size: Balance performance vs cost
- API vs Self-hosted: Consider deployment constraints
- Cost Analysis: Evaluate API costs vs infrastructure
4. Development & Testing
- Prompt Engineering: Develop effective prompts
- RAG Implementation: If using retrieval-augmented generation
- Agent Development: If building agent systems
- Testing: Unit tests, integration tests, evaluation
5. Evaluation & Optimization
- Performance Metrics: Accuracy, latency, cost
- Safety Testing: Bias, toxicity, hallucinations
- User Testing: Gather feedback from real users
- Iteration: Refine based on results
6. Deployment
- Infrastructure: Choose deployment platform
- Monitoring: Set up logging and monitoring
- Scaling: Plan for traffic and growth
- Security: Implement access controls and safeguards
7. Monitoring & Maintenance
- Performance Monitoring: Track metrics continuously
- Model Drift: Monitor for degradation
- User Feedback: Collect and act on feedback
- Updates: Regular model and system updates
Lifecycle Cheat Sheet
Key Considerations at Each Stage
Problem Definition:
- Is GenAI the right solution? (vs traditional ML, rule-based)
- What are the success criteria?
- What are the constraints? (latency, cost, privacy)
Data Preparation:
- Quality over quantity
- Representative of production data
- Privacy and compliance considerations
Model Selection:
- Performance vs cost trade-off
- Latency requirements
- Data privacy (API vs self-hosted)
Development:
- Start simple, iterate
- Test early and often
- Consider edge cases and failures
Evaluation:
- Multiple metrics (not just accuracy)
- Safety and bias testing
- Real-world user testing
Deployment:
- Start with MVP
- Plan for scaling
- Implement monitoring from day one
Monitoring:
- Track key metrics continuously
- Set up alerts for anomalies
- Regular model and system updates
Best Practices
- Start Small: Begin with MVP, expand gradually
- Iterate Quickly: Fast feedback loops
- Measure Everything: Track metrics from the start
- Safety First: Build safety and bias checks early
- User-Centric: Involve users throughout the process
- Document Everything: Code, decisions, experiments
- Plan for Scale: Design for growth from the start
Building Generative AI Apps
Tech Stack
Frontend / UI:
- Streamlit - Fast, Python-based UI
- Gradio - Simple ML app interfaces
- React/Vue - Custom web interfaces
- Next.js - Full-stack framework
Backend Logic:
- Python - Primary language
- FastAPI - API framework
- Flask - Lightweight web framework
- Django - Full-featured framework
LLM Framework:
- LangChain - Application framework
- LangGraph - Graph-based workflows
- LlamaIndex - Data indexing and querying
Vector Database:
- Pinecone - Managed cloud service
- ChromaDB - Open-source, Python-first
- FAISS - Fast similarity search
- Weaviate - Open-source, GraphQL
Model APIs:
- OpenAI - GPT-3.5, GPT-4
- Google Gemini - Multimodal AI
- Anthropic Claude - Helpful AI
- Mistral - Open-source models
- HuggingFace - Model hub and APIs
Example: Streamlit RAG App
import streamlit as st
from langchain_openai import ChatOpenAI
from langchain_community.vectorstores import FAISS
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain.chains import RetrievalQA
# Page config
st.set_page_config(page_title="RAG Chatbot")
# Initialize session state
if "messages" not in st.session_state:
st.session_state.messages = []
# Load vector store
@st.cache_resource
def load_vectorstore():
embeddings = HuggingFaceEmbeddings()
vectorstore = FAISS.load_local("vectorstore", embeddings)
return vectorstore
# Load RAG chain
@st.cache_resource
def load_rag_chain():
vectorstore = load_vectorstore()
# temperature=0 lowers randomness; not a correctness guarantee
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=retriever,
return_source_documents=True
)
return qa_chain
# UI
st.title("RAG Chatbot")
# Display chat history
for message in st.session_state.messages:
with st.chat_message(message["role"]):
st.markdown(message["content"])
# User input
if prompt := st.chat_input("Ask a question..."):
# Add user message
st.session_state.messages.append({"role": "user", "content": prompt})
with st.chat_message("user"):
st.markdown(prompt)
# Get response
qa_chain = load_rag_chain()
result = qa_chain({"query": prompt})
# Display response
with st.chat_message("assistant"):
st.markdown(result["result"])
# Show sources
with st.expander("Sources"):
for doc in result["source_documents"]:
st.text(doc.page_content[:200])
# Add assistant message
st.session_state.messages.append({
"role": "assistant",
"content": result["result"]
})
Deployment Options
Cloud Platforms:
- AWS - SageMaker, Lambda, EC2
- Google Cloud - Vertex AI, Cloud Run
- Azure - Azure OpenAI, Functions
- Vercel - Serverless deployment
- Railway - Simple deployment
Containerization:
- Docker - Containerize applications
- Kubernetes - Orchestration
- Docker Compose - Local development
Monitoring:
- LangSmith - LangChain monitoring
- Weights & Biases - Experiment tracking
- Prometheus - Metrics collection
Resources
Official Documentation
Learning Resources
Vector Database Resources
Model Providers
Try next: Ship one small RAG or agent demo with cost logging and a citation check. Expand only after that works.