Dùng Codex làm provider cho Microsoft Agent Framework

Dùng Codex CLI làm provider cho Microsoft Agent Framework trong C# qua package AgentFrameworkToolkit.Codex: agent, session, approval, tool C#.

Đã duyệt độc lập · cập nhật 26/10/2026 · 26 min

1. Hai chủ đề yêu thích: Microsoft Agent Framework và Codex

Rasmus Wulff Jensen mở đầu video trên kênh AI in C# bằng hai trong số những chủ đề anh yêu thích: một là Microsoft Agent Framework, hai là Codex, coding agent của OpenAI. Trong video đăng ngày 23/10/2026, anh cho xem một NuGet package do chính anh làm, để kết hợp hai thứ đó lại: dùng Microsoft Agent Framework nhưng phía sau là Codex.

Điểm anh nhấn mạnh ngay từ đầu: theo video đăng ngày 23/10/2026, cách này không cần API key hay mua token riêng. Bạn dùng gói subscription OpenAI đang có. Ảnh mở đầu video cũng ghi đúng ý đó: "No API Key or Tokens, Use your OpenAI Subscription".

Ảnh tiêu đề: Codex in Microsoft Agent Framework, No API Key or Tokens, Use your OpenAI Subscription
Ảnh tiêu đề của video (đăng ngày 23/10/2026): logo Codex chỉ sang logo Agent Framework, kèm dòng "No API Key or Tokens, Use your OpenAI Subscription".

Anh có sẵn một sample repo, link nằm trong phần mô tả video (xem mục nguồn bên dưới). Kế hoạch của anh gồm hai phần: trước hết làm lại từ đầu, không có dòng code nào sẵn, để thấy một agent đầu tiên chạy; sau đó cho xem toàn bộ những tính năng mà hệ thống này làm được, tính đến video đăng ngày 23/10/2026.

2. Điều kiện duy nhất: Codex CLI đã cài và đã đăng nhập

Trước khi làm gì, bạn phải chắc là máy đã cài Codex CLI. Rasmus nói rõ: không phải bạn cần dùng Codex CLI để làm việc, nó chỉ cần được cài trên máy. Nếu gõ codex mà nó khởi động lên, và đã đăng nhập, thì bạn sẵn sàng (theo video đăng ngày 23/10/2026).

Cửa sổ terminal chạy OpenAI Codex v0.163.0 với danh sách lệnh /init, /status, /permissions, /model, /review
Rasmus mở Codex CLI trong terminal để kiểm tra nó chạy được (video đăng ngày 23/10/2026): màn hình ghi OpenAI Codex v0.163.0, gợi ý các lệnh /init, /status, /permissions, /model, /review, và dòng trạng thái cho thấy model đang chọn cùng "Context 100% left".

Trong trường hợp của anh, anh đã đăng nhập bằng subscription OpenAI của mình. Nếu chưa cài, anh đọc lệnh cài qua npm như sau (README của repo Codex trên GitHub cũng ghi đúng dạng này, đọc ngày 26/10/2026):

npm install -g @openai/codex

Chạy Codex lần đầu, nó sẽ hướng dẫn bạn đăng nhập bằng tài khoản của mình. Theo Rasmus (video đăng ngày 23/10/2026), đó có thể là bất kỳ gói trả phí nào bạn đang có ở OpenAI. Xong bước này là bạn sẵn sàng.

Anh nhắc lại: thật ra mình không cần Codex cho việc gì khác ngoài chuyện nó có mặt trên máy, vì trong đó có một file thực thi (executable) mà package sẽ tận dụng (theo video đăng ngày 23/10/2026).

3. Cài package AgentFrameworkToolkit.Codex và tạo CodexAgentFactory

Bước tiếp theo là cài một NuGet package. Rasmus nói rõ đây không phải thứ do team Agent Framework làm ra, mà là thứ anh tự build. Anh có một bộ tên là Agent Framework Toolkit, có thể bạn đã nghe tới, và tính đến video đăng ngày 23/10/2026 có thêm một bản NuGet dành riêng cho Codex.

NuGet Package Manager trong Visual Studio hiển thị AgentFrameworkToolkit.Codex phiên bản 1.25.2 của Rasmus Wulff Jensen
Trong NuGet Package Manager của Visual Studio (video đăng ngày 23/10/2026), package AgentFrameworkToolkit.Codex bản 1.25.2 có mô tả "Codex app-server coding agents for Microsoft Agent Framework", tác giả Rasmus Wulff Jensen, license MIT, ngày đăng 21/10/2026.

Cài package này xong, đi xuống dưới trong file Program.cs, bạn có thể tạo một thứ gọi là CodexAgentFactory. Factory này nhận được connection và các thiết lập khác, nhưng theo Rasmus (video đăng ngày 23/10/2026), ngay khi mới cài bạn không cần làm gì hơn: chỉ cần có một factory là đủ.

4. Experimental, pragma và working directory

Rasmus cho thấy anh đánh dấu các API này là experimental, tính đến video đăng ngày 23/10/2026. Lý do anh nêu: đây là thứ hoàn toàn mới, và anh muốn được phép tạo breaking change nếu cần. Anh nói tới lúc đó anh chưa thấy điều gì buộc phải làm vậy, nhưng cũng giống Responses API của OpenAI đang ở dạng preview, package này cũng thế. Vì vậy bạn cần thêm một dòng #pragma warning disable để tắt cảnh báo đó; trên màn hình là:

#pragma warning disable AFT999

Có factory rồi thì chỉ việc gọi CreateAgent. Bạn có thể truyền vào một bộ options, hoặc chỉ cần truyền một working directory. Rasmus giải thích: bất cứ khi nào làm việc với Codex, bạn phải đưa cho nó một folder để nó làm việc trên đó. Ở CLI, đó là folder bạn đứng khi khởi động. Trong app Codex, đó là project bạn đã chọn. Đó là cách Codex làm việc theo lời anh trong video đăng ngày 23/10/2026. Ở đây anh chỉ dùng Environment.CurrentDirectory, tức làm việc ngay tại chỗ, nhưng có thể là bất kỳ folder nào.

Program.cs của ZeroToFirstAgent.Codex: tạo CodexAgentFactory, CreateAgent, gọi RunAsync, RunAsync<Movie> và RunStreamingAsync
Toàn bộ chương trình agent đầu tiên trong video đăng ngày 23/10/2026: tạo CodexAgentFactory, gọi CreateAgent(Environment.CurrentDirectory), rồi ba kiểu gọi quen thuộc của Agent Framework. Khung Output phía dưới cho thấy NuGet đã cài xong các package liên quan.

Kết quả là bạn có một agent, và theo Rasmus (video đăng ngày 23/10/2026) agent đó làm được đúng những gì một agent bình thường trong Agent Framework làm. Anh gõ await agent.RunAsync(...) với câu hỏi "What is the capital of France?". Anh chỉ ra rằng mọi thứ giống hệt hệ thống Agent Framework thường: kết quả trả về là AgentResponse, hàm là RunAsync. Biến kiểu CodexAgent ở đây cũng có thể khai báo đơn giản là AIAgent, nó vẫn hiểu. Sau đó chỉ cần Console.WriteLine để in ra.

Đoạn code agent đầu tiên trên màn hình (video đăng ngày 23/10/2026), rút gọn lại phần chính:

CodexAgentFactory agentFactory = new CodexAgentFactory();
CodexAgent agent = agentFactory.CreateAgent(Environment.CurrentDirectory);

AgentResponse response1 = await agent.RunAsync("What is the capital of France?");
Console.WriteLine(response1);

5. Response thường, structured output, streaming và lần chạy đầu tiên

Việc tiếp theo, tất nhiên, là structured output (code trong video đăng ngày 23/10/2026). Rasmus đã tạo sẵn một record Movie nhỏ ở cuối file, gồm Title và YearOfRelease. Anh gọi agent.RunAsync<Movie> để lấy về bộ phim đứng đầu theo IMDB, đặt tên đúng là response2, rồi in ra response2.Result.Title và response2.Result.YearOfRelease.

Cuối cùng là streaming (video đăng ngày 23/10/2026): agent.RunStreamingAsync với câu "How to make soup?". Anh lưu ý ở đây không phải await thường mà là await foreach: mỗi vòng nhận về một update, và anh gọi Console.Write(update).

AgentResponse<Movie> response2 = await agent.RunAsync<Movie>("Top movie according to IMDB");
Console.WriteLine(response2.Result.Title);
Console.WriteLine(response2.Result.YearOfRelease);

await foreach (AgentResponseUpdate update in agent.RunStreamingAsync("How to make soup?"))
{
    Console.Write(update);
}

record Movie(string Title, int YearOfRelease);

Theo Rasmus (video đăng ngày 23/10/2026), mọi thứ ở đây đều giống hệt cách làm thường ngày. Khác biệt duy nhất là cách tạo agent. Và agent đó không có credential, không có API key nào. Nó dùng hạn mức (limits) của gói OpenAI của bạn, tất nhiên, nhưng ngoài chuyện đó ra, anh nói nó không tốn thêm gì ngoài tiền subscription.

Anh đặt project này làm startup project rồi chạy thử. Câu đầu tiên hỏi thủ đô của Pháp, câu trả lời về là Paris. Câu thứ hai hỏi phim đứng đầu IMDB qua structured output, kết quả là The Shawshank Redemption, năm 1994. Rồi phần streaming chảy về đúng như streaming thường thấy (demo trong video đăng ngày 23/10/2026).

Cửa sổ console in ra: The capital of France is Paris. The Shawshank Redemption. 1994
Kết quả lần chạy đầu tiên (demo trong video đăng ngày 23/10/2026): câu trả lời thường "The capital of France is Paris.", rồi structured output in ra tên phim "The Shawshank Redemption" và năm 1994.

Kết luận của anh cho phần này: một khi đã cài và đăng nhập Codex CLI, dùng nó cực kỳ đơn giản (theo video đăng ngày 23/10/2026).

6. "Miễn phí" trong ngoặc kép, rồi sang demo đầy đủ với CodexConnection

Rasmus nói bạn có thể làm việc này "miễn phí", và anh tự đặt chữ "free" trong ngoặc kép: bạn đã có subscription, bạn không dùng hết hạn mức, nên về cơ bản là miễn phí. Còn nếu chạm giới hạn thì cũng đành vậy. Đó là nhận định của anh trong video đăng ngày 23/10/2026.

Đó là phần đơn giản. Giờ anh đi sâu hơn vào những gì package thật sự làm được. Anh có một sample khác ở phía trên, vì package này thuộc bộ NuGet của anh tên Agent Framework Toolkit, mà anh mô tả là một cách để dùng các provider khác, và dùng những provider quen thuộc theo cách dễ hơn. Anh đóng sample cũ, mở sample mới. Ở đây cũng y như trước: chỉ có package NuGet là đủ. Anh chạy nó (video đăng ngày 23/10/2026) và đi qua từng dòng một, có chỉnh lại khung code để người xem nhìn dễ hơn.

Đầu tiên, ngoài factory, anh đã nhắc là có thể tạo một CodexConnection. Phần này là tùy chọn: theo Rasmus (video đăng ngày 23/10/2026), 99% trường hợp bạn không cần làm gì đặc biệt ở đây. Nhưng nó có ích trong vài tình huống:

  • Bạn cài Codex theo kiểu đặc biệt hoặc nâng cao, nên cần chỉ ra file thực thi nằm ở đâu. Nếu không, nó tự tìm trong PATH (theo video đăng ngày 23/10/2026).
  • Bạn muốn để Codex home, nơi chứa credential và các cấu hình, ở một đường dẫn khác (theo video đăng ngày 23/10/2026).
  • Bạn muốn dùng endpoint và API key, để dùng Codex với một công cụ bên thứ ba, hoặc dùng token của OpenAI thay cho subscription (theo video đăng ngày 23/10/2026).
  • Thêm vài thứ nữa như biến môi trường và các thiết lập nâng cao khác mà anh nói 99% thời gian bạn có lẽ sẽ không bao giờ cần (video đăng ngày 23/10/2026).

Tóm lại, theo anh trong video đăng ngày 23/10/2026, phần lớn trường hợp bạn không cần đặt gì trong CodexConnection, nhưng có thể làm nếu muốn. Trong code của anh, khối này để trống, chỉ có dòng chú thích "Various Advanced options (if you installed Codex in a special way) or use tokens instead".

Code C# vớiAgent Framework CodexAgentFactory+ CodexConnection (tùy chọn) Codex CLI trên máy, đã đăng nhậpdùng subscription OpenAI (mặc định) Endpoint + API keytoken OpenAI hoặc công cụ bên thứ ba
Hình 6.1Hai đường Rasmus mô tả trong video đăng ngày 23/10/2026: mặc định package tìm Codex CLI trong PATH và dùng gói subscription đã đăng nhập; CodexConnection chỉ cần khi Codex được cài kiểu đặc biệt hoặc khi muốn dùng endpoint và API key.

7. Working directory, AGENTS.md và CodexAgentOptions

Như đã nói, mình cần ở trong một folder, tức một working directory. Lần này Rasmus tạo một working directory riêng, tên "My-Codex-Demo" trong thư mục tạm, và đặt vào đó một file AGENTS.md. Theo anh (video đăng ngày 23/10/2026), bất cứ khi nào bạn đặt agent vào một working directory như vậy, nó sẽ đọc AGENTS.md và các skill có trong đó.

File AGENTS.md của anh rất ngắn, anh chỉ bảo agent nói chuyện như cướp biển (dòng "Speak like a pirate", hiện ra lúc agent đọc file ở phần demo sau). Tất nhiên, theo anh (video đăng ngày 23/10/2026), ngoài đời bạn sẽ đặt đủ thứ vào AGENTS.md để agent bắt đầu làm theo. Trong code, anh chỉ tạo đường dẫn đó rồi tạo agent.

Lần đầu, anh chỉ truyền working directory. Nhưng muốn kiểm soát kỹ hơn những gì agent làm, anh dùng CodexAgentOptions, một bộ thiết lập khá nhiều thứ. Đầu tiên, tất nhiên, là WorkingDirectory, bắt buộc phải có. Sau đó là chọn model, giống như chọn trong Codex: theo Rasmus (video đăng ngày 23/10/2026), các model có trong Codex cũng dùng được ở đây, và bạn chỉnh được reasoning effort.

Anh nói thêm, bạn cũng đặt được service tier, nếu muốn chạy fast mode, hoặc nếu có gói subscription 500 đô và muốn chạy ultra fast (con số và tên gói theo lời anh trong video đăng ngày 23/10/2026). Bản thân anh thường chỉ chạy chế độ bình thường.

Code CodexAgentOptions với WorkingDirectory, Model, ReasoningEffort, ServiceTier, Permissions, ApprovalPolicy, Instructions, Tools, OnUserInputRequested, OnRunEvent
Khối CodexAgentOptions trong sample đầy đủ (video đăng ngày 23/10/2026), mỗi dòng có chú thích của Rasmus: working directory "sẽ đọc Agents.md và Skills trong folder đó", permissions là "Codex có quyền truy cập kiểu gì", approval "đặt Never nếu không bao giờ muốn yêu cầu duyệt", tools là "tool C# của bạn đưa cho Codex".

Đoạn khởi tạo trên màn hình (video đăng ngày 23/10/2026):

CodexAgentFactory factory = new CodexAgentFactory(new CodexConnection
{
    //Various Advanced options (if you installed Codex in a special way) or use tokens instead
});

string workPath = Path.Combine(Path.GetTempPath(), "My-Codex-Demo");
Directory.CreateDirectory(workPath);

CodexAgent agent = factory.CreateAgent(new CodexAgentOptions
{
    WorkingDirectory = workPath, //Choose any local folder... Will pick up Agents.md and Skills in that folder
    Model = "gpt-6.1-sol",
    ReasoningEffort = CodexReasoningEffort.Low,
    ServiceTier = CodexServiceTier.Normal,
    Permissions = CodexPermissions.WorkspaceWrite, //What type of access should Codex Have
    ApprovalPolicy = CodexApprovalPolicy.OnRequest, //Set to Never if you never want approval requests
    Instructions = "You are a nice AI", //Additional instructions beyond Agents.md file
    Tools = [AIFunctionFactory.Create(GetWeather)], //Pass your own C# driven tools to Codex for extra features
    OnUserInputRequested = HandleUserInputRequestedAsync,//Let Codex as Questions to the user
    OnRunEvent = HandleRunEvent,
    //+ Various Advanced settings to control Codex further
});

8. Thread hiện trong app Codex, permissions và approval

Bạn đặt được permissions y như trong Codex. Để giải thích, Rasmus mở app Codex lên. Anh chỉ ra một điều: những câu anh vừa hỏi từ code thật ra đều nằm trong Codex. Các thread được ghi nhận và xuất hiện ở mục Recents, vì trong trường hợp của anh chúng không thuộc project nào (demo trong video đăng ngày 23/10/2026).

App Codex mở trên Visual Studio, mục Recents có các thread How to make soup?, Top movie according to IMDB, What is the capital of France?
App Codex trong video đăng ngày 23/10/2026: ở mục Recents có ngay "How to make soup?", "Top movie according to IMDB" và "What is the capital of France?", tức ba câu vừa chạy từ code C#; ô nhập phía dưới đang đặt "Full access".

Anh nói chuyện này có thể hơi phiền, nhưng tính đến video đăng ngày 23/10/2026 anh chưa tìm được cách ẩn chúng khỏi Codex, vì chính Codex chạy chúng, chính nó tạo thread. Anh đoán có thể sẽ build thêm phần xóa thread sau khi chạy xong. Còn hiện tại thì chúng cứ nằm ở đó, và bạn có thể tiếp tục các thread đó nếu muốn.

Thứ anh muốn chỉ là phần quyền: "Full access" và các thiết lập khác về việc agent được làm gì. Đó là những gì bạn đặt được trong code. Theo Rasmus (video đăng ngày 23/10/2026), permissions có ba mức:

  • Read-only: chỉ đọc (video đăng ngày 23/10/2026).
  • Full access: toàn quyền (video đăng ngày 23/10/2026).
  • Workspace write: được ghi trong workspace, nhưng không ghi ở chỗ khác (video đăng ngày 23/10/2026).

Còn approval là câu hỏi: agent có nên xin duyệt hay không bao giờ xin. Anh nói anh hay chọn full access và never, nhưng mặc định là hai giá trị trong code (WorkspaceWrite và OnRequest). Trang NuGet của package cũng ghi mặc định là ApprovalPolicy.OnRequest và Permissions.WorkspaceWrite, khớp với preset Auto của Codex (đọc ngày 26/10/2026).

9. Instructions, tool C#, câu hỏi cho user và run event

Nếu không có AGENTS.md, bạn vẫn có thể gửi thêm instructions ngay trong options khi cần. Và một điều Rasmus gọi là rất hay: bạn dùng được tool thật kiểu Agent Framework, và Codex vẫn thực thi chúng, chỉ bằng cách truyền vào một tập tool như bình thường (theo video đăng ngày 23/10/2026). Trong sample, đó là AIFunctionFactory.Create(GetWeather).

Codex còn có khả năng đặt câu hỏi, không chỉ trong câu trả lời mà dưới dạng một prompt hỏi trước (upfront prompt), theo Rasmus trong video đăng ngày 23/10/2026. Việc này cần được xử lý bằng code ở phía dưới, trong HandleUserInputRequestedAsync. Anh không đi sâu, nhưng về cơ bản nó đưa ra vài câu hỏi, bạn trả lời, rồi code gửi các câu trả lời đó ngược lại cho Codex để nó làm tiếp.

Nếu muốn theo dõi chuyện gì đang diễn ra trong Codex, như khi nào một lần chạy bắt đầu, khi nào kết thúc, nó đang nghĩ gì, tool nào đang được gọi, theo Rasmus (video đăng ngày 23/10/2026) bạn lấy được hết qua CodexRunEvent, có nhiều loại (kind) và nhiều command khác nhau. Trong sample, hàm HandleRunEvent bỏ qua các delta và in phần tóm tắt của từng event ra màn hình bằng màu xám.

Theo Rasmus (video đăng ngày 23/10/2026), nếu bạn thật sự muốn build một harness hoàn chỉnh từ đây, bạn sẽ dùng hai cơ chế này (câu hỏi cho user và run event). Còn nếu muốn nó chạy tự động hơn ở phía sau, có lẽ bạn sẽ không dùng chúng, không dùng cơ chế nhập liệu nào, và đặt nó ở chế độ full access để nó hoàn toàn tự chủ.

Code C# của bạnAgent Framework Codexworking directory Tools: GetWeather (C#) OnRunEvent: run started, message, command, tool call câu trả lời cho OnUserInputRequested Muốn chạy tự động: bỏ hai callback, đặt full access + never
Hình 9.1Những gì đi qua lại giữa code C# và Codex theo cách Rasmus giải thích trong video đăng ngày 23/10/2026: tool C# do code cung cấp, run event Codex gửi về, và câu trả lời cho các câu hỏi Codex đặt ra.

Theo anh (video đăng ngày 23/10/2026), đó là những thiết lập quan trọng nhất. Ngoài ra còn nhiều thứ khác: ID, name và description quen thuộc, rồi đủ loại thứ bổ sung bạn có thể gửi vào nếu muốn làm một local model provider. Bạn cũng có thể lấy phần tool calling từ code C#, và đi sâu hơn nữa với các tham số resume thread. Anh nói nó thật sự rất, rất nâng cao. Bạn có thể vào đó, nhưng có lẽ bạn không cần.

10. Session: hỏi về Elvis, lấy thread ID rồi resume

Giờ Rasmus chạy một session. Khi dùng Codex, tất nhiên nó chạy theo các cuộc chat, hay thread, tùy cách gọi, và theo anh chúng cũng được hỗ trợ ở đây qua cơ chế tạo session (theo video đăng ngày 23/10/2026). Anh gọi CreateSessionAsync rồi hỏi "Who is Elvis?", và dĩ nhiên nhận được câu trả lời. Event đầu tiên hiện ra là "run started". Câu trả lời về đúng là nói về Elvis, và được viết bằng giọng cướp biển (pirate speak) theo AGENTS.md (demo trong video đăng ngày 23/10/2026).

Vậy là đã có một cuộc hội thoại. Nếu muốn, bạn gọi session.GetThreadId() để lấy thread ID thật bên Codex (theo video đăng ngày 23/10/2026). Rasmus mở lại app Codex để so: ID này chính là thứ bạn lấy được khi mở menu của thread trong app, chọn Copy rồi "Copy deeplink"; theo anh, đó chính là thread ID.

Có thread ID rồi, bạn lưu nó lại ở đâu đó, và sau này chỉ cần tạo một session mới truyền ID đó vào để resume. Anh hỏi tiếp "How tall is he?". Agent biết phần đầu của cuộc trò chuyện, nên theo anh nó trả lời được về chiều cao của Elvis Presley (demo trong video đăng ngày 23/10/2026).

AgentSession session = await agent.CreateSessionAsync();

AgentResponse startConversation = await agent.RunAsync("Who is Elvis?", session);

string codexThreadId = session.GetThreadId()!;

AgentSession resumedSession = await agent.CreateSessionAsync(codexThreadId);
CreateSessionAsync()thread mới trong Codex "Who is Elvis?"run started, trả lời GetThreadId()= deeplink trong app CreateSessionAsync(id)"How tall is he?" Thread ID là thứ cần lưu lại để quay về đúng cuộc trò chuyện
Hình 10.1Vòng đời session trong sample của Rasmus (video đăng ngày 23/10/2026): tạo session, hỏi, lấy thread ID của Codex, rồi resume bằng ID đó để hỏi tiếp.

11. Chat loop với tool approval và danh sách file thay đổi

Phần còn lại của video đăng ngày 23/10/2026, Rasmus chỉ dùng một chat loop để thử nhiều thứ: tạo file, tạo ảnh, và vân vân. Thứ duy nhất anh thêm vào là cách xử lý tool call approval thông thường. Nếu có việc gì cần anh duyệt, nó sẽ hiện lên và hỏi ngay trong vòng lặp. Trong code, vòng while lọc các ToolApprovalRequestContent trong response, in thông tin ra, hỏi "Approve? [Y/N]", rồi gửi các quyết định ngược lại bằng một ChatMessage mới.

Code chat loop: vòng while xử lý ToolApprovalRequestContent, hỏi Approve? [Y/N], rồi GetFileChanges
Chat loop trong sample (video đăng ngày 23/10/2026): đoạn được bôi đậm là phần xử lý approval; bên dưới, response.GetFileChanges() trả về danh sách CodexFileChange để in đường dẫn từng file.

Ngoài ra, theo Rasmus (video đăng ngày 23/10/2026), nếu hệ thống thay đổi file nào thì bạn lấy lại được qua GetFileChanges, để tham chiếu các file đó theo dạng có cấu trúc chứ không chỉ đọc trong câu trả lời. Chỗ này hơi khác một chút; còn lại là hoàn toàn bình thường. Phía trên là các phần bổ sung để nhận các event lõi.

Anh nhắc lại (video đăng ngày 23/10/2026): tất cả những thứ này không cần nếu bạn chỉ muốn dùng nó như một chatbot. Nhưng nếu muốn build một thứ thật, đầy đủ các tính năng đi kèm, bạn có thể sẽ cần hết. Rồi anh chạy, dùng nó như một chatbot.

12. Demo: sửa AGENTS.md và xem trong folder có gì

Yêu cầu đầu tiên Rasmus gõ là "Update Agents.md to not speak like a pirate". Một lần chạy bắt đầu, và theo anh các tin nhắn nhỏ xen giữa sẽ luôn hiện ra, đúng như những gì bạn thường thấy trong Codex trước khi câu trả lời thật về (demo trong video đăng ngày 23/10/2026). Trên màn hình, agent báo sẽ sửa AGENTS.md cho dùng ngôn ngữ thường, chạy một lệnh PowerShell Get-Content để đọc file (ra dòng "Speak like a pirate"), rồi có event FileChange báo file đã được sửa.

Console chat loop: Update Agents.md to not speak like a pirate, các dòng Run, Message, Command, FileChange; cửa sổ Agents.md ghi Use plain, natural language. Do not speak like a pirate.
Demo trong video đăng ngày 23/10/2026: các event [Run], [Message], [Command], [FileChange] hiện từng dòng, chương trình in ra file đã đổi; cửa sổ Agents.md phía trên giờ ghi "Use plain, natural language. Do not speak like a pirate."

Mở file AGENTS.md ra, anh cho thấy nó giờ ghi là không nói như cướp biển nữa. Theo Rasmus (video đăng ngày 23/10/2026), cũng như khi làm với Codex hay các coding agent khác, ở đây làm được y như vậy.

Câu tiếp theo: "what is in this folder?". Agent chỉ việc quét folder, tìm ra trong đó có gì: trên màn hình là đúng một file AGENTS.md (demo trong video đăng ngày 23/10/2026). Một lần nữa anh chỉ ra tất cả những tin nhắn mà bình thường bị giấu đi khi bạn dùng Codex. Theo anh, ở đây làm được bất cứ gì Codex làm được.

13. Demo: web search tin tức không gian

Rasmus hỏi "What is the latest space news?". Theo anh, vì Codex có web search, nó sẽ tìm trên web, giống như khi dùng web search tool trong Responses API (video đăng ngày 23/10/2026). Trên màn hình là một loạt event WebSearch bắt đầu và hoàn tất, có cả truy vấn "space news October 21 2026 latest" và trang tin của NASA.

Console với các dòng WebSearch và kết quả Here are some of the latest space headlines as of October 21, 2026
Kết quả web search trong demo của video đăng ngày 23/10/2026: sau các event WebSearch, agent trả về bốn tin không gian "as of October 21, 2026", mỗi tin kèm link nguồn (NASA, Space.com).

Tìm xong, agent trả về những tin không gian mới tính đến ngày 21 tháng 10, mà Rasmus nói chính là ngày anh làm video này (demo trong video đăng ngày 23/10/2026). Trên màn hình là bốn mẩu tin ngày 20/10: SpaceX phóng lại Starfall, NASA tiến triển về động cơ đẩy hạt nhân, thiết kế cánh quạt mới cho trực thăng sao Hỏa, và phi hành đoàn ISS làm in sinh học cùng chuẩn bị đi bộ ngoài không gian.

14. Demo: tạo ảnh con hổ và xin phép mở file

Tiếp theo là tạo ảnh: "create an image of a tiger and place it in the working directory". Lần này agent dùng skill, và một loạt thứ diễn ra. Theo Rasmus (video đăng ngày 23/10/2026), nó đọc skill tạo ảnh có sẵn trong Codex, nên một lần nữa mình có tất cả những thứ này gần như miễn phí. Và nếu có skill do anh tự viết, nó cũng dùng được những skill đó.

Anh nói đôi khi hơi phiền khi nhận về hết các tin nhắn này, vì về cơ bản nó in ra toàn bộ skill tạo ảnh mà nó vừa đọc: trên màn hình là cả đoạn dài về biến môi trường, chế độ script và bảng tham chiếu các file trong skill. Trong một chatbot thật, tất nhiên bạn sẽ không in hết ra như vậy, hoặc thu gọn mặc định giống cách các tool đang làm (theo Rasmus, video đăng ngày 23/10/2026).

Rồi agent tạo ra file tiger.png. Trên màn hình, nó ghi đã dùng trình tạo ảnh có sẵn với prompt cho một con hổ Bengal chân thực đứng trong rừng xanh dưới ánh sáng ban ngày dịu (demo trong video đăng ngày 23/10/2026).

Lười một chút, Rasmus gõ "launch it". Vì thiết lập approval của anh, nó hiện lên hỏi xin phép: trên màn hình là "Permission to run a command", lý do "May I open tiger.png in your default image viewer?", kèm working directory và lệnh PowerShell Start-Process, cuối cùng là "Approve? [Y/N]" (demo trong video đăng ngày 23/10/2026). Anh nói nếu không muốn bước này, bạn chỉ cần vào đặt là không bao giờ hỏi approval, và nó sẽ mở luôn.

Lần này phải duyệt, anh gõ y, và con hổ hiện lên trong trình xem ảnh mặc định của anh. Theo Rasmus (video đăng ngày 23/10/2026), thật ra chẳng có gì ở đây mà mình không làm được.

"launch it"người dùng gõ Permission to runa command (OnRequest) Approve? [Y/N]người dùng gõ y Start-Processmở tiger.png Đặt ApprovalPolicy = Never thì bỏ qua bước hỏi
Hình 14.1Luồng duyệt khi mở ảnh trong demo của video đăng ngày 23/10/2026: Codex xin chạy lệnh, chat loop hỏi người dùng, có "y" thì lệnh mới chạy.

15. Demo: tạo file trong và ngoài workspace

Tất nhiên Rasmus cũng có thể bảo "create a random file in the folder", và một lát sau file được tạo ra. Lần này nó không hỏi xin phép, vì anh đang đặt WorkspaceWrite (demo trong video đăng ngày 23/10/2026).

Nhưng khi anh yêu cầu tạo một file ngẫu nhiên ở một folder khác không phải workspace (trên màn hình là D:\Hello), nó quay lại xin phép, đúng theo thiết lập anh đã đặt. Trên màn hình, lý do agent đưa ra là "May I create a random text file in D:\Hello, outside the working directory?"; anh gõ y, và file random-55b004b0.txt được tạo trong D:\Hello (demo trong video đăng ngày 23/10/2026).

Console: Create a random file in D:\Hello, Permission to run a command, Reason: May I create a random text file in D:\Hello, outside the working directory?
Demo trong video đăng ngày 23/10/2026: ghi file ra ngoài working directory khiến Codex xin phép, kèm lệnh PowerShell nó định chạy; sau khi được duyệt, file ngẫu nhiên xuất hiện trong D:\Hello.

Anh nhắc lại, trong trường hợp của mình anh sẽ chuyển approval sang never và cho full access. Theo anh (video đăng ngày 23/10/2026), khi đó nó làm được hết những việc này mà không có yêu cầu xin phép nào.

16. Demo: hỏi lại user và gọi tool thời tiết viết bằng C#

Thứ cuối cùng là tính năng câu hỏi. Rasmus nói hơi khó để nó hiện ra. Anh gõ "use your question feature to let me choose between 3 random color". Nếu bạn dùng Codex, có thể bạn biết đôi khi nó bật lên một câu hỏi như vậy. Lần này thì được; theo anh, có lúc anh không làm nó hiện ra được, nó chỉ trả về văn bản (demo trong video đăng ngày 23/10/2026).

Nhưng lần này nó đi vào đoạn code xử lý câu hỏi. Anh cho xem đoạn code đó: nó lấy các lựa chọn, nối chuỗi lại và hiện ra. Trên màn hình là câu hỏi "Which color do you choose?" với ba lựa chọn Teal / Coral / Violet. Anh gõ "3rd one", câu trả lời được gửi về, và agent đáp "You chose Violet" (demo trong video đăng ngày 23/10/2026).

Console: Which color do you choose? Teal / Coral / Violet, 3rd one, You chose Violet; rồi What is the weather i Paris với ToolCall GetWeather và kết quả sunny and 19°C
Hai demo cuối trong video đăng ngày 23/10/2026: câu hỏi chọn màu (Teal / Coral / Violet, chọn cái thứ ba là Violet), rồi câu hỏi thời tiết Paris: event ToolCall gọi tool C# GetWeather với tham số "Paris" và nhận về "It is sunny and 19 Degrees".

Rasmus nói phần này khá hay (video đăng ngày 23/10/2026). Và một lần nữa, theo anh, bạn không cần làm hết những phần thêm như tool approval hay xuất event nếu không cần.

Rồi anh nhớ ra mình chưa cho xem phần gọi tool thời tiết local. Anh hỏi thời tiết ở Paris. Ngoài đời, agent tất nhiên làm được việc này bằng web search, nhưng vì đã có tool nên anh mong nó gọi tool. Lúc đầu anh tưởng nó không gọi, mà dùng web search; rồi anh thấy nó thật ra có gọi tool của mình (demo trong video đăng ngày 23/10/2026). Trên màn hình có cả event WebSearch lẫn ToolCall tới GetWeather.

Anh đọc kết quả là trời nắng và "90 degrees", nhưng màn hình và hàm GetWeather trong sample ghi "It is sunny and 19 Degrees", và câu trả lời cuối của agent là "It's currently sunny and 19°C in Paris, France." (demo trong video đăng ngày 23/10/2026).

static string GetWeather(string city)
{
    return "It is sunny and 19 Degrees";
}

Theo Rasmus (video đăng ngày 23/10/2026), những chỉ dẫn kiểu "đừng dùng web search, đừng làm thế này thế kia" thì nên đưa vào instructions của bạn.

17. Hạn chế: cần Codex CLI, hợp với công cụ chạy local

Rasmus nói cách này rất, rất mạnh. Hạn chế, tất nhiên, là bạn phải có Codex CLI. Vì vậy theo anh (video đăng ngày 23/10/2026), nó không hợp nếu bạn cần build một website host trên Azure, vì bạn không thật sự cài Codex CLI lên đó được, trừ khi chạy trên một máy ảo. Và ngay cả khi đó, có lẽ bạn cũng không muốn đặt Codex trực tiếp lên đấy.

Nên theo anh, cách này chủ yếu dành cho các công cụ local, chẳng hạn build trên một máy Windows. Nhưng việc đó hoàn toàn làm được. Anh lấy ví dụ công cụ tài chính của chính mình, giúp anh quản lý tài chính và trả lời các câu hỏi. Kế hoạch của anh là chuyển công cụ đó sang Codex CLI, vì về cơ bản anh không phải trả tiền token mà vẫn được dùng những model tốt nhất (nhận định của anh trong video đăng ngày 23/10/2026).

Anh nói nó vẫn tiêu một phần usage của anh, và chỉ vào chỗ xem usage trong app Codex. Nhưng theo Rasmus (video đăng ngày 23/10/2026), mức tiêu không hơn gì so với khi anh hỏi đúng câu đó ngay trong Codex: nó không lấy thêm gì cả. Chỉ là mình làm được theo cách này, với chi phí khá rẻ.

HợpKhông hợp Công cụ local trên máy WindowsCodex CLI đã cài và đăng nhậpdùng hạn mức subscriptionví dụ: công cụ tài chính cá nhân Website host trên Azurekhông cài được Codex CLItrừ khi dùng máy ảo, và kể cả vậycũng không muốn đặt Codex lên đó
Hình 17.1Đánh đổi khi triển khai theo lời Rasmus trong video đăng ngày 23/10/2026: package cần Codex CLI có mặt trên máy chạy, nên nó hợp với công cụ local hơn là ứng dụng host trên cloud.

Đó là toàn bộ. Rasmus nhắc lại tên package, AgentFrameworkToolkit.Codex, và nói với package đó bạn sẽ làm được những gì anh vừa cho xem (theo video đăng ngày 23/10/2026). Anh cảm ơn mọi người đã theo dõi.

Nguồn và liên kết 10 nguồn

  1. Tên gốc: How to use Codex as provider for Microsoft Agent Framework #NoTokenCost
  2. Sự kiện: YouTube
  3. Video gốc: https://www.youtube.com/watch?v=1cJjlc073F0 youtube.com
  4. Kênh YouTube AI in C# (Rasmus Wulff Jensen): youtube.com/channel/UClmT_VztthYxP4MaD2fpHLw youtube.com
  5. Code agent đầu tiên trong video, folder ZeroToFirstAgent.Codex của repo agent-framework-samples (đọc ngày 26/10/2026): github.com/rwjdk/agent-framework-samples/.../ZeroToFirstAgent.Codex github.com
  6. Code demo đầy đủ (CodexAgentOptions, session, chat loop, approval, GetWeather), folder AgentFrameworkToolkit.Codex (đọc ngày 26/10/2026): github.com/rwjdk/agent-framework-samples/.../AgentFrameworkToolkit.Codex github.com
  7. Package AgentFrameworkToolkit.Codex trên NuGet, README ghi trạng thái experimental (diagnostic AFT999) và mặc định OnRequest cùng WorkspaceWrite (đọc ngày 26/10/2026): nuget.org/packages/AgentFrameworkToolkit.Codex nuget.org
  8. Repo Agent Framework Toolkit của Rasmus (đọc ngày 26/10/2026): github.com/rwjdk/agent-framework-toolkit github.com
  9. Repo Codex của OpenAI, README có lệnh cài qua npm (đọc ngày 26/10/2026): github.com/openai/codex github.com
  10. Tài liệu Microsoft Agent Framework (đọc ngày 26/10/2026): learn.microsoft.com/en-us/agent-framework learn.microsoft.com