|
@@ -0,0 +1,689 @@
|
|
|
+{
|
|
|
+ "cells": [
|
|
|
+ {
|
|
|
+ "cell_type": "markdown",
|
|
|
+ "id": "a0eaff04",
|
|
|
+ "metadata": {},
|
|
|
+ "source": [
|
|
|
+ "# Ensure the required libraries are installed i.e.\n",
|
|
|
+ "!pip install sentence-transformers qdrant-client requests IPython\n"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "markdown",
|
|
|
+ "id": "4a8cdfac",
|
|
|
+ "metadata": {},
|
|
|
+ "source": [
|
|
|
+ "# Step 1: Import necessary modules"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "code",
|
|
|
+ "execution_count": 2,
|
|
|
+ "id": "b3f67c91",
|
|
|
+ "metadata": {},
|
|
|
+ "outputs": [
|
|
|
+ {
|
|
|
+ "name": "stdout",
|
|
|
+ "output_type": "stream",
|
|
|
+ "text": [
|
|
|
+ "Libraries installed and modules imported successfully.\n"
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "source": [
|
|
|
+ "import os\n",
|
|
|
+ "import uuid\n",
|
|
|
+ "import re\n",
|
|
|
+ "from pathlib import Path\n",
|
|
|
+ "from sentence_transformers import SentenceTransformer, CrossEncoder\n",
|
|
|
+ "from qdrant_client import QdrantClient, models\n",
|
|
|
+ "from qdrant_client.models import SearchRequest\n",
|
|
|
+ "import requests\n",
|
|
|
+ "from IPython.display import Markdown, display\n",
|
|
|
+ "import json\n",
|
|
|
+ "\n",
|
|
|
+ "print(\"Libraries installed and modules imported successfully.\")"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "markdown",
|
|
|
+ "id": "58a4962f",
|
|
|
+ "metadata": {},
|
|
|
+ "source": [
|
|
|
+ "# Step 2: Define Configuration and Global Variables\n",
|
|
|
+ "This contains all your static configuration, including API keys, URLs, and file paths."
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "code",
|
|
|
+ "execution_count": null,
|
|
|
+ "id": "01e548da",
|
|
|
+ "metadata": {},
|
|
|
+ "outputs": [
|
|
|
+ {
|
|
|
+ "name": "stdout",
|
|
|
+ "output_type": "stream",
|
|
|
+ "text": [
|
|
|
+ "Configuration variables and collection name set.\n"
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "source": [
|
|
|
+ "# --- Configuration ---\n",
|
|
|
+ "# API Keys should be loaded from environment variables for security.\n",
|
|
|
+ "# DO NOT commit your .env file or hardcode API keys directly in the code for production.\n",
|
|
|
+ "\n",
|
|
|
+ "\n",
|
|
|
+ "LLAMA_API_KEY = os.getenv(\"LLAMA_API_KEY\")\n",
|
|
|
+ "if not LLAMA_API_KEY:\n",
|
|
|
+ " raise ValueError(\"LLAMA_API_KEY not found. Please set it as an environment variable or in a .env file.\")\n",
|
|
|
+ "\n",
|
|
|
+ "API_URL = \"https://api.llama.com/v1/chat/completions\"\n",
|
|
|
+ "HEADERS = {\n",
|
|
|
+ " \"Content-Type\": \"application/json\",\n",
|
|
|
+ " \"Authorization\": f\"Bearer {LLAMA_API_KEY}\"\n",
|
|
|
+ "}\n",
|
|
|
+ "LLAMA_MODEL = \"Llama-4-Maverick-17B-128E-Instruct-FP8\"\n",
|
|
|
+ "\n",
|
|
|
+ "# Qdrant Configuration (Now using In-Memory Qdrant for offline use)\n",
|
|
|
+ "# No QDRANT_URL or QDRANT_API_KEY needed for in-memory client.\n",
|
|
|
+ "\n",
|
|
|
+ "# The Qdrant collection to be queried. This will be created in-memory.\n",
|
|
|
+ "MAIN_COLLECTION_NAME = \"readme_blogs_latest\"\n",
|
|
|
+ "\n",
|
|
|
+ "print(\"Configuration variables and collection name set.\")"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "markdown",
|
|
|
+ "id": "d76eccb5",
|
|
|
+ "metadata": {},
|
|
|
+ "source": [
|
|
|
+ "# Step 3: Define Helper Functions\n",
|
|
|
+ "It contains all the functions that handle the core logic of the application: markdown_splitter, setup_qdrant, and query_qdrant."
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "code",
|
|
|
+ "execution_count": null,
|
|
|
+ "id": "2b972b21",
|
|
|
+ "metadata": {},
|
|
|
+ "outputs": [
|
|
|
+ {
|
|
|
+ "name": "stdout",
|
|
|
+ "output_type": "stream",
|
|
|
+ "text": [
|
|
|
+ "Helper functions for querying Qdrant defined.\n"
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "source": [
|
|
|
+ "def get_qdrant_client():\n",
|
|
|
+ " \"\"\"Returns an in-memory Qdrant client instance.\"\"\"\n",
|
|
|
+ " # For an in-memory client, you don't pass URL or API Key.\n",
|
|
|
+ " return QdrantClient(\":memory:\")\n",
|
|
|
+ "\n",
|
|
|
+ "def get_embedding_model():\n",
|
|
|
+ " \"\"\"Returns the SentenceTransformer embedding model.\"\"\"\n",
|
|
|
+ " return SentenceTransformer('all-MiniLM-L6-v2')\n",
|
|
|
+ "\n",
|
|
|
+ "def create_qdrant_collection(client, collection_name, vector_size):\n",
|
|
|
+ " \"\"\"Creates a Qdrant collection with the specified vector size if it doesn't exist.\"\"\"\n",
|
|
|
+ " try:\n",
|
|
|
+ " # Check if collection exists\n",
|
|
|
+ " client.get_collection(collection_name=collection_name)\n",
|
|
|
+ " print(f\"Collection '{collection_name}' already exists.\")\n",
|
|
|
+ " except Exception: # QdrantClient throws if collection doesn't exist\n",
|
|
|
+ " print(f\"Creating collection '{collection_name}'...\")\n",
|
|
|
+ " client.recreate_collection(\n",
|
|
|
+ " collection_name=collection_name,\n",
|
|
|
+ " vectors_config=models.VectorParams(size=vector_size, distance=models.Distance.COSINE),\n",
|
|
|
+ " )\n",
|
|
|
+ " print(f\"Collection '{collection_name}' created.\")\n",
|
|
|
+ "\n",
|
|
|
+ "def ingest_data_into_qdrant(client, collection_name, embedding_model, data_chunks):\n",
|
|
|
+ " \"\"\"\n",
|
|
|
+ " Ingests data (text chunks) into the Qdrant collection.\n",
|
|
|
+ " You will need to replace this with your actual data loading and chunking logic.\n",
|
|
|
+ " \"\"\"\n",
|
|
|
+ " print(f\"Ingesting data into collection '{collection_name}'...\")\n",
|
|
|
+ " if not data_chunks:\n",
|
|
|
+ " print(\"No data chunks provided for ingestion.\")\n",
|
|
|
+ " return\n",
|
|
|
+ "\n",
|
|
|
+ " points = []\n",
|
|
|
+ " for i, chunk_text in enumerate(data_chunks):\n",
|
|
|
+ " embedding = embedding_model.encode(chunk_text).tolist()\n",
|
|
|
+ " points.append(\n",
|
|
|
+ " models.PointStruct(\n",
|
|
|
+ " id=i, # Unique ID for each point\n",
|
|
|
+ " vector=embedding,\n",
|
|
|
+ " payload={\"text\": chunk_text}\n",
|
|
|
+ " )\n",
|
|
|
+ " )\n",
|
|
|
+ " \n",
|
|
|
+ " # Ensure the collection has been created with the correct vector size\n",
|
|
|
+ " # before attempting to upsert.\n",
|
|
|
+ " # The vector size must match the embedding model output.\n",
|
|
|
+ " embedding_size = len(embedding_model.encode(\"test\").tolist())\n",
|
|
|
+ " create_qdrant_collection(client, collection_name, embedding_size)\n",
|
|
|
+ "\n",
|
|
|
+ " operation_info = client.upsert(\n",
|
|
|
+ " collection_name=collection_name,\n",
|
|
|
+ " wait=True,\n",
|
|
|
+ " points=points,\n",
|
|
|
+ " )\n",
|
|
|
+ " print(f\"Data ingestion complete. Status: {operation_info.status}\")\n",
|
|
|
+ "\n",
|
|
|
+ "\n",
|
|
|
+ "def query_qdrant(query, client, collection_name, top_k=5):\n",
|
|
|
+ " \"\"\"Query Qdrant with hybrid search and reranking on a specified collection.\"\"\"\n",
|
|
|
+ " embedding_model = get_embedding_model()\n",
|
|
|
+ " query_embedding = embedding_model.encode(query).tolist()\n",
|
|
|
+ " \n",
|
|
|
+ " # Initial vector search\n",
|
|
|
+ " try:\n",
|
|
|
+ " results = client.search(\n",
|
|
|
+ " collection_name=collection_name,\n",
|
|
|
+ " query_vector=query_embedding,\n",
|
|
|
+ " limit=top_k*2\n",
|
|
|
+ " )\n",
|
|
|
+ " except Exception as e:\n",
|
|
|
+ " print(f\"Error during Qdrant search on collection '{collection_name}': {e}\")\n",
|
|
|
+ " return []\n",
|
|
|
+ " \n",
|
|
|
+ " if not results:\n",
|
|
|
+ " print(\"No results found in Qdrant for the given query.\")\n",
|
|
|
+ " return []\n",
|
|
|
+ "\n",
|
|
|
+ " # Rerank using cross-encoder\n",
|
|
|
+ " cross_encoder = CrossEncoder('cross-encoder/ms-marco-MiniLM-L6-v2')\n",
|
|
|
+ " pairs = [(query, hit.payload[\"text\"]) for hit in results]\n",
|
|
|
+ " scores = cross_encoder.predict(pairs)\n",
|
|
|
+ " \n",
|
|
|
+ " # Combine scores with results\n",
|
|
|
+ " sorted_results = [x for _, x in sorted(zip(scores, results), key=lambda pair: pair[0], reverse=True)]\n",
|
|
|
+ " return sorted_results[:top_k]\n",
|
|
|
+ "\n",
|
|
|
+ "print(\"Helper functions for querying Qdrant defined.\")"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "markdown",
|
|
|
+ "id": "092d8cd8",
|
|
|
+ "metadata": {},
|
|
|
+ "source": [
|
|
|
+ "# Step 4: Define the Main Blog Generation Function\n",
|
|
|
+ "This function orchestrates the RAG process by calling the helper functions, building the prompt, and making the API call."
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "code",
|
|
|
+ "execution_count": null,
|
|
|
+ "id": "0d682099",
|
|
|
+ "metadata": {},
|
|
|
+ "outputs": [
|
|
|
+ {
|
|
|
+ "name": "stdout",
|
|
|
+ "output_type": "stream",
|
|
|
+ "text": [
|
|
|
+ "Blog generation function defined.\n"
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "source": [
|
|
|
+ "def generate_blog(topic):\n",
|
|
|
+ " \"\"\"Generates a technical blog post based on a topic using RAG.\"\"\"\n",
|
|
|
+ " print(\"Getting Qdrant client and querying pre-existing collection...\")\n",
|
|
|
+ " client = get_qdrant_client()\n",
|
|
|
+ " embedding_model = get_embedding_model()\n",
|
|
|
+ "\n",
|
|
|
+ " # IMPORTANT: For in-memory Qdrant, you MUST ingest your data every time\n",
|
|
|
+ " # the script runs or the client is initialized, as it's not persistent.\n",
|
|
|
+ " # Replace this with your actual data loading and chunking.\n",
|
|
|
+ " # Example placeholder data:\n",
|
|
|
+ " example_data_chunks = [\n",
|
|
|
+ " \"Llama 3 is a powerful large language model developed by Meta. It excels at various NLP tasks.\",\n",
|
|
|
+ " \"To build a chatbot with Llama 3, you'll typically use an API to send prompts and receive responses.\",\n",
|
|
|
+ " \"Messenger Platform allows developers to create interactive experiences for Facebook Messenger users.\",\n",
|
|
|
+ " \"Integrating Llama 3 with Messenger involves setting up webhooks and handling message events.\",\n",
|
|
|
+ " \"Key steps include setting up a Facebook App, configuring webhooks, and deploying your bot's backend.\",\n",
|
|
|
+ " \"Best practices for chatbots include clear error handling, concise responses, and user guidance.\",\n",
|
|
|
+ " \"Security is crucial; always protect your API keys and ensure your webhook endpoints are secure.\"\n",
|
|
|
+ " ]\n",
|
|
|
+ " ingest_data_into_qdrant(client, MAIN_COLLECTION_NAME, embedding_model, example_data_chunks)\n",
|
|
|
+ " # End of IMPORTANT section for data ingestion\n",
|
|
|
+ "\n",
|
|
|
+ "\n",
|
|
|
+ " # Query relevant sections from the main collection\n",
|
|
|
+ " relevant_chunks = query_qdrant(topic, client, MAIN_COLLECTION_NAME)\n",
|
|
|
+ " \n",
|
|
|
+ " if not relevant_chunks:\n",
|
|
|
+ " error_message = \"No relevant content found in the knowledge base. Cannot generate blog post.\"\n",
|
|
|
+ " print(error_message)\n",
|
|
|
+ " return error_message\n",
|
|
|
+ "\n",
|
|
|
+ " context = \"\\n\".join([chunk.payload[\"text\"] for chunk in relevant_chunks])\n",
|
|
|
+ " \n",
|
|
|
+ " system_prompt = f\"\"\"\n",
|
|
|
+ " You are a technical writer specializing in creating comprehensive documentation-based blog posts. \n",
|
|
|
+ " Use the following context from technical documentation to write an in-depth blog post about {topic}.\n",
|
|
|
+ " \n",
|
|
|
+ " Requirements:\n",
|
|
|
+ " 1. Structure the blog with clear sections and subsections\n",
|
|
|
+ " 2. Include code examples and configuration details where relevant\n",
|
|
|
+ " 3. Explain architectural components using diagrams (describe in markdown)\n",
|
|
|
+ " 4. Add setup instructions and best practices\n",
|
|
|
+ " 5. Use technical terminology appropriate for developers\n",
|
|
|
+ " \n",
|
|
|
+ " Context:\n",
|
|
|
+ " {context}\n",
|
|
|
+ " \"\"\"\n",
|
|
|
+ " \n",
|
|
|
+ " payload = {\n",
|
|
|
+ " \"model\": LLAMA_MODEL,\n",
|
|
|
+ " \"messages\": [\n",
|
|
|
+ " {\"role\": \"system\", \"content\": system_prompt},\n",
|
|
|
+ " {\"role\": \"user\", \"content\": f\"Write a detailed technical blog post about {topic}\"}\n",
|
|
|
+ " ],\n",
|
|
|
+ " \"temperature\": 0.5,\n",
|
|
|
+ " \"max_tokens\": 4096\n",
|
|
|
+ " }\n",
|
|
|
+ " \n",
|
|
|
+ " print(\"Sending request to Llama API for blog generation...\")\n",
|
|
|
+ " try:\n",
|
|
|
+ " response = requests.post(API_URL, headers=HEADERS, json=payload)\n",
|
|
|
+ " \n",
|
|
|
+ " if response.status_code == 200:\n",
|
|
|
+ " response_json = response.json()\n",
|
|
|
+ " # Adjusting to handle the potentially nested structure as seen in your original code\n",
|
|
|
+ " # where 'completion_message' might be missing or 'content' might be missing.\n",
|
|
|
+ " # Adding .get with default values for safer access.\n",
|
|
|
+ " blog_content = response_json.get('completion_message', {}).get('content', {}).get('text', '')\n",
|
|
|
+ " \n",
|
|
|
+ " if not blog_content:\n",
|
|
|
+ " print(\"Warning: 'completion_message.content.text' was empty or not found in API response.\")\n",
|
|
|
+ " print(f\"Full API response: {response_json}\")\n",
|
|
|
+ " return \"Error: Could not extract blog content from API response.\"\n",
|
|
|
+ "\n",
|
|
|
+ " # Format as markdown\n",
|
|
|
+ " markdown_content = f\"# {topic}\\n\\n{blog_content}\"\n",
|
|
|
+ " \n",
|
|
|
+ " # Save to file\n",
|
|
|
+ " output_path = Path(f\"{topic.replace(' ', '_')}_blog.md\")\n",
|
|
|
+ " with open(output_path, \"w\", encoding=\"utf-8\") as f:\n",
|
|
|
+ " f.write(markdown_content)\n",
|
|
|
+ " \n",
|
|
|
+ " print(f\"Blog post generated and saved to {output_path}.\")\n",
|
|
|
+ " \n",
|
|
|
+ " # Display markdown content directly in the notebook\n",
|
|
|
+ " display(Markdown(markdown_content))\n",
|
|
|
+ " return markdown_content\n",
|
|
|
+ " \n",
|
|
|
+ " else:\n",
|
|
|
+ " error_message = f\"Error: {response.status_code} - {response.text}\"\n",
|
|
|
+ " print(error_message)\n",
|
|
|
+ " return error_message\n",
|
|
|
+ " \n",
|
|
|
+ " except Exception as e:\n",
|
|
|
+ " error_message = f\"An unexpected error occurred: {str(e)}\"\n",
|
|
|
+ " print(error_message)\n",
|
|
|
+ " return error_message\n",
|
|
|
+ "\n",
|
|
|
+ "print(\"Blog generation function defined.\")"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "markdown",
|
|
|
+ "id": "67497a92",
|
|
|
+ "metadata": {},
|
|
|
+ "source": [
|
|
|
+ "# Step 5: Specify the topic for the blog post and execute the Blog Generation Process\n"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "code",
|
|
|
+ "execution_count": null,
|
|
|
+ "id": "6b3113ef",
|
|
|
+ "metadata": {},
|
|
|
+ "outputs": [
|
|
|
+ {
|
|
|
+ "name": "stdout",
|
|
|
+ "output_type": "stream",
|
|
|
+ "text": [
|
|
|
+ "Getting Qdrant client and querying pre-existing collection...\n"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "name": "stderr",
|
|
|
+ "output_type": "stream",
|
|
|
+ "text": [
|
|
|
+ "/var/folders/f5/lntr7_gx6fd1y_1rtgwf2g9h0000gn/T/ipykernel_89390/3804544503.py:16: DeprecationWarning: `search` method is deprecated and will be removed in the future. Use `query_points` instead.\n",
|
|
|
+ " results = client.search(\n"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "data": {
|
|
|
+ "application/vnd.jupyter.widget-view+json": {
|
|
|
+ "model_id": "f0623176afc44a00ac97aa280a104140",
|
|
|
+ "version_major": 2,
|
|
|
+ "version_minor": 0
|
|
|
+ },
|
|
|
+ "text/plain": [
|
|
|
+ "config.json: 0%| | 0.00/794 [00:00<?, ?B/s]"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ "metadata": {},
|
|
|
+ "output_type": "display_data"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "data": {
|
|
|
+ "application/vnd.jupyter.widget-view+json": {
|
|
|
+ "model_id": "bf7cfa830d6945c099716abd819fd652",
|
|
|
+ "version_major": 2,
|
|
|
+ "version_minor": 0
|
|
|
+ },
|
|
|
+ "text/plain": [
|
|
|
+ "model.safetensors: 0%| | 0.00/90.9M [00:00<?, ?B/s]"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ "metadata": {},
|
|
|
+ "output_type": "display_data"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "data": {
|
|
|
+ "application/vnd.jupyter.widget-view+json": {
|
|
|
+ "model_id": "6b3a805cb1d04d659b0cda97fee10189",
|
|
|
+ "version_major": 2,
|
|
|
+ "version_minor": 0
|
|
|
+ },
|
|
|
+ "text/plain": [
|
|
|
+ "tokenizer_config.json: 0.00B [00:00, ?B/s]"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ "metadata": {},
|
|
|
+ "output_type": "display_data"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "data": {
|
|
|
+ "application/vnd.jupyter.widget-view+json": {
|
|
|
+ "model_id": "4a44a1a1123c4ea3960c454c260d7d01",
|
|
|
+ "version_major": 2,
|
|
|
+ "version_minor": 0
|
|
|
+ },
|
|
|
+ "text/plain": [
|
|
|
+ "vocab.txt: 0.00B [00:00, ?B/s]"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ "metadata": {},
|
|
|
+ "output_type": "display_data"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "data": {
|
|
|
+ "application/vnd.jupyter.widget-view+json": {
|
|
|
+ "model_id": "87a76d03243d4179849421448a3bd59e",
|
|
|
+ "version_major": 2,
|
|
|
+ "version_minor": 0
|
|
|
+ },
|
|
|
+ "text/plain": [
|
|
|
+ "tokenizer.json: 0.00B [00:00, ?B/s]"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ "metadata": {},
|
|
|
+ "output_type": "display_data"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "data": {
|
|
|
+ "application/vnd.jupyter.widget-view+json": {
|
|
|
+ "model_id": "7178785c5aaa4c02bd3f92277b67cb9f",
|
|
|
+ "version_major": 2,
|
|
|
+ "version_minor": 0
|
|
|
+ },
|
|
|
+ "text/plain": [
|
|
|
+ "special_tokens_map.json: 0%| | 0.00/132 [00:00<?, ?B/s]"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ "metadata": {},
|
|
|
+ "output_type": "display_data"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "data": {
|
|
|
+ "application/vnd.jupyter.widget-view+json": {
|
|
|
+ "model_id": "04882361094c4a8e892c5c8d5b9e36a3",
|
|
|
+ "version_major": 2,
|
|
|
+ "version_minor": 0
|
|
|
+ },
|
|
|
+ "text/plain": [
|
|
|
+ "README.md: 0.00B [00:00, ?B/s]"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ "metadata": {},
|
|
|
+ "output_type": "display_data"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "name": "stdout",
|
|
|
+ "output_type": "stream",
|
|
|
+ "text": [
|
|
|
+ "Sending request to Llama API for blog generation...\n",
|
|
|
+ "Blog post generated and saved to Building_a_Messenger_Chatbot_with_Llama_3_blog.md.\n"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "data": {
|
|
|
+ "text/markdown": [
|
|
|
+ "# Building a Messenger Chatbot with Llama 3\n",
|
|
|
+ "\n",
|
|
|
+ "Building a Messenger Chatbot with Llama 3: A Step-by-Step Guide\n",
|
|
|
+ "=============================================================\n",
|
|
|
+ "\n",
|
|
|
+ "### Introduction\n",
|
|
|
+ "\n",
|
|
|
+ "In this blog post, we'll explore the process of building a Llama 3 enabled Messenger chatbot using the Messenger Platform. We'll cover the architectural components, setup instructions, and best practices to help you get started.\n",
|
|
|
+ "\n",
|
|
|
+ "### Overview of the Messenger Platform\n",
|
|
|
+ "\n",
|
|
|
+ "The Messenger Platform is a powerful tool that allows businesses to connect with their customers through a Facebook business page. By integrating Llama 3 with the Messenger Platform, businesses can create intelligent and knowledgeable chatbots that provide 24x7 customer support, improving customer experience and reducing costs.\n",
|
|
|
+ "\n",
|
|
|
+ "### Architectural Components\n",
|
|
|
+ "\n",
|
|
|
+ "The diagram below illustrates the components and overall data flow of the Llama 3 enabled Messenger chatbot demo:\n",
|
|
|
+ "```markdown\n",
|
|
|
+ "+---------------+\n",
|
|
|
+ "| User |\n",
|
|
|
+ "| (Messenger |\n",
|
|
|
+ "| App) |\n",
|
|
|
+ "+---------------+\n",
|
|
|
+ " |\n",
|
|
|
+ " | (1) Send Message\n",
|
|
|
+ " v\n",
|
|
|
+ "+---------------+\n",
|
|
|
+ "| Facebook |\n",
|
|
|
+ "| Business Page |\n",
|
|
|
+ "+---------------+\n",
|
|
|
+ " |\n",
|
|
|
+ " | (2) Webhook Event\n",
|
|
|
+ " v\n",
|
|
|
+ "+---------------+\n",
|
|
|
+ "| Web Server |\n",
|
|
|
+ "| (e.g., Amazon |\n",
|
|
|
+ "| EC2 instance) |\n",
|
|
|
+ "+---------------+\n",
|
|
|
+ " |\n",
|
|
|
+ " | (3) Process Event\n",
|
|
|
+ " | and Generate Response\n",
|
|
|
+ " | using Llama 3\n",
|
|
|
+ " v\n",
|
|
|
+ "+---------------+\n",
|
|
|
+ "| Llama 3 |\n",
|
|
|
+ "| Model |\n",
|
|
|
+ "+---------------+\n",
|
|
|
+ " |\n",
|
|
|
+ " | (4) Send Response\n",
|
|
|
+ " | back to User\n",
|
|
|
+ " v\n",
|
|
|
+ "+---------------+\n",
|
|
|
+ "| Facebook |\n",
|
|
|
+ "| Business Page |\n",
|
|
|
+ "+---------------+\n",
|
|
|
+ " |\n",
|
|
|
+ " | (5) Receive Response\n",
|
|
|
+ " v\n",
|
|
|
+ "+---------------+\n",
|
|
|
+ "| User |\n",
|
|
|
+ "| (Messenger |\n",
|
|
|
+ "| App) |\n",
|
|
|
+ "+---------------+\n",
|
|
|
+ "```\n",
|
|
|
+ "The components involved are:\n",
|
|
|
+ "\n",
|
|
|
+ "* **User**: The customer interacting with the Facebook business page using the Messenger app.\n",
|
|
|
+ "* **Facebook Business Page**: The business page that receives user messages and sends responses.\n",
|
|
|
+ "* **Web Server**: The server that processes incoming webhook events, generates responses using Llama 3, and sends responses back to the user.\n",
|
|
|
+ "* **Llama 3 Model**: The AI model that generates human-like responses to user queries.\n",
|
|
|
+ "\n",
|
|
|
+ "### Setup Instructions\n",
|
|
|
+ "\n",
|
|
|
+ "To build a Llama 3 enabled Messenger chatbot, follow these steps:\n",
|
|
|
+ "\n",
|
|
|
+ "#### Step 1: Create a Facebook Business Page\n",
|
|
|
+ "\n",
|
|
|
+ "1. Go to the Facebook Business Page creation page and follow the instructions to create a new page.\n",
|
|
|
+ "2. Ensure that you have the necessary permissions to manage the page.\n",
|
|
|
+ "\n",
|
|
|
+ "#### Step 2: Set up a Web Server\n",
|
|
|
+ "\n",
|
|
|
+ "1. Choose a cloud provider (e.g., Amazon Web Services) and launch an EC2 instance to host your web server.\n",
|
|
|
+ "2. Configure the instance with the necessary dependencies, such as Node.js and a webhook event handler.\n",
|
|
|
+ "\n",
|
|
|
+ "Here's an example of a basic Node.js server using Express.js:\n",
|
|
|
+ "```javascript\n",
|
|
|
+ "const express = require('express');\n",
|
|
|
+ "const app = express();\n",
|
|
|
+ "\n",
|
|
|
+ "app.use(express.json());\n",
|
|
|
+ "\n",
|
|
|
+ "app.post('/webhook', (req, res) => {\n",
|
|
|
+ " // Process webhook event\n",
|
|
|
+ " const event = req.body;\n",
|
|
|
+ " // Generate response using Llama 3\n",
|
|
|
+ " const response = generateResponse(event);\n",
|
|
|
+ " // Send response back to user\n",
|
|
|
+ " sendResponse(response);\n",
|
|
|
+ " res.status(200).send('EVENT_RECEIVED');\n",
|
|
|
+ "});\n",
|
|
|
+ "\n",
|
|
|
+ "app.listen(3000, () => {\n",
|
|
|
+ " console.log('Server listening on port 3000');\n",
|
|
|
+ "});\n",
|
|
|
+ "```\n",
|
|
|
+ "#### Step 3: Integrate Llama 3 with the Web Server\n",
|
|
|
+ "\n",
|
|
|
+ "1. Install the necessary dependencies for Llama 3, such as the Llama 3 Python library.\n",
|
|
|
+ "2. Implement a function to generate responses using Llama 3.\n",
|
|
|
+ "\n",
|
|
|
+ "Here's an example of a Python function that generates a response using Llama 3:\n",
|
|
|
+ "```python\n",
|
|
|
+ "import llama\n",
|
|
|
+ "\n",
|
|
|
+ "def generate_response(event):\n",
|
|
|
+ " # Initialize Llama 3 model\n",
|
|
|
+ " model = llama.Llama3()\n",
|
|
|
+ " # Process event and generate response\n",
|
|
|
+ " response = model.generate(event['message'])\n",
|
|
|
+ " return response\n",
|
|
|
+ "```\n",
|
|
|
+ "#### Step 4: Configure Webhook Events\n",
|
|
|
+ "\n",
|
|
|
+ "1. Go to the Facebook Developer Dashboard and navigate to your app's settings.\n",
|
|
|
+ "2. Configure the webhook events to send incoming messages to your web server.\n",
|
|
|
+ "\n",
|
|
|
+ "Here's an example of a webhook event configuration:\n",
|
|
|
+ "```json\n",
|
|
|
+ "{\n",
|
|
|
+ " \"object\": \"page\",\n",
|
|
|
+ " \"entry\": [\n",
|
|
|
+ " {\n",
|
|
|
+ " \"id\": \"PAGE_ID\",\n",
|
|
|
+ " \"time\": 1643723400,\n",
|
|
|
+ " \"messaging\": [\n",
|
|
|
+ " {\n",
|
|
|
+ " \"sender\": {\n",
|
|
|
+ " \"id\": \"USER_ID\"\n",
|
|
|
+ " },\n",
|
|
|
+ " \"recipient\": {\n",
|
|
|
+ " \"id\": \"PAGE_ID\"\n",
|
|
|
+ " },\n",
|
|
|
+ " \"timestamp\": 1643723400,\n",
|
|
|
+ " \"message\": {\n",
|
|
|
+ " \"text\": \"Hello, how are you?\"\n",
|
|
|
+ " }\n",
|
|
|
+ " }\n",
|
|
|
+ " ]\n",
|
|
|
+ " }\n",
|
|
|
+ " ]\n",
|
|
|
+ "}\n",
|
|
|
+ "```\n",
|
|
|
+ "#### Step 5: Test the Chatbot\n",
|
|
|
+ "\n",
|
|
|
+ "1. Use the Messenger app to send a message to your Facebook business page.\n",
|
|
|
+ "2. Verify that the chatbot responds with a relevant answer generated by Llama 3.\n",
|
|
|
+ "\n",
|
|
|
+ "### Best Practices\n",
|
|
|
+ "\n",
|
|
|
+ "* Ensure that your web server is secure and scalable to handle a large volume of incoming requests.\n",
|
|
|
+ "* Implement logging and monitoring to track chatbot performance and identify areas for improvement.\n",
|
|
|
+ "* Continuously update and fine-tune your Llama 3 model to improve response accuracy and relevance.\n",
|
|
|
+ "\n",
|
|
|
+ "By following these steps and best practices, you can build a Llama 3 enabled Messenger chatbot that provides an engaging and informative customer experience."
|
|
|
+ ],
|
|
|
+ "text/plain": [
|
|
|
+ "<IPython.core.display.Markdown object>"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ "metadata": {},
|
|
|
+ "output_type": "display_data"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "source": [
|
|
|
+ "# Specify the topic for the blog post\n",
|
|
|
+ "topic = \"Building a Messenger Chatbot with Llama 3\"\n",
|
|
|
+ "\n",
|
|
|
+ "# Generate and display the blog content\n",
|
|
|
+ "blog_content = generate_blog(topic)\n",
|
|
|
+ "\n",
|
|
|
+ "if isinstance(blog_content, str) and \"Error\" in blog_content:\n",
|
|
|
+ " print(blog_content)"
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "cell_type": "code",
|
|
|
+ "execution_count": null,
|
|
|
+ "id": "0930f7de",
|
|
|
+ "metadata": {},
|
|
|
+ "outputs": [],
|
|
|
+ "source": []
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "metadata": {
|
|
|
+ "kernelspec": {
|
|
|
+ "display_name": "test_blogs",
|
|
|
+ "language": "python",
|
|
|
+ "name": "python3"
|
|
|
+ },
|
|
|
+ "language_info": {
|
|
|
+ "codemirror_mode": {
|
|
|
+ "name": "ipython",
|
|
|
+ "version": 3
|
|
|
+ },
|
|
|
+ "file_extension": ".py",
|
|
|
+ "mimetype": "text/x-python",
|
|
|
+ "name": "python",
|
|
|
+ "nbconvert_exporter": "python",
|
|
|
+ "pygments_lexer": "ipython3",
|
|
|
+ "version": "3.12.11"
|
|
|
+ }
|
|
|
+ },
|
|
|
+ "nbformat": 4,
|
|
|
+ "nbformat_minor": 5
|
|
|
+}
|