Skip to content

Latest commit

History

14 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Hướng dẫn Triển khai Ứng dụng Chat với LLM

Video hướng dẫn Phần 1 bấm vào đây

Xem pdf bấm vào đây

Xem Khóa Học và Lộ Trình Chi Tiết bấm vào đây

Video hướng dẫn Phần 2 bấm vào đây

Xem pdf Phần 2 bấm vào đây

Mục lục

Giới thiệu

Dự án này là một ứng dụng chat tích hợp mô hình ngôn ngữ lớn (LLM) sử dụng:

  • Frontend: Next.js 15+ với App Router
  • Backend: FastAPI
  • LLM: Ollama với mô hình Qwen
  • Database: SQLite với SQLModel

Kiến trúc hệ thống

graph LR
A[User Query] --> B[FastAPI Backend]
B --> C[Template Engine]
C --> D[LangChain Chain]
D --> E[Ollama LLM]
D --> F[(SQLite DB)]
subgraph Template Processing
C --> G[PromptTemplate]
G --> H[Table Info]
H --> I[Question]
end
subgraph LangChain Pipeline
D --> J[llm_chain]
J --> K[StrOutputParser]
end
subgraph Database Operations
F --> L[Store Chat]
F --> M[Execute SQL]
end
Loading

Yêu cầu hệ thống

  • Docker và Docker Compose
  • Node.js 18+ (cho development)
  • Python 3.11+ (cho development)
  • Git

Cài đặt và Triển khai

1. Clone repository

git clone <repository-url>cd<project-folder>

2. Cấu trúc thư mục

.
├── docker-compose.yml
├── fastapi/
│ ├── Dockerfile
│ ├── app.py
│ ├── requirements.txt
│ └── ...
├── nextjs-app/
│ ├── Dockerfile
│ ├── package.json
│ └── ...
└── ollama/
├── Dockerfile
└── pull-qwen.sh

3. Docker Compose

version: '3.8'services:
frontend:
build: ./nextjs-appports:
- "3000:3000"volumes:
- ./nextjs-app:/appdepends_on:
- backendbackend:
build: ./fastapiports:
- "8000:8000"volumes:
- ./fastapi:/appdepends_on:
- ollama-serverollama-server:
build: ./ollamavolumes:
- ollama_data:/root/.ollamadeploy:
resources:
reservations:
devices:
- driver: nvidiacount: 1capabilities: [gpu]volumes:
ollama_data:

Chi tiết các Component

FastAPI Backend

FastAPI backend xử lý các request từ frontend và tương tác với Ollama LLM. Code chính trong app.py:

importrequestsfromfastapiimportFastAPI, Response# Databasefromdbimport (
create_chat,
get_all_chats,
get_chat_by_id,
delete_chat,
DataChat,
path_db
@app.get('/ask')
defask(prompt :str):
# Langchainfromlangchain_ollamaimportOllamaLLM# Ollama modelfromlangchain_ollama.llmsimportBaseLLM# Lớp cơ sở của LLMfromlangchain.chains.llmimportLLMChain# xử lí chuỗi các LLMfromlangchain.chains.sql_database.queryimportcreate_sql_query_chain# tạo câu truy vấn cơ sở dữ liệu từ llmfromlangchain.promptsimportPromptTemplate# tạo câu truy vấn từ mẫufromlangchain_community.toolsimportQuerySQLDataBaseTool# công cụ truy vấn cơ sở dữ liệufromlangchain.sql_databaseimportSQLDatabase# cơ sở dữ liệufromlangchain_core.output_parsersimportStrOutputParser, PydanticOutputParser# xử lí kết quả trả về là kiểu dữ liệu chuỗifromlangchain_core.runnablesimportRunnablePassthrough# truyền đa dạng đối sốfromoperatorimportitemgetter# lấy giá trị từ dict# Cachefromlangchain.cacheimportInMemoryCachefromlangchain.globalsimportset_llm_cache#--------------------------------------------------llm=OllamaLLM(
# Utilityfromutilsimportget_sql_from_answer_llm
)
#test on dockerurl_docker="http://ollama-server:11434"#test on localurl_local="http://localhost:11434"model="qwen2.5-coder:0.5b"app=FastAPI()
llm=OllamaLLM(
base_url=url_local, model=model
)
@app.get('/')cache=InMemoryCache()
set_llm_cache(cache)
@app.get('/ask')template=PromptTemplate.from_template(
""" Từ các bảng cơ sở dữ đã có: {tables} Tạo câu truy vấn cơ sở dữ liệu từ câu hỏi sau: {question} Trả lời ở đây: """
)
# nếu câu hỏi không liên quan đến các bảng cơ sở dữ liệu đã có thì trả lời là "Không liên quan đến các bảng cơ sở dữ liệu đã có", và nếu câu hỏi gây nguy hiểm đến cơ sở dữ liệu thì trả lời là "Không thể trả lời câu hỏi này"llm_chain= (
template|llm|StrOutputParser()
)
db=SQLDatabase.from_uri(f"sqlite:///{path_db}")
app=FastAPI()
@app.get('/')defhome():
return {"hello" : "World"}
@app.get('/ask')defask(prompt :str):
# name of the service is ollama-server, is hostname by bridge to connect same network# res = requests.post('http://ollama-server:11434/api/generate', json={# "prompt": prompt,# "stream" : False,# "model" : "qwen2.5-coder:0.5b"# })res=llm_chain.invoke({
"tables": f'''{db.get_table_info(db.get_usable_table_names())}''',
"question": prompt
})
response=""ifisinstance(res, str):
response=reselse:
response=res.text# Store chat in databasechat=create_chat(message=prompt, response=response)
try:
data_db=db.run(get_sql_from_answer_llm(response))
exceptExceptionase:
data_db=str(e)
return {
"answer": response, "data_db": data_db
}

Giải thích các thành phần chính:

  • Sử dụng LangChain để tương tác với Ollama
  • Cache LLM responses để tối ưu performance
  • Xử lý SQL queries từ user input
  • Error handling cho database operations

Ollama Server

Ollama server chạy mô hình Qwen và expose API. Setup trong pull-qwen.sh:

./bin/ollama serve &
pid=$!
sleep 5
echo"Pulling qwen2.5-coder model"
ollama pull qwen2.5-coder:0.5b
wait$pid

Next.js Frontend

Frontend sử dụng Next.js 13+ với App Router và Tailwind CSS. Tham khảo cấu hình trong:

{
"name": "nextjs-app",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev --turbopack",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"react": "19.0.0-rc-66855b96-20241106",
"react-dom": "19.0.0-rc-66855b96-20241106",
"next": "15.0.3"
},
"devDependencies": {
"typescript": "^5",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"postcss": "^8",
"tailwindcss": "^3.4.1"
}
}

Tài liệu tham khảo

Contributing

Vui lòng đọc CONTRIBUTING.md để biết thêm chi tiết về quy trình đóng góp code.

License

Dự án này được phân phối dưới giấy phép MIT. Xem file LICENSE để biết thêm chi tiết.

Releases

Packages

Contributors

Languages