Hoàn thành bài "Lesson 5: Xử lý lỗi và Độ tin cậy trong Hệ thống Tác vụ" trước để mở khoá bài này.Đến bài trước

Introduction

Ở các bài học trước bạn đã học cách thiết kế prompts, kết nối với API AI và cấu trúc một quy trình làm việc của agent. Bài học này ghép tất cả lại với nhau: bạn sẽ xây dựng một tính năng được hỗ trợ AI hoàn chỉnh bên trong một ứng dụng web thực tế, từ giao diện người dùng cho đến đánh giá. Tính năng ví dụ mà chúng ta sử dụng xuyên suốt là một người rà soát mã nguồn được hỗ trợ AI, nhận một đoạn mã do người dùng dán và trả về phản hồi cùng một thang đánh giá chất lượng.

Mục tiêu không phải viết mã production hoàn hảo. Mục tiêu là hiểu mọi lớp của ngăn xếp — dạng form frontend, điểm cuối backend, prompt, gọi API, phân tích phản hồi và kiểm thử — để bạn có thể lặp lại mẫu cho bất kỳ tính năng nào.

Cấu trúc dự án

Một ứng dụng Node.js/Express nhỏ là đủ để trình diễn toàn bộ chu trình. Backend phơi bày một tuyến đường nhận văn bản mã, gửi nó đến mô hình AI và trả về phản hồi có cấu trúc. Frontend là một mẫu HTML đơn giản đăng bài đoạn mã và hiển thị kết quả.

sơ đồ kiến trúc 4 tầng của tính năng AI gồm biểu mẫu frontend, endpoint backend, lệnh gọi API AI và hiển thị phản hồi
javascript
// server.js
import express from "express";
import { reviewCode } from "./agent.js";
const app = express();
app.use(express.json());
app.use(express.static("public"));
app.post("/api/review", async (req, res) => {
const { code } = req.body;
if (!code || code.length < 5) {
return res.status(400).json({ error: "Code snippet required" });
}
const result = await reviewCode(code);
res.json(result);
});
app.listen(3000, () => console.log("Server on http://localhost:3000"));

Lớp Agent

Agent là một module thuần túy nắm giữ mẫu prompt và lời gọi API. Việc tách riêng nó khỏi trình xử lý tuyến đường giúp dễ kiểm thử độc lập. Prompt yêu cầu mô hình trả về JSON với một thang điểm và danh sách các vấn đề, điều này loại bỏ nhu cầu phân tích chuỗi fragile sau này.

javascript
// agent.js
import OpenAI from "openai";
const client = new OpenAI();
export async function reviewCode(code) {
const prompt = `You are a senior code reviewer. Analyze the following code and respond ONLY with valid JSON in this exact shape:
{"score": <number 0-100>, "issues": [{"line": <number or null>, "severity": "low|medium|high", "message": "<text>"}], "summary": "<one sentence>"}
Code:
${code}`;
const response = await client.chat.completions.create({
model: "gpt-4o-mini",
messages: [{ role: "user", content: prompt }],
temperature: 0.2,
response_format: { type: "json_object" }
});
return JSON.parse(response.choices[0].message.content);
}

Lớp Frontend

Giao diện người dùng (UI) được thiết kế tối giản một cách có chủ ý. Một ô textarea cho mã, một nút gửi, và một bảng kết quả. Đăng tải JSON giúp cho mã đồng nhất với backend và tránh sự cố với encoding của form.

html
<form id="review-form">
<textarea id="code" rows="10" placeholder="Paste your code here"></textarea>
<button type="submit">Review</button>
</form>
<pre id="result"></pre>
<script>
document.getElementById("review-form").onsubmit = async (e) => {
e.preventDefault();
const code = document.getElementById("code").value;
const res = await fetch("/api/review", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ code })
});
const data = await res.json();
document.getElementById("result").textContent = JSON.stringify(data, null, 2);
};
</script>

Kiểm thử Tính năng

Kiểm thử ở mức đơn vị cho agent trực tiếp là cách nhanh nhất để bắt các sự cố quay vòng của prompt. Xây dựng một tập hợp nhỏ các snippet mã với phạm vi điểm mong đợi và chạy chúng liên tục. Nếu một điều chỉnh prompt làm mất đi một trường hợp, bạn sẽ thấy ngay lập tức.

sơ đồ vòng lặp kiểm thử gồm 4 bước: chạy test case, gọi agent, so sánh đầu ra với khoảng giá trị kỳ vọng và ghi nhật ký kết quả
javascript
// test.js
import { reviewCode } from "./agent.js";
const cases = [
{ code: "def add(a,b): return a+b", expectMin: 70 },
{ code: "eval(input())", expectMax: 30 },
{ code: "function f(){ while(true){} }", expectMax: 40 }
];
for (const c of cases) {
const r = await reviewCode(c.code);
const ok = (c.expectMin ? r.score >= c.expectMin : true) &&
(c.expectMax ? r.score <= c.expectMax : true);
console.log(`${ok ? "PASS" : "FAIL"} score=${r.score} code=${c.code.slice(0,30)}`);
}

Các lỗi phổ biến

Ba vấn đề thường xuất hiện lặp đi lặp lại. Thứ nhất, không đặt response_format thành json_object khi bạn cần đầu ra có cấu trúc, điều này gây ra các lỗi phân tích dữ liệu ẩn. Thứ hai, quên xác thực độ dài đầu vào phía máy chủ, cho phép người dùng gửi các prompt quá lớn và gây phát sinh chi phí. Thứ ba, chỉ kiểm thử với mã hoàn hảo, điều này không bao giờ cho thấy model xử lý lỗi như thế nào. Luôn bao gồm ít nhất một snippet sai rõ ràng trong bộ kiểm thử của bạn.

Tóm tắt

Bạn bây giờ đã có một mẫu làm việc để triển khai một tính năng AI: frontend mỏng, một tuyến Express, một module agent riêng biệt nắm sở hữu prompt và gọi API, và một bộ kiểm thử nhỏ bảo vệ khỏi sự quay lại lỗi. Sử dụng lại bố cục này cho các chức năng tóm tắt, phân loại, trợ lý trò chuyện, hoặc bất kỳ công cụ dựa trên AI nào khác bạn thêm vào một ứng dụng web.

Luyện tập sau buổi học

Bài kiểm tra cuối bài

Ôn lại kiến thức, thử sức và nhận góp ý cho bài làm.

0/1
Đã trả lời · 0/1