Coding assistant là gì?

1 — Nền tảngCơ bản25 phút

Hỏi 10 developer dùng AI coding tool: "Khi bạn ra lệnh 'đọc file X', ai thực sự đọc file đó?"

Bạn sẽ học được
  • Mô tả quy trình 3 bước mà một coding assistant thực hiện khi nhận task
  • Giải thích vì sao language model một mình không đọc được file hay chạy được command
  • Mô tả cơ chế tool use — cách LM "gọi" action ra thế giới thực
  • So sánh khả năng tool use của Claude với các model khác, và hiểu vì sao điều đó quan trọng
  • Dự đoán khi nào Claude Code "bí" và cần bạn can thiệp

Coding assistant hoạt động thế nào?

Một coding assistant nhận task — ví dụ "sửa bug dựa trên error message này" — và làm ba việc, giống hệt cách một developer người làm:

1. Gather context — Thu thập ngữ cảnh

Error message nói gì? File nào bị ảnh hưởng? Dependencies nào liên quan? Bug này mới xuất hiện hay có từ lâu?

Developer người sẽ: mở log, grep codebase, đọc git blame. Coding assistant làm chính xác những thao tác đó — không phải bằng "trí nhớ" mà bằng cách đọc file thật.

2. Formulate a plan — Lập kế hoạch

"Thay đổi function A, sau đó cập nhật caller ở B, C. Chạy test để verify."

Bước này là text pure — LM rất mạnh ở đây. Không cần tool, chỉ cần suy luận dựa trên context vừa gather.

3. Take action — Thực hiện

Update file, chạy command, chạy test. Nếu test fail → quay lại bước 1 với context mới (error mới). Vòng lặp cho đến khi done.

Key insight: Bước 1 và bước 3 đều yêu cầu tương tác với thế giới bên ngoài — đọc file, chạy command, fetch docs. LM tự thân không làm được điều đó.

┌──────────────────────────────────────────────────────────┐
│                                                          │
│   ┌──────────────┐    ┌──────────────┐    ┌───────────┐ │
│   │  1. GATHER   │───▶│  2. PLAN     │───▶│ 3. ACT    │ │
│   │   CONTEXT    │    │              │    │           │ │
│   └──────────────┘    └──────────────┘    └───────────┘ │
│      ▲                                          │       │
│      │                                          │       │
│      └──────────── Loop nếu cần ─────────────────┘      │
│                                                          │
└──────────────────────────────────────────────────────────┘

Vấn đề: LM chỉ sinh text

Đây là chỗ gây confusion nhất. Hãy thẳng thắn:

Language model là hàm:

Hết. Không hơn.

Nếu bạn paste prompt "đọc file main.go" vào một LM raw (không có wrapper), nó sẽ:

Đó không phải đọc file. Đó là tưởng tượng về file. Kết quả sai toàn tập.

Thí nghiệm nhỏ

Mở claude.ai (web chat, không phải Claude Code) và hỏi:

  • Tạo ra một đoạn text trông như "nội dung file main.go" — dựa trên guess từ training data
  • Hoặc trả lời: "Tôi không có khả năng đọc file trực tiếp."
input:  text
output: text

Thí nghiệm nhỏ

Claude sẽ trả lời kiểu: "Tôi không thể truy cập file system của bạn." — đúng. Nó thừa nhận giới hạn.

Giờ hỏi tương tự trong Claude Code:

Đọc file ~/.bashrc của tôi và cho tôi biết có gì trong đó.

Vấn đề: LM chỉ sinh text (tiếp)

Claude Code sẽ thực sự đọc được file. Tại sao cùng model, kết quả khác?

Câu trả lời: tool use.

Đọc file ~/.bashrc của tôi và cho tôi biết có gì trong đó.

Tool use — Mắt, tai, tay cho LM

Cơ chế tool use thông minh ở chỗ: bạn không thực sự cho LM khả năng đọc file. Bạn dạy nó yêu cầu ai đó khác đọc file hộ mình.

Luồng hoạt động chi tiết

Khi bạn gửi prompt tới Claude Code, trước khi prompt đó tới LM, Claude Code tự động thêm instruction vào:

LM đọc system prompt, hiểu: "À, nếu muốn đọc file, tôi cần trả về format đặc biệt."

5 bước của một tool use loop

Nhìn từ bạn: Claude "đọc file". Thực tế: LM sinh text đặc biệt → Claude Code đọc file thay → gửi nội dung lại cho LM → LM tóm tắt.

Đây là lý do tại sao:

So sánh với developer người

Nếu bạn thay "LM" bằng "Tony, senior engineer qua điện thoại" sẽ dễ hình dung:

Tony = LM. Bạn (+ terminal) = Claude Code. Format "<tool_use>" = cách Tony nói "đánh cat file giúp tôi".

Khác biệt: Tony có thể xử lý dăm file trong cuộc gọi 30 phút. LM có thể xử lý trăm file trong vài chục giây. Bản chất flow giống hệt.

  • Khi internet chậm, Claude Code vẫn "đọc file" nhanh (vì LM chỉ generate text, file system là local)
  • Khi API Anthropic lỗi, Claude Code dừng hoàn toàn (vì vòng lặp yêu cầu LM generate text)
  • Token cost tăng nhanh khi Claude "đọc nhiều file" (mỗi file content đều phải gửi lại cho LM)
┌────────────────────────────────────────────────────────────┐
│                                                            │
│  1. BẠN:    "Đọc file main.go, có gì trong đó?"            │
│              │                                             │
│              ▼                                             │
│  2. CLAUDE CODE: Gắn tool definitions vào prompt           │
│              │                                             │
│              ▼                                             │
│  3. LM:     Sinh text:                                     │
│              <tool_use>                                    │
│                <name>ReadFile</name>                       │
│                <args>{"path": "main.go"}</args>            │
│              </tool_use>                                   │
│              │                                             │
│              ▼                                             │
│  4. CLAUDE CODE: THẤY text đó, parse ra, THỰC THI          │
│              fs.readFile("main.go") → "package main..."    │
│              Gửi kết quả vào lượt tiếp theo của LM         │
│              │                                             │
│              ▼                                             │
│  5. LM:     Đọc kết quả, sinh final answer:               │
│              "File main.go chứa package main và hàm..."    │
│                                                            │
└────────────────────────────────────────────────────────────┘

Tool use challenge — Không phải LM nào cũng giỏi

Đây là chỗ tạo ra khác biệt lớn giữa các coding assistant.

Các cách LM có thể "dở" về tool use

Tại sao Claude (Opus, Sonnet, Haiku) mạnh ở tool use?

Model Claude được train đặc biệt cho tool use — không phải chỉ "may ra biết dùng tool" mà là kỹ năng cốt lõi. Cụ thể:

  • Đoán tool name sai — trả về <read_file> khi tool được định nghĩa là <ReadFile>
  • Không parse argument đúng — gửi {"file_path": "x"} khi schema yêu cầu {"path": "x"}
  • Không biết khi nào cần dùng tool — hallucinate file content thay vì gọi ReadFile
  • Gọi tool lặp lại vô tận — stuck trong loop đọc cùng file 10 lần
  • Không biết combine tool — không nghĩ ra rằng phải Grep trước khi Read để tìm file cần đọc
Năng lựcÝ nghĩa cho bạn
Hiểu tool description chính xácClaude dùng đúng tool ngay lần đầu, không mất request debug
Combine nhiều tool thông minhGrep → Read → Edit → Bash(test) trong một flow mượt
Dùng tool chưa từng thấyBạn thêm MCP server mới, Claude adapt ngay không cần fine-tune
Biết khi nào dừng loopKhông bị stuck ở "read file mãi", biết khi đủ context để action

Lợi ích của tool use mạnh đối với Claude Code

1. Giải quyết task khó hơn

Claude có thể ghép nhiều tool để giải task phức tạp — và vẫn dùng được tool nó chưa từng thấy (khi bạn thêm MCP server mới).

Ví dụ: bạn thêm MCP server Linear (quản lý ticket). Claude chưa từng train trên Linear MCP specifically. Nhưng vì tool use là kỹ năng chung, Claude đọc description Linear tool → hiểu → dùng luôn ở request tiếp theo. Không cần retrain.

2. Platform có thể mở rộng

Mỗi team dùng tool khác nhau: Jira hay Linear, Slack hay Teams, AWS hay GCP. Tool use mạnh nghĩa là Claude Code adapt theo workflow bạn, không bắt bạn adapt theo nó.

3. Bảo mật tốt hơn

Hậu quả thú vị: vì Claude tương tác với codebase thay vì indexing toàn bộ và gửi lên server, nó không cần gửi toàn bộ code của bạn ra ngoài.

So sánh với cách tiếp cận cũ:

Với enterprise có requirement "code không được leave our infrastructure", Claude Code + Anthropic trên AWS Bedrock/GCP Vertex là setup khả thi — không thể với tool indexing-based.

┌───────────────────────────────────────────────┐
│  CÁCH CŨ (indexing-based):                    │
│  1. Tool index toàn bộ code → embeddings      │
│  2. Push embeddings lên server                │
│  3. Khi query, search semantic + send file    │
│                                               │
│  → Code bạn có trên server bên thứ 3          │
│  → Vấn đề với enterprise/gov/finance          │
└───────────────────────────────────────────────┘

┌───────────────────────────────────────────────┐
│  CÁCH CLAUDE CODE (agentic search):           │
│  1. Không indexing                            │
│  2. LM gọi `Grep` khi cần tìm pattern         │
│  3. LM gọi `Read` file cụ thể khi cần nội dung│
│                                               │
│  → Chỉ file thực sự cần được send lên API     │
│  → Compliance-friendly                        │
└───────────────────────────────────────────────┘

Ví dụ thực chiến: Chứng kiến tool use loop

Tình huống

Bạn có codebase Next.js. Muốn Claude thêm field phoneNumber vào form signup, validation đúng, test pass.

Bước 1: Bạn gõ

Bước 2: Claude gather context (tool use — Grep)

Thêm field phoneNumber (optional) vào signup form. Validation: nếu 
có, phải là format E.164. Thêm test cho cả trường hợp có và không.

Bước 2: Claude gather context (tool use — Grep)

Trả về: src/app/signup/page.tsx, src/lib/auth.ts, src/app/signup/page.test.tsx

Bước 3: Claude đọc các file (tool use — Read)

[Tool call] Grep
  pattern: "signup"
  glob: "**/*.{ts,tsx}"

Bước 3: Claude đọc các file (tool use — Read)

Claude thấy form dùng React Hook Form + Zod validator.

Bước 4: Claude lập kế hoạch (text only, không tool)

[Tool call] Read
  file_path: "src/app/signup/page.tsx"

Bước 4: Claude lập kế hoạch (text only, không tool)

Bước 5: Claude thực thi (tool use — Edit + Bash)

Kế hoạch:
1. Update Zod schema trong lib/validators/signup.ts: thêm phoneNumber 
   optional, regex E.164
2. Update form UI trong page.tsx: thêm <input> phoneNumber
3. Update test: 2 case mới (có/không phoneNumber), verify E.164 validation

Bước 5: Claude thực thi (tool use — Edit + Bash)

Test fail! Vì regex E.164 ở schema sai.

Bước 6: Claude loop back (context mới = error)

[Tool call] Edit lib/validators/signup.ts
[Tool call] Edit app/signup/page.tsx
[Tool call] Edit app/signup/page.test.tsx
[Tool call] Bash "npm run test signup"

Bước 6: Claude loop back (context mới = error)

Claude gather context mới → đọc lại schema → fix regex → chạy lại test → pass.

Kết quả

Developer thấy: "Claude đã làm xong." → review diff, approve. Thực tế behind the scenes: ~15 tool call trong 45 giây.

Thời gian bạn tốn: ~3 phút (gõ prompt + review). Thời gian nếu làm tay: ~30 phút (tìm file, hiểu validator, code, chạy test, debug regex).

Test error: "Phone +1234 should be valid E.164 but got invalid"

Case studies: tool use power theo ngành

💼 Developer Productivity — Team frontend

Trước: "Mỗi lần có design mới trên Figma, dev phải crop screenshot, đọc spec, tự code component. Tốn 2 giờ/component."

Với tool use (Claude Code + MCP Playwright + Figma):

🏭 Platform Engineering — Database migration

Trước: "Migrate 40 stored procedure từ MSSQL sang PostgreSQL. Mỗi proc phải đọc, dịch syntax, test. 3 tuần full-time."

Với tool use:

🔍 Code Archaeology — Onboard codebase 1M dòng

Trước: "Engineer mới mất 3-4 tuần chỉ để hiểu đủ làm task đầu tiên."

Với tool use:

🛡️ Security Review — Audit dependency

Trước: "Quarterly security audit 80 dependency — đọc changelog, check CVE, verify usage trong code. 1 tuần."

Với tool use:

  • Claude đọc Figma frame qua MCP
  • Tự generate React component
  • Claude dùng Playwright MCP mở browser, so với Figma, tự adjust
  • Kết quả: 2 giờ → 25 phút/component, accuracy design 90%+ ngay lần đầu
  • Claude đọc procedure MSSQL (Read)
  • Hiểu logic, rewrite PostgreSQL (Edit)
  • Tạo test case (Write)
  • Chạy migration test (Bash)
  • Loop fix nếu fail
  • Kết quả: 3 tuần → 4 ngày, coverage test 100%
  • Claude dùng Grep + Read để trace feature
  • Claude đọc git log, git blame
  • Claude sinh architecture diagram ASCII + report
  • Engineer mới có overview trong 2-3 ngày thay vì tuần
  • Kết quả: thời gian onboard giảm 70%
  • Claude fetch changelog (web fetch tool)
  • Cross-ref với CVE database
  • Grep tìm usage trong codebase
  • Generate risk report với ưu tiên
  • Kết quả: 1 tuần → 1 ngày review + 0.5 ngày human verify

Anti-patterns khi tin vào tool use

❌ Giả sử Claude "biết" những gì không cung cấp

Biểu hiện: "Thêm vào flow mới giống flow cũ" mà không chỉ flow cũ ở đâu.

Tại sao sai: Claude có thể grep tìm, nhưng cũng có thể đoán sai "flow cũ" là flow nào nếu codebase có nhiều flow tương tự.

Cách đúng: @src/flows/checkout-v2.ts cụ thể. Cho Claude điểm bắt đầu.

❌ Confused khi Claude "lơ" tool có sẵn

Biểu hiện: bạn cài MCP Linear, Claude vẫn hỏi thủ công.

Tại sao: Có thể Claude chưa biết tool mới thêm (cần restart session), hoặc matcher permission chặn.

Cách đúng: Chạy /mcp để verify server đang active. Verify settings.json allow list.

❌ Không biết tool nào có sẵn

Biểu hiện: "Sao Claude không mở browser cho tôi?" — chưa cài MCP Playwright.

Cách đúng: Hỏi Claude: "List all tools you have access to in this session." Claude sẽ liệt kê.

❌ Dùng chat web (claude.ai) cho task cần tool file system

Biểu hiện: dán code vào chat claude.ai, hỏi, confused tại sao không edit file.

Cách đúng: Chat web KHÔNG có tool use file system. Dùng Claude Code CLI hoặc IDE integration cho task cần touch file.

Mẹo nâng cao

Mẹo 1: Hỏi Claude list tool khi nghi ngờ

Claude sẽ list. Nếu thiếu tool mong đợi → kiểm tra config MCP.

Mẹo 2: Verify tool call bằng cách quan sát

Claude Code hiện tool call real-time. Nếu task yêu cầu edit file mà không thấy [Edit] xuất hiện → Claude không edit thật, đang giả vờ. Dừng ngay.

Mẹo 3: Khi debug, xem transcript

Claude Code log mọi tool call vào transcript. Bạn có thể truy ra: tool nào gọi, argument là gì, output là gì. Dùng để debug khi Claude đi sai hướng.

Show me all tools you can use right now, including MCP tools.

Áp dụng ngay

Bài tập 1: Quan sát tool use loop (10 phút)

Bước 1: Cài Claude Code (nếu chưa) — hướng dẫn ở Bài 4.4.

Bước 2: Mở terminal trong một project TS/JS có sẵn. Chạy claude.

Bước 3: Gõ prompt test:

Bước 4: Quan sát tool call hiện ra. Ghi lại:

Bước 5: Giờ cùng task đó, hỏi Claude Code không dùng tool:

  • Tool nào được gọi (Glob/Grep/Bash/Read...)? ________
  • Thứ tự gọi: ________
  • Có tool nào bị gọi 2 lần không? ________
  • Thời gian total: _____ giây
Đếm số file TypeScript trong project này, chia theo thư mục con.

Bài tập 1: Quan sát tool use loop (10 phút)

So sánh kết quả. Sự khác biệt chính là minh chứng tool use cần thiết thế nào.

Bài tập 2 (optional, 15 phút): Phân biệt chat vs Claude Code

Bước 1: Cùng một câu hỏi — thử trên cả hai:

Câu hỏi: "Xem file package.json trong project của tôi và cho tôi biết tôi dùng framework gì."

Bước 2: Hỏi trên claude.ai (chat web):

Bước 3: Hỏi trên Claude Code CLI (trong thư mục project):

Bước 4: Viết 2 câu giải thích tại sao kết quả khác:

  • Kết quả: ________
  • Claude có hỏi thêm gì không?
  • Kết quả: ________
  • Tool nào được dùng?
Đếm số file TypeScript mà KHÔNG dùng bất kỳ tool nào. Chỉ đoán 
dựa trên kinh nghiệm.

Bài tập 2 (optional, 15 phút): Phân biệt chat vs Claude Code

________________________________________________
________________________________________________

Tóm tắt bài học

🎯 Coding assistant = Gather context → Plan → Act (vòng lặp) — 80% thời gian nó ở bước 1 và 3, chỉ dùng LM pure ở bước 2.

🎯 LM không đọc file, không chạy command — nó sinh text có format đặc biệt yêu cầu tool host thực hiện.

🎯 Tool use là skill riêng biệt — không phải mọi LM giỏi chat đều giỏi tool use.

🎯 Claude được train chuyên cho tool use — đó là lý do Claude Code đáng tin cho task có nhiều bước edit/read/bash.

🎯 Kiến trúc agentic search > indexing — không cần upload toàn codebase, compliance-friendly cho enterprise.

Tài liệu tham khảo
  • Building effective agents — Anthropic blog
  • Designing Claude Code — talk by Boris Cherny
  • MCP specification — modelcontextprotocol.io
  • Bài 4.10 — MCP servers (sẽ đi sâu mechanism thêm tool mới)
  • Bài 4.12 — Giới thiệu hooks (chen vào tool use loop như thế nào)
Nội dung này có hữu ích không?