Study interactive :: Progress tools open in the Study Hub reader.

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

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:

Examples of Generative AI

Text Generation:

Image Generation:

Code Generation:

Audio Generation:

How Generative AI Works

Two Main Approaches:

  1. Large Language Models (LLMs):

    • Trained on massive text datasets
    • Predict next word/token in sequence
    • Examples: GPT, Gemini, Claude
  2. 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:

Open-Source:

Commercial:

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:

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:

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:

Transformers

Neural network architecture that uses self-attention for context understanding.

Key Components:

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?


Capabilities & Limitations

What LLMs Can Do

Text Generation:

Summarization:

Question Answering:

Translation:

Code Writing:

Conversation:

Limitations

Hallucination:

Training Data Bias:

No Real-World Understanding:

Context Limitations:

Outdated Information:

Cost:

Mitigation Strategies:


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:

Core Principle: LLMs are instruction-following systems. The quality of your instructions directly impacts the quality of outputs.

Understanding Language Models

How LLMs Work:

Implications for Prompting:

Prompt Engineering Mindset

Key Principles:

  1. Clarity Over Cleverness

    • Clear, direct instructions work better than clever tricks
    • Be explicit about what you want
  2. Iterative Refinement

    • Start simple, then refine
    • Test and improve based on results
    • Document what works
  3. Context is King

    • Provide relevant background
    • Include necessary information
    • Set the right tone and style
  4. 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:

# Zero-shot
prompt = "Translate this to French: Hello, how are you?"

Few-Shot Prompting:

# 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:

Handling AI Hallucinations

What are Hallucinations?

Why They Happen:

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?

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:

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:

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:

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:

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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:

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:

After Getting Response:

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

Prompt Engineering Resources

Practice Platforms:

Learning Resources:


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:

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:

Use Cases:

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:


AI Agents

What are AI Agents?

AI Agents are autonomous systems that combine:

Purpose: Perform tasks autonomously without constant human intervention.

Types of AI Agents

1. Reactive Agents

Respond based on current input without memory.

Characteristics:

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:

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:

1. Pinecone:

2. Weaviate:

3. FAISS (Facebook AI Similarity Search):

4. ChromaDB:

5. Qdrant:

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
)
# 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:

Context-Aware AI:

Memory-Based Systems:


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

User QueryQuery EmbeddingVector Searchvector DBRetrieve Top-K DocumentsAugment Promptquery plus contextLLM GenerationResponse plus Sources

Use Cases

Document Q&A:

Knowledge Assistants:

Custom Chatbots:

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:

Example: Content Creation System

Agents:

  1. Planner Agent → Defines workflow and tasks
  2. Research Agent → Gathers information
  3. Writer Agent → Generates content
  4. 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:

Scalability:

Robustness:

Flexibility:


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

2. Data Preparation

3. Model Selection

4. Development & Testing

5. Evaluation & Optimization

6. Deployment

7. Monitoring & Maintenance

Lifecycle Cheat Sheet

1. Problem Definitionuse case and success metrics2. Data Preparation3. Model SelectionAPI vs self-hosted4. Development and Testingprompts, RAG, agents5. Evaluation and Optimization6. Deploymentinfra, monitoring, security7. Monitoring and Maintenance

Key Considerations at Each Stage

Problem Definition:

Data Preparation:

Model Selection:

Development:

Evaluation:

Deployment:

Monitoring:

Best Practices

  1. Start Small: Begin with MVP, expand gradually
  2. Iterate Quickly: Fast feedback loops
  3. Measure Everything: Track metrics from the start
  4. Safety First: Build safety and bias checks early
  5. User-Centric: Involve users throughout the process
  6. Document Everything: Code, decisions, experiments
  7. Plan for Scale: Design for growth from the start

Building Generative AI Apps

Tech Stack

Frontend / UI:

Backend Logic:

LLM Framework:

Vector Database:

Model 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:

Containerization:

Monitoring:


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.