The journey to today’s sophisticated chatbots began decades ago with simple rule-based systems. The field of natural language processing (NLP) has undergone several revolutions:
1. Early Systems (1960s-1990s): ELIZA (1966) and PARRY (1972) used pattern matching to simulate conversation, but had no real understanding.
2. Statistical NLP (1990s-2010s): Systems began using probabilistic models and machine learning, but remained limited in scope.
3. Neural Networks Revolution (2010s): The introduction of word embeddings (Word2Vec, 2013) and sequence models (LSTMs) improved language understanding.
4. Transformer Breakthrough (2017): Google’s Transformer paper introduced the self-attention mechanism, enabling models to process entire sentences at once rather than word-by-word.
5. Large Language Models (2018-present): GPT (2018), BERT (2018), and their successors demonstrated that scaling up model size and training data led to remarkable emergent capabilities. Models like GPT-3 (2020) and LLaMA (2023) showed that with sufficient scale, LLMs could perform tasks they weren’t explicitly trained for.
Today’s chatbots leverage these advances to provide human-like interactions while maintaining the speed and scalability of software.
Implementing a Custom Website Chatbot
Architecture Overview
Our implementation consists of two main components:
1. Backend API: FastAPI server connecting to Hugging Face’s inference API
2. Frontend Interface: HTML/CSS/JavaScript chat widget
Backend Implementation (llama_api.py)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel from huggingface_hub import InferenceClient app = FastAPI() #Eitors NOTE Enable CORS for local development; restrict in production app.add_middleware( CORSMiddleware, allow_origins=["*"], #Eitors NOTE Change to your domain in production! allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) client = InferenceClient( provider="hyperbolic", api_key="YOUR API KEY"#charges may be incured ) class ChatMessage(BaseModel): messages: list # [{"role": "user"/"assistant", "content": "..."}] @app.post("/chat") async def chat_with_llama(payload: ChatMessage): resp = client.chat.completions.create( model="meta-llama/Llama-3.2-3B-Instruct", messages=payload.messages, stream=False ) return {"response": resp.choices[0].message.content} |
Key features:
– FastAPI provides a modern Python web framework
– CORS middleware enables frontend-backend communication
– System prompt defines the chatbot’s personality and behavior
– Simple endpoint that forwards messages to LLaMA 3 via Hugging Face
Frontend Implementation (index.html)
copy and run on your computer!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>KNCMAP-TECHNOLOGIES</title> <style> body { font-family: Arial, sans-serif; padding: 20px; background: #f4f4f4; } /* Chat Popup Styles */ .chat-popup { display: none; position: fixed; bottom: 20px; right: 20px; width: 350px; height: 500px; background: white; border-radius: 15px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); z-index: 1000; overflow: hidden; flex-direction: column; } .chat-header { background: #4f46e5; color: white; padding: 15px; font-weight: bold; display: flex; justify-content: space-between; align-items: center; } .chat-close { cursor: pointer; font-size: 20px; } .chat-body { flex: 1; padding: 15px; overflow-y: auto; background: #f9fafb; } .chat-input-container { padding: 10px; background: white; border-top: 1px solid #e5e7eb; display: flex; gap: 8px; } .chat-input { flex: 1; padding: 10px; border: 1px solid #e5e7eb; border-radius: 8px; outline: none; } .chat-submit { background: #4f46e5; color: white; border: none; border-radius: 8px; padding: 0 15px; cursor: pointer; display: flex; align-items: center; justify-content: center; } .chat-submit:hover { background: #4338ca; } .chat-button { position: fixed; bottom: 20px; right: 20px; background: #4f46e5; color: white; width: 60px; height: 60px; border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2); z-index: 999; } .chat-button i { font-size: 24px; } .message { margin-bottom: 15px; max-width: 80%; padding: 10px 15px; border-radius: 18px; line-height: 1.4; word-wrap: break-word; word-break: break-word; white-space: pre-line; } .user-message { background: #4f46e5; color: white; margin-left: auto; border-bottom-right-radius: 5px; } .bot-message { background: #e5e7eb; color: #111827; margin-right: auto; border-bottom-left-radius: 5px; } /* Loading indicator */ .typing-indicator { display: inline-block; padding: 10px 15px; background: #e5e7eb; border-radius: 18px; border-bottom-left-radius: 5px; margin-bottom: 15px; } .typing-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: #6b7280; margin-right: 3px; animation: typingAnimation 1.4s infinite ease-in-out; } .typing-dot:nth-child(1) { animation-delay: 0s; } .typing-dot:nth-child(2) { animation-delay: 0.2s; } .typing-dot:nth-child(3) { animation-delay: 0.4s; } @keyframes typingAnimation { 0%, 60%, 100% { transform: translateY(0); } 30% { transform: translateY(-5px); } } </style> </head> <body> <div style="max-width: 800px; margin: auto;"> <h2>KNCMAP-TECHNOLOGIES</h2> <p>Welcome to our website. Click the chat button to interact with our AI assistant.</p> </div> <!-- Chat Button --> <div class="chat-button" onclick="toggleChat()"> <i>chat</i> </div> <!-- Chat Popup --> <div class="chat-popup" id="chatPopup"> <div class="chat-header"> <span>KNCMAP AI Assistant</span> <span class="chat-close" onclick="toggleChat()">×</span> </div> <div class="chat-body" id="chatBody"> <!-- Initial greeting message --> <div class="message bot-message"> Hello! I'm the KNCMAP-TECHNOLOGIES AI Assistant. How can I help you today? </div> </div> <div class="chat-input-container"> <input type="text" class="chat-input" id="userInput" placeholder="Type your message..." onkeypress="handleKeyPress(event)"> <button class="chat-submit" onclick="sendMessage()">Send</button> </div> </div> <script> // Maintain chat history let chatHistory = [ { role: "assistant", content: "Hello! I'm the KNCMAP-TECHNOLOGIES AI Assistant. How can I help you today?" } ]; function toggleChat() { const popup = document.getElementById('chatPopup'); popup.style.display = popup.style.display === 'flex' ? 'none' : 'flex'; if (popup.style.display === 'flex') { document.getElementById('userInput').focus(); } } function handleKeyPress(event) { if (event.key === 'Enter') { sendMessage(); } } async function sendMessage() { const userInput = document.getElementById('userInput'); const message = userInput.value.trim(); if (message) { // Add user message to chat addMessage(message, 'user'); chatHistory.push({ role: "user", content: message }); userInput.value = ''; // Show typing indicator showTypingIndicator(); try { // Call your FastAPI endpoint const response = await fetch("https://chatbot.treyzz.com/chat", {// use your api if you have method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ messages: chatHistory }) }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); // Add AI response to chat addMessage(data.response, 'bot'); chatHistory.push({ role: "assistant", content: data.response }); } catch (error) { console.error("Error calling API:", error); addMessage("Sorry, I'm having trouble connecting to the server. Please try again later.", 'bot'); } finally { removeTypingIndicator(); } } } function addMessage(text, sender) { const chatBody = document.getElementById('chatBody'); const messageDiv = document.createElement('div'); messageDiv.className = `message ${sender}-message`; messageDiv.textContent = text; chatBody.appendChild(messageDiv); chatBody.scrollTop = chatBody.scrollHeight; } function showTypingIndicator() { const chatBody = document.getElementById('chatBody'); const typingDiv = document.createElement('div'); typingDiv.className = 'typing-indicator'; typingDiv.id = 'typingIndicator'; typingDiv.innerHTML = ` <div class="typing-dot"></div> <div class="typing-dot"></div> <div class="typing-dot"></div> `; chatBody.appendChild(typingDiv); chatBody.scrollTop = chatBody.scrollHeight; } function removeTypingIndicator() { const typingIndicator = document.getElementById('typingIndicator'); if (typingIndicator) { typingIndicator.remove(); } } </script> </body> </html> |
Deployment Considerations
1. Backend Hosting: Deploy your FastAPI server using services like:
– AWS EC2 or Lambda
– Google Cloud Run
– Azure App Service
– Heroku
– Vercel (with serverless functions)
2. Frontend Integration:
– Add the chat widget to your existing website by copying the HTML/CSS/JS
– Update the API endpoint URL in the JavaScript to point to your deployed backend
3. Security:
– Restrict CORS to your production domain
– Consider adding rate limiting
– Protect your API keys
4. Scaling:
– Add caching for frequent queries
– Implement connection pooling for database access if needed
– Monitor performance as usage grows
Customization Options
1. Branding:
– Update colors to match your brand
– Customize the assistant’s avatar and greeting
2. Functionality:
– Add support for file uploads
– Implement conversation history storage
– Add quick reply buttons for common questions
3. Advanced Features:
– Integrate with your knowledge base
– Add multilingual support
– Implement sentiment analysis for better responses
Conclusion
Implementing a custom chatbot has never been easier thanks to modern LLMs and web technologies. This implementation gives you full control over the user experience while leveraging powerful AI capabilities. By hosting your own solution, you ensure data privacy and can customize the experience to perfectly match your brand and use case.
Free API Script
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
<script> // Maintain chat history let chatHistory = [ { role: "assistant", content: "Hello! I'm the KNCMAP-TECHNOLOGIES AI Assistant. How can I help you today?" } ]; function toggleChat() { const popup = document.getElementById('chatPopup'); popup.style.display = popup.style.display === 'flex' ? 'none' : 'flex'; if (popup.style.display === 'flex') { document.getElementById('userInput').focus(); } } function handleKeyPress(event) { if (event.key === 'Enter') { sendMessage(); } } async function sendMessage() { const userInput = document.getElementById('userInput'); const message = userInput.value.trim(); if (message) { // Add user message to chat addMessage(message, 'user'); chatHistory.push({ role: "user", content: message }); userInput.value = ''; // Show typing indicator showTypingIndicator(); try { // Call your FastAPI endpoint const response = await fetch("https://chatbot.treyzz.com/chat", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ messages: chatHistory }) }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); // Add AI response to chat addMessage(data.response, 'bot'); chatHistory.push({ role: "assistant", content: data.response }); } catch (error) { console.error("Error calling API:", error); addMessage("Sorry, I'm having trouble connecting to the server. Please try again later.", 'bot'); } finally { removeTypingIndicator(); } } } function addMessage(text, sender) { const chatBody = document.getElementById('chatBody'); const messageDiv = document.createElement('div'); messageDiv.className = `message ${sender}-message`; messageDiv.textContent = text; chatBody.appendChild(messageDiv); chatBody.scrollTop = chatBody.scrollHeight; } function showTypingIndicator() { const chatBody = document.getElementById('chatBody'); const typingDiv = document.createElement('div'); typingDiv.className = 'typing-indicator'; typingDiv.id = 'typingIndicator'; typingDiv.innerHTML = ` <div class="typing-dot"></div> <div class="typing-dot"></div> <div class="typing-dot"></div> `; chatBody.appendChild(typingDiv); chatBody.scrollTop = chatBody.scrollHeight; } function removeTypingIndicator() { const typingIndicator = document.getElementById('typingIndicator'); if (typingIndicator) { typingIndicator.remove(); } } </script> |
The combination of FastAPI for the backend and a simple JavaScript frontend makes this solution accessible to developers of all skill levels while remaining robust enough for production use.