Skip to content

Instantly share code, notes, and snippets.

@nghyane
Created February 21, 2026 07:50
Show Gist options
  • Select an option

  • Save nghyane/e3a5d2db84e8c3608f0d06ffe38b3db2 to your computer and use it in GitHub Desktop.

Select an option

Save nghyane/e3a5d2db84e8c3608f0d06ffe38b3db2 to your computer and use it in GitHub Desktop.
Code Mode: Khi LLM viết code để điều khiển tools

Code Mode: Khi LLM viết code để điều khiển tools

Vấn đề

AI coding agent hoạt động bằng cách gọi tools — đọc file, chạy lệnh, tìm kiếm. Mỗi lần gọi là một round-trip tới LLM, và mỗi round-trip gửi lại toàn bộ context: system prompt, lịch sử hội thoại, định nghĩa tools.

Một task đơn giản — đọc 3 file rồi grep — tốn 4 round-trips. Context phình ra theo từng lượt:

LLM → read(file1)    → 50k tokens
LLM → read(file2)    → 55k tokens
LLM → read(file3)    → 60k tokens
LLM → grep(pattern)  → 65k tokens
                        ─────────
                        ~230k tokens

4 lần gọi, mỗi lần kéo theo cả đống context cũ. Đây là bottleneck lớn nhất về tốc độ lẫn chi phí.

Code Mode

Ý tưởng đơn giản: thay vì LLM gọi từng tool, LLM viết một đoạn JavaScript gọi tất cả cùng lúc. Engine chạy đoạn code đó locally rồi trả kết quả về trong một lượt duy nhất.

async () => {
  const [a, b, c, d] = await Promise.all([
    codemode.read({ path: "file1" }),
    codemode.read({ path: "file2" }),
    codemode.read({ path: "file3" }),
    codemode.grep({ pattern: "TODO", path: "src/" }),
  ]);
  return { a, b, c, d };
}

4 round-trips thành 1. ~230k tokens thành ~50k. Các tool calls còn chạy song song qua Promise.all().

Cách hoạt động

Luồng xử lý gồm 4 bước:

LLM viết code
  ↓  normalize — chuẩn hóa thành async arrow function
  ↓  execute   — chạy trong sandbox, dispatch tool calls
  ↓  bridge    — emit events để TUI render từng sub-tool
  ↓
Kết quả trả về LLM

Typed API cho LLM

LLM không viết code mù. Engine đọc JSON Schema của từng tool, convert sang TypeScript declarations, rồi nhúng vào tool description:

interface ReadInput {
  /** File path to read */
  path: string;
  /** Line range [start, end] */
  range?: number[];
}

declare const codemode: {
  /** Read file contents */
  read: (input: ReadInput) => Promise<unknown>;
  /** Execute shell command */
  bash: (input: BashInput) => Promise<unknown>;
};

LLM nhìn thấy typed API này nên viết code đúng interface ngay từ đầu — không cần đoán tên hàm hay format tham số.

Proxy dispatch

Bên trong sandbox, codemode là một Proxy object. Bất kỳ method call nào cũng được dispatch tới tool tương ứng:

const codemode = new Proxy({}, {
  get: (_target, prop: string) => {
    const fn = fns[prop];
    if (!fn) return async () => { throw new Error(`Tool "${prop}" not found`) };
    return async (args = {}) => fn(args);
  },
});

codemode.bash(...) → bash tool. codemode.read(...) → read tool. Không cần hardcode danh sách — thêm tool mới tự động có trong API.

Normalizer

LLM không phải lúc nào cũng viết code hoàn chỉnh. Normalizer xử lý mọi trường hợp:

  • Đã là async () => { ... } → giữ nguyên
  • Code rời rạc → wrap vào async function, tự thêm return cho expression cuối
  • Một dòng đơn → wrap với auto-return

Sandbox

Code chạy qua new AsyncFunction() với các globals nguy hiểm (process, require, Bun, globalThis) bị shadow thành undefined. console.log redirect vào logs riêng. Timeout 5 phút, hỗ trợ abort signal.

Đây là soft sandbox — mục đích hướng LLM viết code đúng API, không phải chống mã độc.

TUI trong suốt

Mỗi codemode.* call emit event tool_start / tool_done / tool_error. TUI nhận events và render từng sub-tool giống hệt tool call bình thường — bash hiện bash box, read hiện file preview, grep hiện kết quả tìm kiếm. Người dùng không thấy khác biệt gì.

Tích hợp

Code Mode là một package độc lập (packages/codemode/), tích hợp vào coding-agent qua 3 điểm:

  • Setting codemode.enabled — bật/tắt trong Settings, mặc định bật
  • Tool registry — khi bật, wrap tất cả tools thành một tool code duy nhất. Các tool cần tương tác người dùng (ask, report_finding, ...) được giữ nguyên
  • TUI renderer — render sub-tools bên trong code block y hệt tool calls thường

Tóm lại

Code Mode không thêm khả năng mới — agent vẫn dùng cùng bộ tools. Nó thay đổi cách gọi: từ gọi lần lượt sang viết code điều phối. Ít round-trips, ít tokens, chạy song song, nhanh hơn.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment