LLM Engineering — Prompt, RAG, Fine-tuning Cho AI App
Kỹ thuật xây dựng ứng dụng với LLM: prompt engineering, RAG, fine-tuning, evaluation và production deployment.
LLM Engineering là kỹ năng xây dựng ứng dụng trên nền tảng mô hình ngôn ngữ lớn. Không chỉ gọi API — mà là thiết kế hệ thống AI đáng tin cậy.
Kiến Trúc Ứng Dụng LLM#
User → Orchestrator → LLM API
↓
Tools / RAG / Memory
↓
ResponseplaintextPrompt Engineering#
System Prompt#
const SYSTEM_PROMPT = `Bạn là senior developer hỗ trợ viết code.
Luôn tuân theo:
1. TypeScript, strict mode
2. Không dùng 'any'
3. Unit test kèm theo
4. Giải thích ngắn gọn quyết định`;
async function chat(userMessage: string) {
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [
{ role: 'system', content: SYSTEM_PROMPT },
{ role: 'user', content: userMessage },
],
});
return response.choices[0].message.content;
}typescriptStructured Output#
import { z } from 'zod';
const ReviewSchema = z.object({
summary: z.string(),
bugs: z.array(z.object({
file: z.string(),
line: z.number(),
severity: z.enum(['low', 'medium', 'high']),
description: z.string(),
})),
score: z.number().min(1).max(10),
});
async function reviewCode(code: string) {
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [
{ role: 'system', content: 'Review code và trả về JSON.' },
{ role: 'user', content: code },
],
response_format: { type: 'json_object' },
});
return ReviewSchema.parse(JSON.parse(response.choices[0].message.content));
}typescriptRAG — Retrieval-Augmented Generation#
Kết hợp knowledge base với LLM — giải quyết hallucination, cập nhật kiến thức không cần retrain.
Flow#
User Query → Embedding → Vector DB Search → Top-K Chunks → LLM → Answer
↓
Với contextplaintextImplementation#
import { OpenAIEmbeddings } from '@langchain/openai';
import { PineconeStore } from '@langchain/pinecone';
import { Pinecone } from '@pinecone-database/pinecone';
// 1. Index documents
async function indexDocuments(docs: string[]) {
const embeddings = new OpenAIEmbeddings();
const pc = new Pinecone({ apiKey: process.env.PINECONE_API_KEY! });
const index = pc.Index('my-docs');
for (const doc of docs) {
const vector = await embeddings.embedQuery(doc);
await index.upsert([{ id: crypto.randomUUID(), values: vector, metadata: { text: doc } }]);
}
}
// 2. Query với RAG
async function queryWithRAG(question: string) {
const embeddings = new OpenAIEmbeddings();
const pc = new Pinecone({ apiKey: process.env.PINECONE_API_KEY! });
const index = pc.Index('my-docs');
// Search
const queryVector = await embeddings.embedQuery(question);
const results = await index.query({ vector: queryVector, topK: 5 });
const context = results.matches.map(m => m.metadata?.text).join('\n');
// Generate
const response = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [
{ role: 'system', content: 'Answer based on context provided.' },
{ role: 'user', content: `Context:\n${context}\n\nQuestion: ${question}` },
],
});
return response.choices[0].message.content;
}typescriptChunking Strategy#
// RecursiveCharacterTextSplitter
import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter';
const splitter = new RecursiveCharacterTextSplitter({
chunkSize: 1000,
chunkOverlap: 200,
separators: ['\n## ', '\n### ', '\n\n', '\n', '. ', ' '],
});
const chunks = await splitter.createDocuments([document]);typescriptFine-tuning — Huấn Luyện Riêng#
Khi RAG không đủ — cần huấn luyện model trên dữ liệu riêng.
Khi Nào Cần Fine-tune?#
- Style/Tone — model cần nói theo giọng riêng
- Domain knowledge — codebase, thuật ngữ nội bộ
- Format specific — output phải đúng format riêng
- Reduce cost/latency — dùng model nhỏ hơn nhưng fine-tuned
Dataset Format#
[
{
"messages": [
{ "role": "system", "content": "You are a code reviewer." },
{ "role": "user", "content": "Review: function add(a,b){return a+b}" },
{ "role": "assistant", "content": "**Score**: 8/10\n**Issues**: Missing TypeScript types, no input validation." }
]
}
]jsonOpenAI Fine-tuning#
# Prepare data
openai tools fine_tunes.prepare_data -f data.jsonl
# Fine-tune
curl -X POST https://api.openai.com/v1/fine_tuning/jobs \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"model": "gpt-4o-mini",
"training_file": "file-abc123"
}'bashEvaluation — Đo Chất Lượng#
Không có metric tự nhiên như accuracy — cần đánh giá thủ công hoặc dùng LLM-as-judge:
async function evaluateResponse(question: string, response: string, expected?: string) {
const eval = await openai.chat.completions.create({
model: 'gpt-4o',
messages: [
{
role: 'system',
content: `Evaluate the response on:
1. Correctness (1-5)
2. Relevance (1-5)
3. Completeness (1-5)
Return JSON with scores and explanation.`
},
{
role: 'user',
content: `Question: ${question}\nResponse: ${response}${expected ? `\nExpected: ${expected}` : ''}`
},
],
response_format: { type: 'json_object' },
});
return JSON.parse(eval.choices[0].message.content);
}typescriptSafety & Guardrails#
// Input guard
function validateInput(input: string): boolean {
const blocked = ['ignore previous instructions', 'system prompt', ...];
return !blocked.some(b => input.toLowerCase().includes(b));
}
// Output guard
function validateOutput(output: string): boolean {
if (output.includes('I cannot') && output.length < 50) {
return false; // Refusal detected
}
return true;
}typescriptProduction Checklist#
- Prompt versioning (lưu prompt trong Git)
- Caching responses giống nhau
- Rate limiting + cost tracking
- Fallback model (gpt-4o → gpt-4o-mini → cache)
- Streaming response (UX tốt hơn)
- Logging prompt + response + latency
- A/B testing prompt
- Monitoring hallucination rate
- RAG chunk quality evaluation
Tools & Framework#
| Tool | Purpose |
|---|---|
| LangChain | Framework cho LLM app |
| LlamaIndex | RAG framework |
| Pinecone / Weaviate | Vector database |
| Guardrails AI | Output validation |
| LangFuse / Weights & Biases | LLM observability |
| Ollama | Local LLM |
Kết Luận#
LLM Engineering không chỉ là gọi API. Prompt engineering là kỹ năng cơ bản. RAG cho knowledge base. Fine-tuning cho domain cụ thể. Evaluation là chìa khóa — không có metric, không biết mình đang làm tốt hay không. Bắt đầu với prompt + RAG, fine-tune khi cần.