Create a Gen AI App Using DeepSeek-R1 model With Langchain And Ollama

Introduction

In this article, we will be building a GenAi app using the deepseek open-source model, which is capable of generating code and other stuff based on our requirements. In building this app, we will be using open-source tools like Langchain (a framework for AI workflows), Ollama, and DeepSeek-R1. For the code for this article, you can check out my GitHub.

Why are we using DeepSeek-R1, Langchain, and Ollama?

  1. DeepSeek-R1: A highly capable open-source LLM excelling in reasoning, coding, and creative tasks.
  2. Langchain: Simplifies chaining AI components (models, prompts, databases) into cohesive workflows.
  3. Ollama: It lets you run LLMs like DeepSeek-R1, Llama3.3, and Phi-4 locally on your machine, even without a GPU.

Step 1. Download Ollama from the below link

Step 2. Now Download the DeepSeek-R1 Model with Ollama

ollama run deepseek-r1:1.5b

Step 3. Install the below library to run the model

pip install streamlit
pip install langchain_core
pip install langchain_community
pip install langchain_ollama

Now let's start writing code step-wise:

1. LLM Initialization

llm_engine = ChatOllama(
    model=selected_model,
    base_url="http://localhost:11434",
    temperature=0.3,
    streaming=True
)
  • ChatOllama: A client to interact with the local LLM hosted at localhost:11434.
  • selected_model: The LLM you’ve chosen (e.g., DeepSeek).
  • temperature=0.3: Controls randomness (0 = deterministic, 1 = creative).
  • streaming=True: Enables real-time response streaming.

2. System Prompt Configuration

system_prompt = SystemMessagePromptTemplate.from_template(
    "You are an expert AI coding assistant..."
)
  • Defines the initial behavior of the AI (concise, correct, and with debugging tips).
  • Acts like giving context to the model before the conversation starts.

3. Session State Management

if "message_log" not in st.session_state:
    st.session_state.message_log = [{"role": "ai", "content": "Hi! I'm DeepSeek..."}]
  • st.session_state: Maintains chat history across interactions.
  • The first message is a greeting from the AI if no prior chat exists.

4. Display Chat History

def display_chat_history():
    for message in st.session_state.message_log:
        with st.chat_message(message["role"]):
            st.markdown(message["content"])
  • Iterates through all past messages (both user and AI).
  • Displays them with appropriate roles (user or AI) using st.chat_message().

5. Prompt Chain Building

def build_prompt_chain():
    prompt_sequence = [system_prompt]
    for msg in st.session_state.message_log:
        if msg["role"] == "user":
            prompt_sequence.append(HumanMessagePromptTemplate.from_template(msg["content"]))
        elif msg["role"] == "ai":
            prompt_sequence.append(AIMessagePromptTemplate.from_template(msg["content"]))
    return ChatPromptTemplate.from_messages(prompt_sequence)
  • Initialization: The function starts by adding a system_prompt to the prompt sequence to set the AI's behavior.
  • Conversation History Processing: It loops through st.session_state.message_log, adding user messages with HumanMessagePromptTemplate and AI responses with AIMessagePromptTemplate.
  • Prompt Chain Creation: Finally, it returns a ChatPromptTemplate containing the system prompt and full conversation history for context-aware AI responses.

6. Generating AI Response with Streaming

def generate_response():
    prompt_chain = build_prompt_chain()
    processing_pipeline = prompt_chain | llm_engine | StrOutputParser()
    return processing_pipeline.stream({})
  • Chains together: Prompt, LLM, and Output Parser
  • stream(): Streams the response chunk-by-chunk, enabling real-time typing effects.

Below is the combined code in below code. I have added streamlit and html&css code to see the the app on the UI.

import streamlit as st
from langchain_ollama import ChatOllama
from langchain_core.output_parsers import StrOutputParser

from langchain_core.prompts import (
    SystemMessagePromptTemplate,
    HumanMessagePromptTemplate,
    AIMessagePromptTemplate,
    ChatPromptTemplate
)
import warnings
import sys

# Custom CSS styling for the app 
st.markdown("""
<style>
    /* Existing styles */
    .main {
        background-color: #1a1a1a;
        color: #ffffff;
    }
    .sidebar .sidebar-content {
        background-color: #2d2d2d;
    }
    .stTextInput textarea {
        color: #ffffff !important;
    }

    /* Add these new styles for select box */
    .stSelectbox div[data-baseweb="select"] {
        color: white !important;
        background-color: #3d3d3d !important;
    }

    .stSelectbox svg {
        fill: white !important;
    }

    .stSelectbox option {
        background-color: #2d2d2d !important;
        color: white !important;
    }

    /* For dropdown menu items */
    div[role="listbox"] div {
        background-color: #2d2d2d !important;
        color: white !important;
    }
</style>
""", unsafe_allow_html=True)
st.title("🧠 DeepSeek Code Companion build by Lokendra")
st.caption("🚀 Your AI Pair Programmer with Debugging Superpowers")

# Sidebar configuration
with st.sidebar:
    st.header("⚙️ Configuration")
    selected_model = st.selectbox(
        "Choose Model",
        ["deepseek-r1:1.5b", "deepseek-r1:3b", "deepseek-r1:7b", "deepseek-r1:8b"],
        index=0
    )
    st.divider()
    st.markdown("### Model Capabilities")
    st.markdown("""
    - 🐍 Code genaration
    - 🐞 Debugging Assistant
    - 📝 Documentation
    """)
    st.divider()

    st.markdown("### 🔗 Resources")
    st.markdown("""
    - [Ollama Documentation](https://ollama.ai/)
    - [LangChain Guides](https://python.langchain.com/)
    - [DeepSeek GitHub](https://github.com/deepseek-ai)
    """)

# main code logic starts from hare
# Initialize chat engine with selected model(Deepseek)
llm_engine = ChatOllama(
    model=selected_model,
    base_url="http://localhost:11434",
    temperature=0.3,
    streaming=True
)

# System prompt configuration
system_prompt = SystemMessagePromptTemplate.from_template(
    "You are an expert AI coding assistant. Provide concise, correct solutions "
    "with strategic print statements for debugging. Always respond in English."
)

# Session state management
if "message_log" not in st.session_state:
    st.session_state.message_log = [{
        "role": "ai", 
        "content": "Hi! I'm DeepSeek. How can I help you code today? 💻"
    }]

# Display chat messages
def display_chat_history():
    for message in st.session_state.message_log:
        with st.chat_message(message["role"]):
            st.markdown(message["content"])

# Build the prompt chain
def build_prompt_chain():
    prompt_sequence = [system_prompt]
    for msg in st.session_state.message_log:
        if msg["role"] == "user":
            prompt_sequence.append(HumanMessagePromptTemplate.from_template(msg["content"]))
        elif msg["role"] == "ai":
            prompt_sequence.append(AIMessagePromptTemplate.from_template(msg["content"]))
    return ChatPromptTemplate.from_messages(prompt_sequence)

# Generate AI response with streaming
def generate_response():
    prompt_chain = build_prompt_chain()
    processing_pipeline = prompt_chain | llm_engine | StrOutputParser()
    return processing_pipeline.stream({})

# Display chat history
display_chat_history()

# Handle user input
user_query = st.chat_input("Type your coding question here...")

if user_query:
    # Add user message to history
    st.session_state.message_log.append({"role": "user", "content": user_query})

    # Display user message immediately
    with st.chat_message("user"):
        st.markdown(user_query)

    # Create placeholder for assistant response
    with st.chat_message("ai"):
        response_placeholder = st.empty()
        response_placeholder.markdown('<div class="typing-indicator">Generating<span class="dot"></span><span class="dot"></span><span class="dot"></span></div>', unsafe_allow_html=True)

    # Generate and stream response
    full_response = ""
    for chunk in generate_response():
        full_response += chunk
        response_placeholder.markdown(full_response + "▌")

    # Update final response
    response_placeholder.markdown(full_response)

    # Add assistant response to history
    st.session_state.message_log.append({"role": "ai", "content": full_response})

To run the above code, you have to use the below command:

streamlit run app.py

Now you are ready to ask any type of question from your genAi application without using the internet like below:

Localhost

Conclusion

By using DeepSeek-R1, Langchain, and Ollama, we've built a powerful Gen AI application capable of generating intelligent responses. This architecture can be extended to support complex workflows, real-time data processing, and advanced NLP tasks.


Similar Articles