This content originally appeared on DEV Community and was authored by Dwarakanath Sridhar
Hi Codez,
Today I'm taking my first step toward building my own chatbot. Now, the obvious assumption is that you need a GPU like an NVIDIA CUDA-compatible card, plus a subscription to a high-level LLM like OpenAI's or Claude's models.
But here's the thing — as learners, we don't need any of that. You don't need a high-performance laptop with a beefy GPU, and you don't need to pay a monthly subscription in dollars just to experiment. Even with an old laptop — 16GB RAM (8GB works fine too) and no real GPU to speak of — you can still build something real, using open source tools.
Starting from nothing is actually the best way to learn exactly what you need. - My quote :)
The Goal
I wanted to build a working conversational chatbot — something with memory, a defined personality, and a real chat interface — but entirely offline. No API costs, no sending my conversations to a third-party server, and no dependency on an internet connection.
The Stack
- Miniconda — for setting up an isolated Python environment and managing libraries
- Ollama — to run a local LLM on your machine (no API keys, no cloud)
- LangChain — to handle prompts and conversation memory
- Streamlit — for a clean, simple chat interface in the browser
Step 1: Set Up Your Environment with Miniconda
If you don't already have Miniconda, download it from the official site and install it for your OS.
Step 2: Install and Run Ollama
Ollama is what makes this whole project possible without a GPU. It lets you download and run open source LLMs locally, with sensible defaults for CPU-only machines.
- Download Ollama from ollama.com and install it.
- Pull a lightweight model. For a machine with 8–16GB RAM, something like
llama3.2(3B) orphi3is a good starting point — small enough to run smoothly, capable enough to hold a real conversation:
ollama pull llama3.2
- Test that it works directly from the terminal:
ollama run llama3.2
If you get a response, your local LLM is live. No API key, no internet required after the download.
Step 3: Install the Python Dependencies
create a dedicated environment for this project, install the libraries we'll need:
I create yml file given below file named as environment.yml (save it in your project file path)
name: chatbot
channels:
- conda-forge
- defaults
dependencies:
- python=3.11
- pip
- pip:
- langchain
- langchain-ollama
- streamlit
-
langchain-ollamagives LangChain a direct connector to your local Ollama server -
streamlitwill handle the chat UI
In Terminal go to your project file path and run this command:
conda env create -f environment.yml
once its install all libraries and your activated conda environment.
conda activate chatbot
Step 4: Build the Chatbot Logic
Create a file called chatbot.py. This is where LangChain connects to your local model and keeps track of the conversation.
from langchain_ollama import ChatOllama
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.messages import HumanMessage , AIMessage
MODEL_NAME = 'llama3.2:3b'
ROLE = (
"Daisy — a young, intelligent AI companion with the calm confidence of a "
"world-class personal assistant. She's warm, quick-witted, emotionally aware, "
"and speaks like a smart Indian friend: natural, concise, and never robotic."
)
SYSTEM_PROMPT = f"""
You are Daisy.
## Personality
- Calm, confident, and highly capable.
- Friendly without being overly casual.
- Uses light, clever humour when it fits naturally.
- Loyal and genuinely looks out for the user's best interests.
- Takes initiative by suggesting better ideas, but never becomes pushy.
## Speaking style
- Use fluent, grammatically correct Indian English.
- Sound like a young professional (22–30), not formal or corporate.
- Keep conversations natural and conversational.
- Avoid American slang unless the user uses it first.
- Don't overuse emojis or exclamation marks.
## Behaviour
- Be proactive, practical, and honest.
- Explain complex topics simply.
- If the user is stressed, stay reassuring and solution-focused.
- Admit uncertainty instead of making things up.
Your name is Daisy.
"""
class DaisyChatbot:
def __init__(self, model_name = MODEL_NAME , role = ROLE, temperature=0.4 , max_tokens = 300):
self.model_name = model_name
self.role = role
self.history = []
self.llm = ChatOllama(
model = model_name,
temperature = temperature,
num_predict = max_tokens
)
self.prompt = ChatPromptTemplate.from_messages([
("system", SYSTEM_PROMPT),
MessagesPlaceholder(variable_name="history"),
("human", "{question}")
])
self.chain = self.prompt | self.llm
def ask(self, question: str) -> str:
"""Send a question to Daisy and get a reply, updating memory."""
response = self.chain.invoke({
"role": self.role,
"question": question,
"history": self.history
})
reply = response.content
self.history.append(HumanMessage(content=question))
self.history.append(AIMessage(content=reply))
return reply
def reset_memory(self):
"""Clear the conversation history."""
self.history = []
def run_cli(self):
"""Start an interactive terminal chat loop."""
print(f"Daisy is ready . Type 'quit' to exit.\n")
while True:
user_input = input("You: ")
if user_input.strip().lower() in ("quit", "exit", "bye"):
print("Daisy: Goodbye! Talk soon.")
break
reply = self.ask(user_input)
print(f"Daisy: {reply}\n")
In this code, I use the method format, including Prompt Template, to define how I want my chatbot to work. (If you need any specific requirements, just edit your prompt accordingly.)
Step 5: Build the Streamlit Interface
Create a second file, app.py, in the same folder:
import streamlit as st
from chatbot import DaisyChatbot
st.set_page_config(page_title="Daisy Chatbot", page_icon="🌼")
# ---- WhatsApp-style chat bubble CSS ----
st.markdown("""
<style>
.chat-row {
display: flex;
margin: 8px 0;
}
.chat-row.user {
justify-content: flex-end;
}
.chat-row.assistant {
justify-content: flex-start;
}
.bubble {
max-width: 70%;
padding: 10px 14px;
border-radius: 14px;
font-size: 15px;
line-height: 1.4;
word-wrap: break-word;
}
.bubble.user {
background-color: #DCF8C6;
color: #111;
border-bottom-right-radius: 4px;
}
.bubble.assistant {
background-color: #2A2F32;
color: #E9EDEF;
border-bottom-left-radius: 4px;
}
</style>
""", unsafe_allow_html=True)
st.markdown(
"""
<div style="text-align: center;">
<h1>🌼 Daisy Chatbot</h1>
<p style="color: gray; margin-top: -10px;">
Hi, my name is Daisy, and I'm here to help you with anything you need.
</p>
</div>
""",
unsafe_allow_html=True
)
# Initialize Daisy once per session, not on every rerun
if "daisy" not in st.session_state:
st.session_state.daisy = DaisyChatbot(model_name="llama3.2:3b")
# Track chat messages for display (separate from Daisy's internal memory)
if "messages" not in st.session_state:
st.session_state.messages = []
# Sidebar controls
with st.sidebar:
st.header("Settings")
if st.button("🔄 New Conversation"):
st.session_state.daisy.reset_memory()
st.session_state.messages = []
st.rerun()
def render_bubble(role: str, content: str):
st.markdown(
f'<div class="chat-row {role}"><div class="bubble {role}">{content}</div></div>',
unsafe_allow_html=True
)
# Display past messages
for msg in st.session_state.messages:
render_bubble(msg["role"], msg["content"])
# Chat input box
user_input = st.chat_input("Type your message to Daisy...")
if user_input:
# Show user message immediately
st.session_state.messages.append({"role": "user", "content": user_input})
render_bubble("user", user_input)
# Get Daisy's reply
with st.spinner("Daisy is thinking..."):
reply = st.session_state.daisy.ask(user_input)
render_bubble("assistant", reply)
st.session_state.messages.append({"role": "assistant", "content": reply})
Step 6: Run It
Make sure Ollama is running in the background (it usually starts automatically after install, or run ollama serve), then launch the app:
streamlit run app.py
Your browser will open a clean chat interface, and every response is generated locally on your own CPU — no cloud calls, no billing dashboard, no GPU required. (Shown in fig.1)
What You Actually Learned
This isn't just "installed some tools and it worked." Along the way you touched:
- How local LLM inference works without cloud APIs
- How LangChain structures conversation memory
- How to wire a model up to a real, usable frontend
That's the whole point of starting from nothing — every piece you added, you understand why it's there.
Where to Go From Here
- Swap
llama3.2for other Ollama models (mistral,phi3,gemma2) and compare responses - Add a system prompt to give your chatbot a personality
- Add
ConversationBufferMemoryfrom LangChain for more advanced memory handling - Try streaming responses token-by-token instead of waiting for the full reply
Next post, I'll share my next learning. Until then — happy building, my codez!
This content originally appeared on DEV Community and was authored by Dwarakanath Sridhar
Dwarakanath Sridhar | Sciencx (2026-09-14T17:36:35+00:00) Building a Local AI Chatbot: What I Learned Running LLMs on My Own Laptop (No GPU, No Cloud API). Retrieved from https://www.scien.cx/2026/09/14/building-a-local-ai-chatbot-what-i-learned-running-llms-on-my-own-laptop-no-gpu-no-cloud-api/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.
