0
0
Lập trình
Flame Kris
Flame Krisbacodekiller

Xây dựng bot ngôn ngữ kỹ thuật phần mềm với Ollama

Đăng vào 3 tuần trước

• 8 phút đọc

Giới thiệu

Trong bài viết này, chúng ta sẽ tìm hiểu cách xây dựng một bot ngôn ngữ kỹ thuật phần mềm bằng cách sử dụng Ollama, một mô hình LLM được lưu trữ cục bộ. Bot này sẽ có khả năng tương tác trong ngữ cảnh kỹ thuật Site Reliability Engineering (SRE). Chúng ta sẽ thấy cách thiết lập môi trường, cấu trúc ứng dụng và triển khai một giao diện người dùng đơn giản để giao tiếp với bot.

Yêu cầu trước khi bắt đầu

Trước khi bắt đầu, hãy đảm bảo rằng bạn đã cài đặt các công cụ sau:

  • Ollama: Nền tảng LLM mà chúng ta sẽ sử dụng.
  • Python 3: Ngôn ngữ lập trình của chúng ta.
  • Pip: Trình quản lý gói cho Python.

Cài đặt và chạy Ollama

Để cài đặt Ollama, bạn có thể sử dụng lệnh sau:

bash Copy
curl -fsSL https://ollama.com/install.sh | sh
ollama run llama3

Cấu trúc dự án

Chúng ta sẽ tạo cấu trúc dự án như sau:

Copy
sre-language-bot/
├── static/
│   ├── css/
│   │   └── style.css
│   └── js/
│       └── main.js
├── templates/
│   └── index.html
└── app.py

Tạm thời, các tệp CSS và JS có thể để trống.

Backend

Chúng ta sẽ thiết lập một ứng dụng Flask cơ bản trong tệp app.py:

python Copy
import os
import requests
import json
from flask import Flask, request, jsonify, render_template

# Khởi tạo Flask
app = Flask(__name__)

# Đường dẫn chính để phục vụ giao diện HTML
@app.route('/')
def index():
    return render_template('index.html')

if __name__ == '__main__':
    app.run(debug=True)

Cập nhật tệp HTML

Tiếp theo, chúng ta sẽ thêm nội dung vào tệp index.html:

html Copy
<!DOCTYPE html>
<html lang="vi">
<head>
</head>
<body>
    <h1>Chat bot sẽ ở đây</h1>
</body>
</html>

Chạy ứng dụng bằng lệnh python app.py để kiểm tra xem nó có hoạt động không.

Thêm yêu cầu POST cho bot chat

Trong tệp app.py, chúng ta sẽ thêm yêu cầu POST để tạo một endpoint /chat:

python Copy
@app.route('/chat', methods=['POST'])
def chat():
    data = request.json
    chat_history = data.get('messages', [])

    if not chat_history:
        return jsonify({'error': 'Không có lịch sử tin nhắn'}), 400

    try:
        ollama_model = "llama3"
        ollama_api_url = "http://localhost:11434/api/chat"

        payload = {
            "model": ollama_model,
            "stream": False,
            "messages": [
                            {
                                "role": "system",
                                "content": "Bạn là một trợ lý hữu ích và có kiến thức chuyên sâu về lập trình **Golang, Python, Bash và JavaScript** cũng như **Site Reliability Engineering (SRE)** và **Kubernetes**. Hãy cung cấp câu trả lời chi tiết và chính xác cho các câu hỏi kỹ thuật."
                            }
                        ] + chat_history
        }

        response = requests.post(ollama_api_url, json=payload, timeout=120)
        response.raise_for_status()

        ollama_data = response.json()
        model_response = ollama_data['message']['content']

        return jsonify({'response': model_response})
    except requests.exceptions.RequestException as e:
        return jsonify({'error': 'Kết nối tới máy chủ Ollama thất bại.'}), 500
    except Exception as e:
        return jsonify({'error': 'Đã xảy ra lỗi nội bộ.'}), 500

Bây giờ, chúng ta sẽ kiểm tra bằng cách sử dụng curl đến endpoint /chat:

bash Copy
curl -X POST -H "Content-Type: application/json" -d '{"messages": [{"role": "user", "content": "Bạn khỏe không?"}]}' http://127.0.0.1:5000/chat

Frontend

Chúng ta sẽ sử dụng Semantic UI để tạo một giao diện người dùng đơn giản cho bot chat:

html Copy
<div id="messages" class="ui segment inverted chat-container">
    <div class="ui center aligned basic inverted segment">
        <div class="sub header">Bắt đầu cuộc trò chuyện! Bạn muốn biết gì?</div>
    </div>
</div>

<div class="ui action fluid input inverted">
    <input type="text" id="user-input" placeholder="Hãy đặt câu hỏi..." autocomplete="off">
    <button class="ui button inverted green" id="send-btn">
        <i class="paper plane outline icon"></i>
    </button>
</div>

Chúng ta sẽ gọi tệp JavaScript để xử lý các cuộc gọi đến LLM và định dạng phản hồi:

html Copy
<script src="{{ url_for('static', filename='js/main.js') }}"></script>

JavaScript cho giao diện người dùng

Dưới đây là mã JavaScript trong tệp static/js/main.js:

javascript Copy
// Chờ sự kiện nhấn nút gửi trong giao diện người dùng
document.addEventListener('DOMContentLoaded', (event) => {
    const chatBox = document.getElementById('messages');
    const inputField = document.getElementById('user-input');
    const sendBtn = document.getElementById('send-btn');
    let chatHistory = [];

    const appendMessage = (message, sender) => {
        const messageDiv = document.createElement('div');
        messageDiv.classList.add('ui', 'message', 'segment');

        if (sender === 'user') {
            messageDiv.classList.add('user-message', 'right', 'aligned');
            messageDiv.innerHTML = `<p>${message}</p>`;
        } else {
            messageDiv.classList.add('model-message', 'left', 'aligned');
            messageDiv.innerHTML = marked.parse(message);
        }

        chatBox.appendChild(messageDiv);
        chatBox.scrollTop = chatBox.scrollHeight;

        if (sender === 'model') {
            hljs.highlightAll();
        }
    };

    const sendMessage = async () => {
        const message = inputField.value.trim();
        if (message === '') return;

        appendMessage(message, 'user');
        inputField.value = '';
        sendBtn.disabled = true;
        inputField.disabled = true;

        chatHistory.push({ role: 'user', content: message });

        try {
            const response = await fetch('/chat', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ messages: chatHistory })
            });

            if (response.ok) {
                const data = await response.json();
                appendMessage(data.response, 'model');
                chatHistory.push({ role: 'assistant', content: data.response });
            } else {
                appendMessage('Có lỗi xảy ra. Vui lòng thử lại.', 'model');
            }
        } catch (error) {
            appendMessage('Kết nối tới máy chủ thất bại. Vui lòng kiểm tra lại.', 'model');
        } finally {
            sendBtn.disabled = false;
            inputField.disabled = false;
            inputField.focus();
        }
    };

    sendBtn.addEventListener('click', sendMessage);
    inputField.addEventListener('keypress', (e) => {
        if (e.key === 'Enter') {
            sendMessage();
        }
    });
});

Thực hiện và kiểm tra ứng dụng

Bây giờ, bạn có thể khởi động ứng dụng bằng lệnh python app.py và truy cập vào địa chỉ http://127.0.0.1:5000 để kiểm tra bot ngôn ngữ của mình. Bạn sẽ có thể gửi câu hỏi và nhận được phản hồi từ bot.

Thực hành tốt nhất

  • Kiểm tra lỗi: Đảm bảo rằng các yêu cầu và phản hồi được kiểm tra kỹ lưỡng, bao gồm cả việc xử lý các lỗi kết nối.
  • Tối ưu hóa hiệu suất: Sử dụng caching cho các phản hồi thường xuyên để tăng tốc độ phản hồi của bot.

Các cạm bẫy phổ biến

  • Không xử lý đầy đủ các trường hợp ngoại lệ: Đảm bảo rằng mọi lỗi đều được xử lý để tránh sự cố trong ứng dụng.
  • Thiếu kiểm tra đầu vào: Luôn kiểm tra đầu vào của người dùng trước khi gửi tới bot để tránh các lỗi không mong muốn.

Kết luận

Bài viết này đã hướng dẫn bạn qua các bước để xây dựng một bot ngôn ngữ kỹ thuật phần mềm sử dụng Ollama. Bạn có thể mở rộng bot này bằng cách thêm nhiều tính năng hơn và cải thiện khả năng tương tác của nó. Hãy thử nghiệm và tối ưu hóa để tạo ra một sản phẩm tốt nhất cho người dùng của bạn!

Câu hỏi thường gặp

1. Tôi có thể sử dụng mô hình LLM khác không?
Có, bạn có thể thay thế Ollama bằng bất kỳ mô hình LLM nào khác bằng cách điều chỉnh URL API trong mã nguồn.

2. Ứng dụng có thể chạy trên môi trường sản xuất không?
Mặc định, ứng dụng này chỉ dành cho phát triển. Để chạy trên môi trường sản xuất, bạn cần cấu hình WSGI server như Gunicorn.

Tài nguyên thêm

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào