Khả năng sửa file là thứ khiến coding agent hữu ích. Nhưng ghi đè cả file dễ làm mất code. Bài này ta xây bộ tool file an toàn: read_file, list_dir, write_file, và quan trọng nhất — edit_file kiểu thay thế chuỗi chính xác.
Vì sao không nên chỉ dùng write_file
Nếu tool duy nhất để sửa là write_file (ghi đè toàn bộ), LLM phải in lại cả file mỗi lần sửa một dòng. Hệ quả: tốn token, dễ cắt xén nội dung ngoài ý muốn, và với file lớn thì LLM hay "quên" phần cuối. Giải pháp là edit theo mảnh.
Bước 1: Tool edit_file dạng find/replace
def edit_file(path, old_string, new_string):
text = open(path, encoding="utf-8").read()
count = text.count(old_string)
if count == 0:
return "ERROR: không tìm thấy old_string. Hãy read_file lại."
if count > 1:
return f"ERROR: old_string xuất hiện {count} lần, không duy nhất. Thêm ngữ cảnh."
open(path, "w", encoding="utf-8").write(
text.replace(old_string, new_string))
return "OK: đã thay thế 1 vị trí."
Ba quy tắc vàng của edit an toàn:
- Không tìm thấy → báo lỗi, buộc LLM đọc lại file (tránh sửa mù).
- Trùng nhiều → từ chối, buộc LLM cung cấp ngữ cảnh dài hơn để định vị duy nhất.
- Duy nhất → thay và xác nhận.
Bước 2: write_file cho file mới
def write_file(path, content):
import os
os.makedirs(os.path.dirname(path) or ".", exist_ok=True)
open(path, "w", encoding="utf-8").write(content)
return f"OK: đã ghi {len(content)} ký tự vào {path}."
Dùng write_file để tạo mới; dùng edit_file để sửa file có sẵn. Mô tả tool nên nói rõ sự phân công này để LLM chọn đúng.
Bước 3: list_dir để agent tự định hướng
def list_dir(path="."):
import os
return "\n".join(sorted(os.listdir(path)))
Agent thường bắt đầu bằng list_dir để hiểu cấu trúc dự án trước khi đọc file cụ thể — giống lập trình viên mở cây thư mục.
Ví dụ: đổi tên biến trong 1 hàm
- LLM
read_file("utils.py")→ thấydef calc(x): return x*taxrate. - LLM
edit_file("utils.py", old="return xtaxrate", new="return x TAX_RATE"). - Tool báo OK (chuỗi duy nhất) → LLM chạy test xác nhận.
xtaxrate xuất hiện ở 2 hàm, tool báo "trùng 2 lần" và LLM sẽ thêm ngữ cảnh: old="def calc(x): return xtaxrate" để định vị đúng.Khung tư duy: Read-before-Edit
Luật bất di bất dịch: agent phải read_file trước khi edit_file cùng một file trong lượt đó. Vì old_string phải khớp chính xác nội dung hiện tại. Nhiều framework còn chặn cứng: từ chối edit nếu file chưa được đọc trong phiên.
Checklist tool file
- [ ]
edit_filetừ chối khi old_string trùng nhiều hoặc không thấy. - [ ] Thông báo lỗi hướng dẫn LLM cách sửa ("read lại", "thêm ngữ cảnh").
- [ ]
write_filechỉ dùng tạo mới; edit dùng sửa file cũ. - [ ]
read_filetrả kèm số dòng khi cần định vị. - [ ] Có giới hạn kích thước đọc để không nhồi file khổng lồ vào context.
Sai lầm thường gặp
- Chỉ có write_file. Agent ghi đè và vô tình xóa phần code không liên quan.
- Cho phép edit khi old_string trùng nhiều.
replacesẽ đổi tất cả vị trí — gây sửa nhầm hàng loạt. - Không buộc read trước edit. LLM sửa dựa trên trí nhớ sai, old_string không khớp, mất thời gian thử lại.
- Thông báo lỗi cụt lủn ("failed"). LLM không biết vì sao và cách khắc phục; hãy nói rõ nguyên nhân.
- Đọc file nhị phân/khổng lồ làm tràn context window và tốn token vô ích.