Gần đây mình bắt đầu dành thời gian để học thêm nhiều thứ và LLM Application Engineer là một trong những công việc mình thấy khá xịn xò mà bản thân mình đang hướng tới và những kiến thức xoay quanh nó thì rất là nhiều. Mình muốn nâng cấp bản thân hơn, muốn học nhiều hơn. Và mình thấy cách học tốt nhất là viết lại những gì đã học và chia sẻ cho mọi người. Đặc biệt là những người mới học để mong muốn trở thành LLM Application Engineer như mình.
Khi chúng ta làm việc ở Frontend, việc dùng fetch là rất thường xuyên, các bạn đã quá thành thạo với việc này. Với một LLM Application Engineer thì công việc cũng rất là đơn giản, chỉ cần gọi API tới Claude hay OpenAI với HTTP POST, gửi JSON đi và nhận JSON về. Không có train model, không có đụng GPU gì cả.
Ví dụ request đơn giản
Với API web chúng ta sẽ hay làm thế này:
POST /api/orders
Body: { items, address }
→ trả về { orderId, total }còn với API LLM(ví dụ Claude) thì sẽ thế này
POST /v1/messages
Body: { model, max_tokens, messages }
→ trả về { content, usage, stop_reason }Các bạn sẽ thấy là cùng một cách gọi mà thôi nhưng khác ở chỗ đó chính là nội dung của body, không phải cơ chế gì cả. Có 3 fields quan trọng nhất là:
// Body bạn gửi đi — chỉ là JSON
{
model: "claude-opus-4-8", // model nào trả lời
max_tokens: 1024, // giới hạn độ dài output (đơn vị: token)
messages: [ // cuộc hội thoại
{ role: "user", content: "Giải thích RAG trong 1 câu." }
]
}Và JSON trả về, tùy vào API LLM, trong ví dụ mình cho các bạn xem là của Claude thì cấu trúc của nó sẽ có content là một mảng các block, không phải một chuỗi string. Muốn lấy kết quả thì chúng ta sẽ duyệt qua mảng block và tìm block có type === "text"
// Response trả về
{
content: [ { type: "text", text: "RAG tìm tài liệu liên quan rồi..." } ],
stop_reason: "end_turn", // vì sao model dừng
usage: { input_tokens: 14, output_tokens: 22 } // để tính tiền
}Nếu dùng thư viện như @anthropic-ai/sdk thì sẽ trông như thế này
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic(); // đọc ANTHROPIC_API_KEY từ env
const response = await client.messages.create({
model: "claude-opus-4-8",
max_tokens: 1024,
messages: [{ role: "user", content: "Giải thích RAG trong 1 câu." }],
});
// content là mảng block — lọc text ra
for (const block of response.content) {
if (block.type === "text") console.log(block.text);
}API không có trí nhớ
Các bạn nên nắm rằng là LLM API là stateless. Server không nhớ gì giữa 2 request. Nếu các bạn hỏi “Tên tôi là A”, rồi request tiếp theo các bạn hỏi tiếp “Tên tôi là gì?” thì model sẽ không biết, trừ khi các bạn gửi lại toàn bộ lịch sử hội thoại trong field messages mỗi lần.
“Trí nhớ” của chatbot không nằm ở model, nó nằm ở code của chúng ta, chúng ta có thể lưu mảng messages và dùng nó vào mỗi lần gọi như này.
messages: [
{ role: "user", content: "Tên tôi là Tuấn." },
{ role: "assistant", content: "Chào Tuấn!" }, // câu trả lời lần trước
{ role: "user", content: "Tên tôi là gì?" } // giờ model mới biết
]Thực hành nho nhỏ
Đầu tiên các bạn vào console.anthropic.com đăng ký một cái tài khoản sau đó vào mục API Keys và tạo mới một cái(thích đặt tên gì cũng được). Nhớ là copy cái chuỗi bắt đầu bằng sk-ant-... và lưu tạm chỗ an toàn (nó chỉ hiện 1 lần thôi nếu các bạn không copy và lưu thì phải tạo mới)
Sau đó các bạn tạo 1 thư mục là claude-first-call(hoặc gì tùy các bạn) và đưa vào VSCode hoặc Editor nào các bạn thích. Sau đó chạy các lệnh sau giúp mình:
npm init -y
npm install @anthropic-ai/sdk
npm install -D tsx Sau đó mở file package.json lên tìm dòng type và thay bằng “type": "module" . Trong cùng terminal đang mở ở thư mục claude-first-call các bạn dán dòng này vào. Tạm thời chưa dùng biến .env nên terminal các bạn đừng có tắt hay đóng lại nhé.
export ANTHROPIC_API_KEY="sk-ant-...key-của-bạn..."Sau đó các bạn tạo 1 file là index.ts và dán nội dung sau vào:
import Anthropic from "@anthropic-ai/sdk";
// new Anthropic() tự đọc ANTHROPIC_API_KEY từ env — không hardcode key!
const client = new Anthropic();
const response = await client.messages.create({
model: "claude-haiku-4-5", // model rẻ để luyện tập
max_tokens: 1024,
messages: [
{ role: "user", content: "Chào! Giải thích RAG cho mình trong đúng 2 câu." },
],
});
// content là MẢNG block — lọc ra block text rồi in
for (const block of response.content) {
if (block.type === "text") console.log(block.text);
}
// in thêm metadata để thấy "đằng sau hậu trường"
console.log("\n---");
console.log("stop_reason:", response.stop_reason);
console.log("tokens:", response.usage);Sau đó mở terminal và chạy lệnh
npx tsx index.tsSau 1–2 giây, các bạn sẽ thấy Claude trả lời trong terminal, kèm stop_reason: end_turn và số token đã dùng. Chúc mừng các bạn đã gọi một LLM từ code của chính các bạn. 🎉
Đọc kết quả chúng ta sẽ thấy 3 phần quan trọng
- Đoạn text Claude trả lời: Lấy từ
block.textnhư mình đã đề cập ở trên stop_reason: "end_turn". Model tự kết thúc bình thường. Nếu thấy"max_tokens"nghĩa là output bị cắt và chúng ta sẽ phải tăng giá trị củamax_tokenslên cao hơnusage: { input_tokens, output_tokens }: Số token mà các bạn vừa trả tiền. Dựa vào những thông số này để tối ưu chi phí đấy nhé
Bài này dừng ở đây. Hẹn gặp lại các bạn ở những bài viết tiếp theo nhé.


Hay quá anh, mong a ra thêm nhiều blog nữa nhé ạ
a cám ơn em nhiều nhé