<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/scripts/pretty-feed-v3.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:h="http://www.w3.org/TR/html4/"><channel><title>Nguyen Van Duy Khiem (VI)</title><description>Backend-first engineer building workflow-heavy systems, cloud-native services, and applied AI.</description><link>https://astro-pure.js.org</link><item><title>12 Google Certificates: Danh sách courses Coursera</title><link>https://astro-pure.js.org/vi/blog/google-certifications-course-list</link><guid isPermaLink="true">https://astro-pure.js.org/vi/blog/google-certifications-course-list</guid><description>Tổng hợp đầy đủ 12 Google certifications/specializations và danh sách courses/modules kèm thời lượng học.</description><pubDate>Mon, 27 Apr 2026 08:00:00 GMT</pubDate><content:encoded/><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>Global hóa AWS agent plugins cho Codex</title><link>https://astro-pure.js.org/vi/blog/global-agent-plugins-codex</link><guid isPermaLink="true">https://astro-pure.js.org/vi/blog/global-agent-plugins-codex</guid><description>Clone repo awslabs, copy plugin vào ~/.agents/plugins, và dùng marketplace global của Codex ở mọi repo.</description><pubDate>Wed, 22 Apr 2026 08:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import { Aside, Steps, Tabs, TabItem, Collapse } from &apos;astro-pure/user&apos;
import { LinkPreview } from &apos;astro-pure/advanced&apos;&lt;/p&gt;
&lt;h2&gt;Vì sao phải global hóa plugin?&lt;/h2&gt;
&lt;p&gt;Nếu bạn cài marketplace ở dạng repo-local, Codex chỉ nhìn thấy plugin khi bạn đang mở đúng repo chứa file:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;$REPO_ROOT/.agents/plugins/marketplace.json
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Điều đó ổn khi bạn đang phát triển plugin. Nhưng nếu mục tiêu là:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;dùng lại plugin ở nhiều repo khác nhau&lt;/li&gt;
&lt;li&gt;giữ một bộ plugin AWS cố định cho mọi workspace&lt;/li&gt;
&lt;li&gt;không phải mở repo &lt;code&gt;agent-plugins&lt;/code&gt; chỉ để thấy plugin trong Plugin Directory&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;thì bạn nên chuyển sang &lt;strong&gt;personal marketplace&lt;/strong&gt; ở:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;~/.agents/plugins/marketplace.json
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Ý tưởng kiến trúc&lt;/h2&gt;
&lt;p&gt;Ta sẽ đi theo option an toàn nhất:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Clone repo gốc từ &lt;code&gt;awslabs/agent-plugins&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Lấy các plugin AWS cần dùng từ thư mục &lt;code&gt;plugins/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Copy chúng vào một root global dưới home directory&lt;/li&gt;
&lt;li&gt;Tạo &lt;code&gt;~/.agents/plugins/marketplace.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Restart Codex và kiểm tra plugin xuất hiện ở mọi repo&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Sau khi hoàn tất, cấu trúc của bạn sẽ trông như sau:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;C:\Users\&amp;#x3C;you&gt;\.agents\plugins\
├── marketplace.json
└── agent-plugins-for-aws\
    └── plugins\
        ├── amazon-location-service\
        ├── aws-amplify\
        ├── aws-serverless\
        ├── databases-on-aws\
        ├── deploy-on-aws\
        ├── migration-to-aws\
        └── sagemaker-ai\
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Bước 1: Clone repo gốc từ awslabs&lt;/h2&gt;
&lt;p&gt;Nếu bạn chưa có source, clone repo chính thức:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;git clone https://github.com/awslabs/agent-plugins.git
cd agent-plugins
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nếu bạn chỉ muốn dùng plugin, không cần sửa code trong repo này. Bạn chỉ cần nó như một nguồn để copy runtime assets.&lt;/p&gt;
&lt;h3&gt;Cần lấy gì từ repo?&lt;/h3&gt;
&lt;p&gt;Với mỗi plugin, hãy copy &lt;strong&gt;nguyên thư mục plugin&lt;/strong&gt; bên dưới &lt;code&gt;plugins/&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Ví dụ:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;plugins/amazon-location-service/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;plugins/aws-amplify/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;plugins/aws-serverless/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;plugins/databases-on-aws/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;plugins/deploy-on-aws/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;plugins/migration-to-aws/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;plugins/sagemaker-ai/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Lý do phải copy nguyên thư mục thay vì chỉ lấy &lt;code&gt;plugin.json&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;plugin cần &lt;code&gt;.codex-plugin/plugin.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;nhiều plugin cần &lt;code&gt;skills/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;nhiều plugin cần &lt;code&gt;.mcp.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;một số plugin còn có &lt;code&gt;hooks/&lt;/code&gt;, &lt;code&gt;scripts/&lt;/code&gt;, hoặc tài liệu tham chiếu mà skill sẽ dùng&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Bước 2: Tạo root global cho plugin&lt;/h2&gt;
&lt;p&gt;Trên Windows, tạo thư mục global như sau:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;$GlobalRoot = &quot;$HOME\\.agents\\plugins\\agent-plugins-for-aws&quot;
New-Item -ItemType Directory -Force -Path &quot;$GlobalRoot\\plugins&quot; | Out-Null
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sau đó copy các plugin bạn muốn dùng:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;Copy-Item -Recurse -Force .\plugins\amazon-location-service &quot;$GlobalRoot\\plugins\\&quot;
Copy-Item -Recurse -Force .\plugins\aws-amplify &quot;$GlobalRoot\\plugins\\&quot;
Copy-Item -Recurse -Force .\plugins\aws-serverless &quot;$GlobalRoot\\plugins\\&quot;
Copy-Item -Recurse -Force .\plugins\databases-on-aws &quot;$GlobalRoot\\plugins\\&quot;
Copy-Item -Recurse -Force .\plugins\deploy-on-aws &quot;$GlobalRoot\\plugins\\&quot;
Copy-Item -Recurse -Force .\plugins\migration-to-aws &quot;$GlobalRoot\\plugins\\&quot;
Copy-Item -Recurse -Force .\plugins\sagemaker-ai &quot;$GlobalRoot\\plugins\\&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nếu bạn chỉ dùng một vài plugin, chỉ copy đúng những plugin đó.&lt;/p&gt;
&lt;h2&gt;Bước 3: Tạo marketplace global&lt;/h2&gt;
&lt;p&gt;Tạo file:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;C:\Users\&amp;#x3C;you&gt;\.agents\plugins\marketplace.json
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;với nội dung như sau:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;name&quot;: &quot;agent-plugins-for-aws&quot;,
  &quot;interface&quot;: {
    &quot;displayName&quot;: &quot;Agent Plugins for AWS&quot;
  },
  &quot;plugins&quot;: [
    {
      &quot;name&quot;: &quot;amazon-location-service&quot;,
      &quot;source&quot;: {
        &quot;source&quot;: &quot;local&quot;,
        &quot;path&quot;: &quot;./agent-plugins-for-aws/plugins/amazon-location-service&quot;
      },
      &quot;policy&quot;: {
        &quot;installation&quot;: &quot;AVAILABLE&quot;,
        &quot;authentication&quot;: &quot;ON_INSTALL&quot;
      },
      &quot;category&quot;: &quot;Location&quot;
    },
    {
      &quot;name&quot;: &quot;aws-amplify&quot;,
      &quot;source&quot;: {
        &quot;source&quot;: &quot;local&quot;,
        &quot;path&quot;: &quot;./agent-plugins-for-aws/plugins/aws-amplify&quot;
      },
      &quot;policy&quot;: {
        &quot;installation&quot;: &quot;AVAILABLE&quot;,
        &quot;authentication&quot;: &quot;ON_INSTALL&quot;
      },
      &quot;category&quot;: &quot;Full Stack&quot;
    },
    {
      &quot;name&quot;: &quot;aws-serverless&quot;,
      &quot;source&quot;: {
        &quot;source&quot;: &quot;local&quot;,
        &quot;path&quot;: &quot;./agent-plugins-for-aws/plugins/aws-serverless&quot;
      },
      &quot;policy&quot;: {
        &quot;installation&quot;: &quot;AVAILABLE&quot;,
        &quot;authentication&quot;: &quot;ON_INSTALL&quot;
      },
      &quot;category&quot;: &quot;Development&quot;
    },
    {
      &quot;name&quot;: &quot;databases-on-aws&quot;,
      &quot;source&quot;: {
        &quot;source&quot;: &quot;local&quot;,
        &quot;path&quot;: &quot;./agent-plugins-for-aws/plugins/databases-on-aws&quot;
      },
      &quot;policy&quot;: {
        &quot;installation&quot;: &quot;AVAILABLE&quot;,
        &quot;authentication&quot;: &quot;ON_INSTALL&quot;
      },
      &quot;category&quot;: &quot;Database&quot;
    },
    {
      &quot;name&quot;: &quot;deploy-on-aws&quot;,
      &quot;source&quot;: {
        &quot;source&quot;: &quot;local&quot;,
        &quot;path&quot;: &quot;./agent-plugins-for-aws/plugins/deploy-on-aws&quot;
      },
      &quot;policy&quot;: {
        &quot;installation&quot;: &quot;AVAILABLE&quot;,
        &quot;authentication&quot;: &quot;ON_INSTALL&quot;
      },
      &quot;category&quot;: &quot;Deployment&quot;
    },
    {
      &quot;name&quot;: &quot;migration-to-aws&quot;,
      &quot;source&quot;: {
        &quot;source&quot;: &quot;local&quot;,
        &quot;path&quot;: &quot;./agent-plugins-for-aws/plugins/migration-to-aws&quot;
      },
      &quot;policy&quot;: {
        &quot;installation&quot;: &quot;AVAILABLE&quot;,
        &quot;authentication&quot;: &quot;ON_INSTALL&quot;
      },
      &quot;category&quot;: &quot;Migration&quot;
    },
    {
      &quot;name&quot;: &quot;sagemaker-ai&quot;,
      &quot;source&quot;: {
        &quot;source&quot;: &quot;local&quot;,
        &quot;path&quot;: &quot;./agent-plugins-for-aws/plugins/sagemaker-ai&quot;
      },
      &quot;policy&quot;: {
        &quot;installation&quot;: &quot;AVAILABLE&quot;,
        &quot;authentication&quot;: &quot;ON_INSTALL&quot;
      },
      &quot;category&quot;: &quot;AI&quot;
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Điểm quan trọng nhất trong file này là &lt;code&gt;source.path&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;luôn bắt đầu bằng &lt;code&gt;./&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;được resolve relative với thư mục chứa &lt;code&gt;marketplace.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;vì thế &lt;code&gt;./agent-plugins-for-aws/plugins/...&lt;/code&gt; sẽ trỏ đúng tới cây plugin global vừa copy&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Bước 4: Kiểm tra thư mục plugin trước khi mở Codex&lt;/h2&gt;
&lt;p&gt;Mỗi plugin nên có ít nhất:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.codex-plugin/plugin.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;skills/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.mcp.json&lt;/code&gt; nếu plugin cần MCP servers&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Bạn có thể tự kiểm tra nhanh bằng PowerShell:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;$MarketRoot = &quot;$HOME\\.agents\\plugins&quot;
$Plugins = @(
  &quot;amazon-location-service&quot;,
  &quot;aws-amplify&quot;,
  &quot;aws-serverless&quot;,
  &quot;databases-on-aws&quot;,
  &quot;deploy-on-aws&quot;,
  &quot;migration-to-aws&quot;,
  &quot;sagemaker-ai&quot;
)

$Plugins | ForEach-Object {
  $Path = Join-Path $MarketRoot &quot;agent-plugins-for-aws\\plugins\\$_&quot;
  [PSCustomObject]@{
    Name = $_
    PluginDir = Test-Path $Path
    CodexManifest = Test-Path (Join-Path $Path &quot;.codex-plugin\\plugin.json&quot;)
    Skills = Test-Path (Join-Path $Path &quot;skills&quot;)
    McpConfig = Test-Path (Join-Path $Path &quot;.mcp.json&quot;)
  }
} | Format-Table -AutoSize
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nếu tất cả cột đều &lt;code&gt;True&lt;/code&gt;, tree global của bạn đã usable.&lt;/p&gt;
&lt;h2&gt;Bước 5: Restart Codex và xác nhận plugin xuất hiện ở mọi repo&lt;/h2&gt;
&lt;p&gt;Sau khi có &lt;code&gt;~/.agents/plugins/marketplace.json&lt;/code&gt;, restart Codex để nó nạp personal marketplace mới.&lt;/p&gt;
&lt;p&gt;Rồi mở &lt;strong&gt;một repo bất kỳ không liên quan tới AWS plugins&lt;/strong&gt;. Đây là test quan trọng nhất. Nếu plugin vẫn xuất hiện trong Plugin Directory ở repo đó, cấu hình global của bạn đã đúng.&lt;/p&gt;
&lt;p&gt;Nếu plugin chỉ xuất hiện khi bạn mở repo &lt;code&gt;agent-plugins&lt;/code&gt;, nghĩa là bạn vẫn đang dùng marketplace repo-local chứ chưa chuyển hẳn sang personal marketplace.&lt;/p&gt;
&lt;h2&gt;Cài plugin rồi có cần giữ repo gốc không?&lt;/h2&gt;
&lt;p&gt;Không bắt buộc.&lt;/p&gt;
&lt;p&gt;Khi bạn đã copy các plugin cần thiết vào &lt;code&gt;~/.agents/plugins/agent-plugins-for-aws/&lt;/code&gt;, Codex sẽ đọc từ đó. Repo gốc chỉ còn là:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;nơi để cập nhật plugin khi upstream thay đổi&lt;/li&gt;
&lt;li&gt;nơi để xem source hoặc đóng góp lại cho &lt;code&gt;awslabs/agent-plugins&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nếu bạn không định theo dõi upstream, về mặt runtime bạn không còn phụ thuộc vào repo gốc nữa.&lt;/p&gt;
&lt;h2&gt;Khi nào không nên dùng cách này?&lt;/h2&gt;
&lt;p&gt;Copy plugin vào global root là cách đơn giản nhất, nhưng không phải lúc nào cũng phù hợp.&lt;/p&gt;
&lt;p&gt;Bạn có thể chưa nên dùng nếu:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;bạn đang phát triển plugin hằng ngày và muốn mọi thay đổi phản ánh trực tiếp từ repo dev&lt;/li&gt;
&lt;li&gt;bạn thường xuyên đổi branch hoặc test plugin đang dở dang&lt;/li&gt;
&lt;li&gt;bạn muốn một workflow symlink hoặc automation cập nhật tinh gọn hơn&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Trong các case đó, repo-local marketplace hoặc một script sync tự động có thể hợp hơn.&lt;/p&gt;
&lt;h2&gt;Các lỗi phổ biến&lt;/h2&gt;
&lt;h3&gt;1. Thấy marketplace nhưng bấm install không ổn&lt;/h3&gt;
&lt;p&gt;Nguyên nhân thường là &lt;code&gt;source.path&lt;/code&gt; đúng tên nhưng thư mục plugin thiếu file runtime như:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.codex-plugin/plugin.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;skills/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.mcp.json&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. Chỉ thấy plugin trong một repo&lt;/h3&gt;
&lt;p&gt;Nguyên nhân là marketplace đang nằm ở:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;$REPO_ROOT/.agents/plugins/marketplace.json
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;thay vì:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;~/.agents/plugins/marketplace.json
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. Sửa file xong nhưng Codex chưa thấy thay đổi&lt;/h3&gt;
&lt;p&gt;Codex thường cần restart để nạp lại marketplace personal và cache plugin local.&lt;/p&gt;
&lt;h2&gt;Chốt lại quy trình&lt;/h2&gt;
&lt;p&gt;Nếu bạn muốn global hóa AWS agent plugins cho Codex theo cách an toàn và dễ bảo trì nhất, công thức là:&lt;/p&gt;
&lt;p&gt;Đây không phải workflow đẹp nhất về mặt “DRY”, nhưng lại là workflow ít bất ngờ nhất. Bạn tách được plugin runtime khỏi repo development, giữ được marketplace global rõ ràng, và không còn phụ thuộc vào việc phải mở đúng repo thì Codex mới thấy plugin.&lt;/p&gt;
&lt;h2&gt;Tham khảo&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.openai.com/codex/plugins/build&quot;&gt;OpenAI Codex plugins build docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/awslabs/agent-plugins&quot;&gt;awslabs/agent-plugins trên GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>free-coding-models — Tìm LLM Coding Nhanh Trong Giây</title><link>https://astro-pure.js.org/vi/blog/free-coding-models</link><guid isPermaLink="true">https://astro-pure.js.org/vi/blog/free-coding-models</guid><description>Ping 160 mô hình coding miễn phí từ 20 nhà cung cấp theo thời gian thực. Chọn mô hình tốt nhất cho OpenCode, OpenClaw, hoặc bất kỳ AI coding assistant nào.</description><pubDate>Wed, 18 Mar 2026 08:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import { Aside, Tabs, TabItem, Collapse, Steps, Button } from &apos;astro-pure/user&apos;
import { GithubCard, LinkPreview, QRCode } from &apos;astro-pure/advanced&apos;&lt;/p&gt;
&lt;h2&gt;Giới thiệu&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;free-coding-models&lt;/code&gt; là một công cụ TUI thời gian thực ping &lt;strong&gt;160 mô hình coding&lt;/strong&gt; từ &lt;strong&gt;20 nhà cung cấp&lt;/strong&gt; đồng thời, giúp bạn tìm LLM nhanh nhất cho AI coding assistant của mình.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.shields.io/npm/v/free-coding-models?color=76b900&amp;#x26;label=npm&amp;#x26;logo=npm&quot; alt=&quot;npm version&quot;&gt;
&lt;img src=&quot;https://img.shields.io/node/v/free-coding-models?color=76b900&amp;#x26;logo=node.js&quot; alt=&quot;node version&quot;&gt;
&lt;img src=&quot;https://img.shields.io/npm/l/free-coding-models?color=76b900&quot; alt=&quot;license&quot;&gt;
&lt;img src=&quot;https://img.shields.io/badge/models-160-76b900?logo=nvidia&quot; alt=&quot;models count&quot;&gt;
&lt;img src=&quot;https://img.shields.io/badge/providers-20-blue&quot; alt=&quot;providers count&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Những người đóng góp&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/vava-nessa&quot;&gt;vava-nessa&lt;/a&gt; · &lt;a href=&quot;https://github.com/erwinh22&quot;&gt;erwinh22&lt;/a&gt; · &lt;a href=&quot;https://github.com/whit3rabbit&quot;&gt;whit3rabbit&lt;/a&gt; · &lt;a href=&quot;https://github.com/skylaweber&quot;&gt;skylaweber&lt;/a&gt; · &lt;a href=&quot;https://github.com/PhucTruong-ctrl&quot;&gt;PhucTruong-ctrl&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;💬 &lt;a href=&quot;https://discord.gg/ZTNFHvvCkU&quot;&gt;Thảo luận về dự án trên Discord&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Bởi Vanessa Depraute&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. Tạo API key miễn phí (NVIDIA, OpenRouter, Hugging Face, v.v.)
2. npm i -g free-coding-models
3. free-coding-models
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Tìm mô hình LLM coding nhanh nhất trong vài giây&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Ping các mô hình coding miễn phí từ 20 nhà cung cấp theo thời gian thực — chọn mô hình tốt nhất cho OpenCode, OpenClaw, hoặc bất kỳ AI coding assistant nào&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Thông báo beta&lt;/strong&gt;&lt;br&gt;
Hỗ trợ FCM Proxy V2 cho các công cụ bên ngoài vẫn đang trong giai đoạn beta. Claude Code, Codex, Gemini và các launcher proxy-backed khác đã hoạt động trong nhiều thiết lập, nhưng các trường hợp edge về auth và khởi động vẫn có thể thất bại khi tích hợp đang ổn định.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2&gt;Mục lục&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#-t%C3%ADnh-n%C4%83ng&quot;&gt;✨ Tính năng&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#-y%C3%AAu-c%E1%BA%A7u&quot;&gt;📋 Yêu cầu&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#-c%C3%A0i-%C4%91%E1%BA%B7t&quot;&gt;📦 Cài đặt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#-s%E1%BB%AD-d%E1%BB%A5ng&quot;&gt;🚀 Sử dụng&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#-c%E1%BB%99t-tui&quot;&gt;📊 Cột TUI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#-%C4%91i%E1%BB%83m-%E1%BB%95n-%C4%91%E1%BB%8Bnh&quot;&gt;📐 Điểm ổn định&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#-fcm-proxy-v2&quot;&gt;📡 FCM Proxy V2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#-m%C3%B4-h%C3%ACnh-coding&quot;&gt;🤖 Mô hình Coding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#-t%C3%ADch-h%E1%BB%A3p-opencode&quot;&gt;🔌 Tích hợp OpenCode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#-t%C3%ADch-h%E1%BB%A3p-openclaw&quot;&gt;🦞 Tích hợp OpenClaw&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#-c%C3%A1ch-ho%E1%BA%A1t-%C4%91%E1%BB%99ng&quot;&gt;⚙️ Cách hoạt động&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;✨ Tính năng&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;🎯 Tập trung coding&lt;/strong&gt; — Chỉ các mô hình LLM được tối ưu cho việc tạo code, không phải chat hay vision&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;🌐 Nhiều nhà cung cấp&lt;/strong&gt; — Mô hình từ NVIDIA NIM, Groq, Cerebras, SambaNova, OpenRouter, Hugging Face Inference, Replicate, DeepInfra, Fireworks AI, Codestral, Hyperbolic, Scaleway, Google AI, SiliconFlow, Together AI, Cloudflare Workers AI, Perplexity API, Alibaba Cloud (DashScope), ZAI, và iFlow&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;⚙️ Màn hình cài đặt&lt;/strong&gt; — Nhấn &lt;code&gt;P&lt;/code&gt; để quản lý API key nhà cung cấp, bật/tắt nhà cung cấp, truy cập cài đặt FCM Proxy V2, và kiểm tra/cài đặt cập nhật&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;📡 FCM Proxy V2&lt;/strong&gt; — Reverse proxy tích hợp với xoay vòng nhiều key, failover giới hạn rate, và dịch định dạng wire Anthropic cho Claude Code. Chế độ background service tùy chọn giữ proxy chạy 24/7&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;🚀 Ping song song&lt;/strong&gt; — Tất cả mô hình được test đồng thời qua native &lt;code&gt;fetch&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;📊 Animation thời gian thực&lt;/strong&gt; — Xem độ trễ xuất hiện trực tiếp trong buffer màn hình alternate&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;🏆 Xếp hạng thông minh&lt;/strong&gt; — Top 3 mô hình nhanh nhất được highlight với huy chương 🥇🥈🥉&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;⏱ Giám sát thích ứng&lt;/strong&gt; — Bắt đầu với nhịp 2s nhanh trong 60s, ổn định ở 10s, chậm lại 30s sau 5 phút idle, và hỗ trợ chế độ 4s bắt buộc&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;📈 Trung bình cuộn&lt;/strong&gt; — Avg được tính từ TẤT CẢ các ping thành công từ khi bắt đầu&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;📊 Theo dõi uptime&lt;/strong&gt; — Tỷ lệ phần trăm ping thành công hiển thị thời gian thực&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;📐 Điểm ổn định&lt;/strong&gt; — Điểm composite 0–100 đo lường tính nhất quán (p95, jitter, spikes, uptime)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;📊 Theo dõi token usage&lt;/strong&gt; — Proxy logs token prompt+completion cho mỗi cặp nhà cung cấp/mô hình chính xác&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;📜 Request Log Overlay&lt;/strong&gt; — Nhấn &lt;code&gt;X&lt;/code&gt; để kiểm tra các request proxied gần đây và token usage&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;📋 Changelog Overlay&lt;/strong&gt; — Nhấn &lt;code&gt;N&lt;/code&gt; để duyệt tất cả phiên bản trong index&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;🛠 MODEL_NOT_FOUND Rotation&lt;/strong&gt; — Nếu nhà cung cấp trả về 404, TUI xoay qua các nhà cung cấp khác cho cùng mô hình&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;🔄 Auto-retry&lt;/strong&gt; — Các mô hình timeout tiếp tục được retry&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;🎮 Lựa chọn tương tác&lt;/strong&gt; — Di chuyển bằng phím mũi tên, nhấn Enter để hành động&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;💻 Tích hợp OpenCode&lt;/strong&gt; — Tự động phát hiện setup NIM, đặt mô hình làm mặc định, launch OpenCode&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;🦞 Tích hợp OpenClaw&lt;/strong&gt; — Đặt mô hình đã chọn làm nhà cung cấp mặc định&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;🧰 Public tool launchers&lt;/strong&gt; — 13 chế độ công cụ: OpenCode CLI, OpenCode Desktop, OpenClaw, Crush, Goose, Aider, Claude Code, Codex, Gemini, Qwen, OpenHands, Amp, và Pi&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;🔌 Install Endpoints flow&lt;/strong&gt; — Nhấn &lt;code&gt;Y&lt;/code&gt; để cài đặt nhà cung cấp vào công cụ&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;📝 Feature Request (phím J)&lt;/strong&gt; — Gửi phản hồi ẩn danh&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;🐛 Bug Report (phím I)&lt;/strong&gt; — Gửi báo cáo lỗi ẩn danh&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;📶 Chỉ báo trạng thái&lt;/strong&gt; — UP ✅ · No Key 🔑 · Timeout ⏳ · Overloaded 🔥 · Not Found 🚫&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;🏷 Lọc tier&lt;/strong&gt; — Lọc mô hình theo chữ tier (S, A, B, C)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;⭐ Favorites bền vững&lt;/strong&gt; — Nhấn &lt;code&gt;F&lt;/code&gt; để ghim/bỏ ghim mô hình&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;📋 Yêu cầu&lt;/h2&gt;
&lt;p&gt;Trước khi sử dụng &lt;code&gt;free-coding-models&lt;/code&gt;, hãy đảm bảo bạn có:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Node.js 18+&lt;/strong&gt; — Bắt buộc cho native &lt;code&gt;fetch&lt;/code&gt; API&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ít nhất một API key miễn phí&lt;/strong&gt; — chọn bất kỳ hoặc tất cả:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;NVIDIA NIM&lt;/strong&gt; — &lt;a href=&quot;https://build.nvidia.com&quot;&gt;build.nvidia.com&lt;/a&gt; → Profile → API Keys → Generate — free tier: 40 req/phút (không cần thẻ tín dụng)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Groq&lt;/strong&gt; — &lt;a href=&quot;https://console.groq.com/keys&quot;&gt;console.groq.com/keys&lt;/a&gt; → Create API Key — free tier: 30-50 RPM mỗi mô hình (khác nhau)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cerebras&lt;/strong&gt; — &lt;a href=&quot;https://cloud.cerebras.ai&quot;&gt;cloud.cerebras.ai&lt;/a&gt; → API Keys → Create — free tier: hào phóng (developer tier giới hạn cao hơn 10×)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SambaNova&lt;/strong&gt; — &lt;a href=&quot;https://sambanova.ai/developers&quot;&gt;sambanova.ai/developers&lt;/a&gt; → Developers portal → API key (dev tier hào phóng)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OpenRouter&lt;/strong&gt; — &lt;a href=&quot;https://openrouter.ai/keys&quot;&gt;openrouter.ai/keys&lt;/a&gt; → Create key (request miễn phí trên &lt;code&gt;:free&lt;/code&gt; models, xem chi tiết bên dưới)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Chi tiết Free Tier OpenRouter&lt;/h3&gt;
&lt;p&gt;OpenRouter cung cấp request miễn phí trên các mô hình free (&lt;code&gt;:free&lt;/code&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;──────────────────────────────────────────────────
  OpenRouter — Request miễn phí trên mô hình free (:free)
──────────────────────────────────────────────────

  Không credits (hoặc &amp;#x3C;$10)   →   50  request / ngày   (20 req/phút)
  ≥ $10 credits              →  1000 request / ngày   (20 req/phút)

──────────────────────────────────────────────────
Những điều cần biết:

  • Mô hình free (:free) không bao giờ tiêu tốn credits của bạn.
    $10 của bạn vẫn nguyên nếu chỉ dùng mô hình :free.

  • Request thất bại vẫn được tính vào quota hàng ngày.

  • Quota reset mỗi ngày lúc nửa đêm UTC.

  • Mô hình free-tier phổ biến có thể bị rate-limit thêm
    bởi nhà cung cấp trong giờ cao điểm.
──────────────────────────────────────────────────
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Hugging Face Inference&lt;/strong&gt; — &lt;a href=&quot;https://huggingface.co/settings/tokens&quot;&gt;huggingface.co/settings/tokens&lt;/a&gt; → Access Tokens (credits miễn phí hàng tháng)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Replicate&lt;/strong&gt; — &lt;a href=&quot;https://replicate.com/account/api-tokens&quot;&gt;replicate.com/account/api-tokens&lt;/a&gt; → Create token — free tier: 6 req/phút (không cần thanh toán) — lên đến 3,000 RPM (API) / 600 RPM (predictions) với thanh toán&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DeepInfra&lt;/strong&gt; — &lt;a href=&quot;https://deepinfra.com/login&quot;&gt;deepinfra.com/login&lt;/a&gt; → Login → API key — free tier: 200 request đồng thời (mặc định)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fireworks AI&lt;/strong&gt; — &lt;a href=&quot;https://fireworks.ai&quot;&gt;fireworks.ai&lt;/a&gt; → Settings → Access Tokens — $1 credits miễn phí; 10 req/phút không cần thanh toán (giới hạn đầy đủ với thanh toán)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mistral Codestral&lt;/strong&gt; — &lt;a href=&quot;https://codestral.mistral.ai&quot;&gt;codestral.mistral.ai&lt;/a&gt; → API Keys (30 req/phút, 2000/ngày — cần số điện thoại)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hyperbolic&lt;/strong&gt; — &lt;a href=&quot;https://app.hyperbolic.ai/settings&quot;&gt;app.hyperbolic.ai/settings&lt;/a&gt; → API Keys ($1 dùng thử miễn phí)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scaleway&lt;/strong&gt; — &lt;a href=&quot;https://console.scaleway.com/iam/api-keys&quot;&gt;console.scaleway.com/iam/api-keys&lt;/a&gt; → IAM → API Keys (1M tokens miễn phí)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Google AI Studio&lt;/strong&gt; — &lt;a href=&quot;https://aistudio.google.com/apikey&quot;&gt;aistudio.google.com/apikey&lt;/a&gt; → Get API key (mô hình Gemma miễn phí, 14.4K req/ngày)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SiliconFlow&lt;/strong&gt; — &lt;a href=&quot;https://cloud.siliconflow.cn/account/ak&quot;&gt;cloud.siliconflow.cn/account/ak&lt;/a&gt; → API Keys (quota mô hình miễn phí khác nhau theo mô hình)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Together AI&lt;/strong&gt; — &lt;a href=&quot;https://api.together.ai/settings/api-keys&quot;&gt;api.together.ai/settings/api-keys&lt;/a&gt; → API Keys (credits/khuyến mãi khác nhau)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cloudflare Workers AI&lt;/strong&gt; — &lt;a href=&quot;https://dash.cloudflare.com&quot;&gt;dash.cloudflare.com&lt;/a&gt; → Create API token + đặt &lt;code&gt;CLOUDFLARE_ACCOUNT_ID&lt;/code&gt; (Miễn phí: 10k neurons/ngày)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Perplexity API&lt;/strong&gt; — &lt;a href=&quot;https://www.perplexity.ai/settings/api&quot;&gt;perplexity.ai/settings/api&lt;/a&gt; → API Key (giới hạn tier theo chi tiêu)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ZAI&lt;/strong&gt; — &lt;a href=&quot;https://z.ai&quot;&gt;z.ai&lt;/a&gt; → Get API key (Coding Plan subscription)&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;&lt;strong&gt;OpenCode&lt;/strong&gt; &lt;em&gt;(tùy chọn)&lt;/em&gt; — &lt;a href=&quot;https://github.com/opencode-ai/opencode&quot;&gt;Cài đặt OpenCode&lt;/a&gt; để sử dụng tích hợp OpenCode&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OpenClaw&lt;/strong&gt; &lt;em&gt;(tùy chọn)&lt;/em&gt; — &lt;a href=&quot;https://openclaw.ai&quot;&gt;Cài đặt OpenClaw&lt;/a&gt; để sử dụng tích hợp OpenClaw&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Mẹo:&lt;/strong&gt; Bạn không cần tất cả 20 nhà cung cấp. Một key là đủ để bắt đầu. Thêm nhiều hơn sau qua màn hình Settings (phím &lt;code&gt;P&lt;/code&gt;). Các mô hình không có key vẫn hiển thị độ trễ thực (&lt;code&gt;🔑 NO KEY&lt;/code&gt;) để bạn có thể đánh giá nhà cung cấp trước khi đăng ký.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2&gt;📦 Cài đặt&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# npm (cài đặt global — khuyến nghị)
npm install -g free-coding-models

# pnpm
pnpm add -g free-coding-models

# bun
bun add -g free-coding-models

# Hoặc sử dụng trực tiếp với npx/pnpx/bunx
npx free-coding-models YOUR_API_KEY
pnpx free-coding-models YOUR_API_KEY
bunx free-coding-models YOUR_API_KEY
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;🆕 Có gì mới&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Phiên bản 0.3.5 sửa lỗi tương thích proxy Claude Code chính được tìm thấy trong sử dụng thực tế:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Request beta-route Claude Code giờ hoạt động&lt;/strong&gt; — proxy chấp nhận URL Anthropic như &lt;code&gt;/v1/messages?beta=true&lt;/code&gt; và &lt;code&gt;/v1/messages/count_tokens?beta=true&lt;/code&gt;, đây là cách các build Claude Code gần đây thực sự gọi API.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Luồng proxy Claude giờ hoạt động như &lt;code&gt;free-claude-code&lt;/code&gt; ở lớp routing&lt;/strong&gt; — id mô hình Claude fake vẫn map proxy-side sang backend free đã chọn, nhưng route matcher không còn break trước khi mapping chạy.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fix được validate với binary &lt;code&gt;claude&lt;/code&gt; thực&lt;/strong&gt; — không chỉ unit tests. Lỗi &lt;code&gt;selected model (claude-sonnet-4-6) may not exist&lt;/code&gt; chính xác giờ đã biến mất trong local end-to-end repro.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;🚀 Sử dụng&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Chỉ chạy nó — bắt đầu ở chế độ OpenCode CLI, prompt API key nếu chưa đặt
free-coding-models

# Rõ ràng target OpenCode CLI (TUI + Enter launch OpenCode CLI)
free-coding-models --opencode

# Rõ ràng target OpenCode Desktop (TUI + Enter đặt mô hình &amp;#x26; mở Desktop app)
free-coding-models --opencode-desktop

# Rõ ràng target OpenClaw (TUI + Enter đặt mô hình làm mặc định trong OpenClaw)
free-coding-models --openclaw

# Launch các công cụ public được hỗ trợ khác với mô hình đã chọn
free-coding-models --crush
free-coding-models --goose

# Chỉ hiển thị mô hình top-tier (A+, S, S+)
free-coding-models --best

# Phân tích trong 10 giây và xuất mô hình đáng tin cậy nhất
free-coding-models --fiable

# Xuất kết quả dưới dạng JSON (cho scripting/automation)
free-coding-models --json
free-coding-models --tier S --json | jq &apos;.[0].modelId&apos;  # Lấy model ID nhanh nhất S-tier
free-coding-models --json | jq &apos;.[] | select(.avgPing &amp;#x3C; 500)&apos;  # Lọc theo độ trễ

# In toàn bộ help CLI với mọi flag được hỗ trợ và lệnh daemon
free-coding-models --help

# Lọc mô hình theo chữ tier
free-coding-models --tier S          # Chỉ S+ và S
free-coding-models --tier A          # Chỉ A+, A, A-
free-coding-models --tier B          # Chỉ B+, B
free-coding-models --tier C          # Chỉ C

# Kết hợp flag tự do
free-coding-models --openclaw --tier S
free-coding-models --opencode --best
free-coding-models --tier S --json
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;AI E2E workflow (&lt;code&gt;/testfcm&lt;/code&gt;)&lt;/h3&gt;
&lt;p&gt;Để validate level repo, dự án này giờ ship một flow test manual AI-driven lặp lại:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ưu tiên: &lt;code&gt;pnpm test:fcm -- --{&quot;tool&quot;} crush&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Fallback khi &lt;code&gt;pnpm&lt;/code&gt; không khả dụng: &lt;code&gt;npm run test:fcm -- --{&quot;tool&quot;} crush&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Kiểm tra plumbing mock: &lt;code&gt;pnpm test:fcm:mock&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nó làm gì:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Copy &lt;code&gt;~/.free-coding-models.json&lt;/code&gt; hiện tại của bạn vào HOME isolated&lt;/li&gt;
&lt;li&gt;Chạy preflight &lt;code&gt;--json&lt;/code&gt; để bắt regression khởi động rõ ràng&lt;/li&gt;
&lt;li&gt;Bắt đầu TUI thực trong PTY qua lệnh &lt;code&gt;expect&lt;/code&gt; hệ thống&lt;/li&gt;
&lt;li&gt;Nhấn &lt;code&gt;Enter&lt;/code&gt; như user để launch công cụ đã chọn&lt;/li&gt;
&lt;li&gt;Gửi &lt;code&gt;hi&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Capture response, &lt;code&gt;request-log.jsonl&lt;/code&gt;, daemon logs, và tool config được tạo&lt;/li&gt;
&lt;li&gt;Viết báo cáo Markdown vào &lt;code&gt;task/reports/&lt;/code&gt; và artifacts raw vào &lt;code&gt;task/artifacts/&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Flow lệnh được document trong &lt;a href=&quot;task/TESTFCM-WORKFLOW.md&quot;&gt;task/TESTFCM-WORKFLOW.md&lt;/a&gt;. Slash commands project-local cũng được include tại &lt;a href=&quot;.claude/commands/testfcm.md&quot;&gt;.claude/commands/testfcm.md&lt;/a&gt; và &lt;a href=&quot;.crush/commands/testfcm.md&quot;&gt;.crush/commands/testfcm.md&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Chọn công cụ target&lt;/h3&gt;
&lt;p&gt;Chạy &lt;code&gt;free-coding-models&lt;/code&gt; không có flag launcher bắt đầu ở chế độ &lt;strong&gt;OpenCode CLI&lt;/strong&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Nhấn &lt;strong&gt;&lt;code&gt;Z&lt;/code&gt;&lt;/strong&gt; trong TUI để cycle public launch targets: &lt;code&gt;OpenCode CLI&lt;/code&gt; → &lt;code&gt;OpenCode Desktop&lt;/code&gt; → &lt;code&gt;OpenClaw&lt;/code&gt; → &lt;code&gt;Crush&lt;/code&gt; → &lt;code&gt;Goose&lt;/code&gt; → &lt;code&gt;Pi&lt;/code&gt; → &lt;code&gt;Aider&lt;/code&gt; → &lt;code&gt;Claude Code&lt;/code&gt; → &lt;code&gt;Codex&lt;/code&gt; → &lt;code&gt;Gemini&lt;/code&gt; → &lt;code&gt;Qwen&lt;/code&gt; → &lt;code&gt;OpenHands&lt;/code&gt; → &lt;code&gt;Amp&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Hoặc bắt đầu trực tiếp ở chế độ target với flag CLI như &lt;code&gt;--opencode-desktop&lt;/code&gt;, &lt;code&gt;--openclaw&lt;/code&gt;, &lt;code&gt;--crush&lt;/code&gt;, &lt;code&gt;--goose&lt;/code&gt;, &lt;code&gt;--pi&lt;/code&gt;, &lt;code&gt;--aider&lt;/code&gt;, &lt;code&gt;--claude-code&lt;/code&gt;, &lt;code&gt;--codex&lt;/code&gt;, &lt;code&gt;--gemini&lt;/code&gt;, &lt;code&gt;--qwen&lt;/code&gt;, &lt;code&gt;--openhands&lt;/code&gt;, hoặc &lt;code&gt;--amp&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Target active luôn hiển thị trong header badge trước khi bạn nhấn &lt;code&gt;Enter&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Cách hoạt động:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Giai đoạn ping&lt;/strong&gt; — Tất cả mô hình được bật được ping song song (lên đến 160 across 20 nhà cung cấp)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Giám sát liên tục&lt;/strong&gt; — Mô hình bắt đầu với re-ping 2s trong 60s, sau đó fallback 10s tự động, và chậm 30s sau 5 phút idle trừ khi bạn force chế độ 4s với &lt;code&gt;W&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cập nhật thời gian thực&lt;/strong&gt; — Xem cột &quot;Latest&quot;, &quot;Avg&quot;, và &quot;Up%&quot; cập nhật trực tiếp&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chọn bất cứ lúc nào&lt;/strong&gt; — Dùng ↑↓ mũi tên để di chuyển, nhấn Enter trên mô hình để hành động&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Phát hiện thông minh&lt;/strong&gt; — Tự động phát hiện nếu NVIDIA NIM được cấu hình trong OpenCode hoặc OpenClaw&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Setup wizard (lần chạy đầu — walkthrough tất cả 20 nhà cung cấp):&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;  🔑 Setup lần đầu — API keys
  Nhập keys cho bất kỳ nhà cung cấp nào bạn muốn sử dụng. Nhấn Enter để bỏ qua.

  ● NVIDIA NIM
    Free key tại: https://build.nvidia.com
    Profile → API Keys → Generate
  Nhập key (hoặc Enter để bỏ qua): nvapi-xxxx

  ● Groq
    Free key tại: https://console.groq.com/keys
    API Keys → Create API Key
  Nhập key (hoặc Enter để bỏ qua): gsk_xxxx

  ● Cerebras
    Free key tại: https://cloud.cerebras.ai
    API Keys → Create
  Nhập key (hoặc Enter để bỏ qua):

  ● SambaNova
    Free key tại: https://cloud.sambanova.ai/apis
    API Keys → Create ($5 dùng thử miễn phí, 3 tháng)
  Nhập key (hoặc Enter để bỏ qua):

  ✅ 2 key(s) đã lưu vào ~/.free-coding-models.json
  Bạn có thể thêm hoặc thay đổi keys bất cứ lúc nào với phím P trong TUI.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bạn không cần tất cả 20 nhà cung cấp — bỏ qua bất kỳ nhà cung cấp nào bằng cách nhấn Enter. Ít nhất một key là bắt buộc.&lt;/p&gt;
&lt;h3&gt;Thêm hoặc thay đổi keys sau&lt;/h3&gt;
&lt;p&gt;Nhấn &lt;strong&gt;&lt;code&gt;P&lt;/code&gt;&lt;/strong&gt; để mở màn hình Settings bất cứ lúc nào:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  ⚙  Settings

  Providers

  ❯ [ ✅ ] NVIDIA NIM              nvapi-••••••••••••3f9a  [Test ✅]  Free tier (provider quota theo mô hình)
    [ ✅ ] OpenRouter              (no key set)            [Test —]   Free trên :free (50/ngày &amp;#x3C;$10, 1000/ngày ≥$10)
    [ ✅ ] Hugging Face Inference  (no key set)            [Test —]   Credits miễn phí hàng tháng (~$0.10)

  Setup Instructions — NVIDIA NIM
  1) Tạo tài khoản NVIDIA NIM: https://build.nvidia.com
  2) Profile → API Keys → Generate
  3) Nhấn T để test key của bạn

  ↑↓ Navigate  •  Enter Edit/Run  •  + Add key  •  - Remove key  •  Space Toggle  •  T Test key  •  S Sync→OpenCode  •  R Restore backup  •  U Updates  •  ⌫ Delete profile  •  Esc Close
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;↑↓&lt;/strong&gt; — di chuyển nhà cung cấp&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enter&lt;/strong&gt; — chỉnh sửa key đã chọn, chạy maintenance actions, hoặc load profile đã chọn&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;+ / -&lt;/strong&gt; — thêm key khác cho nhà cung cấp đã chọn hoặc xóa một key&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Space&lt;/strong&gt; — toggle nhà cung cấp enabled/disabled&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;T&lt;/strong&gt; — fire real test ping để verify key hoạt động (hiển thị ✅/❌)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;S&lt;/strong&gt; — sync &lt;code&gt;fcm-proxy&lt;/code&gt; vào OpenCode khi proxy mode + persistence được bật&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;R&lt;/strong&gt; — restore backup OpenCode cuối cùng được tạo bởi sync/cleanup flows&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;U&lt;/strong&gt; — manually check npm cho version mới hơn&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Backspace&lt;/strong&gt; — xóa saved profile đã chọn&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Esc&lt;/strong&gt; — đóng settings và reload danh sách mô hình&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Keys được lưu vào &lt;code&gt;~/.free-coding-models.json&lt;/code&gt; (permissions &lt;code&gt;0600&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Update manual ở cùng màn hình Settings (&lt;code&gt;P&lt;/code&gt;) dưới &lt;strong&gt;Maintenance&lt;/strong&gt; (Enter để check, Enter lần nữa để install khi update khả dụng).
Khi npm release mới hơn được biết, footer chính cũng thêm warning line đỏ full-width với lệnh recovery manual &lt;code&gt;npm install -g free-coding-models@latest&lt;/code&gt;.
Favorites cũng được persist trong cùng file config và tồn tại qua restart, app relaunches, và package updates.
Hàng favorites stays pinned ở trên cùng và vẫn hiển thị ngay cả khi chế độ &lt;code&gt;Configured Only&lt;/code&gt; được bật.
Bảng chính giờ bắt đầu ở chế độ &lt;code&gt;Configured Only&lt;/code&gt;, vì vậy nếu chưa có gì được setup bạn có thể nhấn &lt;code&gt;P&lt;/code&gt; và thêm API key đầu tiên ngay lập tức.&lt;/p&gt;
&lt;h3&gt;Environment variable overrides&lt;/h3&gt;
&lt;p&gt;Env vars luôn ưu tiên hơn file config:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;NVIDIA_API_KEY=nvapi-xxx free-coding-models
GROQ_API_KEY=gsk_xxx free-coding-models
CEREBRAS_API_KEY=csk_xxx free-coding-models
OPENROUTER_API_KEY=sk-or-xxx free-coding-models
HUGGINGFACE_API_KEY=hf_xxx free-coding-models
REPLICATE_API_TOKEN=r8_xxx free-coding-models
DEEPINFRA_API_KEY=di_xxx free-coding-models
FIREWORKS_API_KEY=fw_xxx free-coding-models
SILICONFLOW_API_KEY=sk_xxx free-coding-models
TOGETHER_API_KEY=together_xxx free-coding-models
CLOUDFLARE_API_TOKEN=cf_xxx CLOUDFLARE_ACCOUNT_ID=your_account_id free-coding-models
PERPLEXITY_API_KEY=pplx_xxx free-coding-models
ZAI_API_KEY=zai-xxx free-coding-models
DASHSCOPE_API_KEY=sk-xxx free-coding-models
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Lấy API keys miễn phí của bạn&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;NVIDIA NIM&lt;/strong&gt; (44 mô hình, S+ → C tier):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Đăng ký tại &lt;a href=&quot;https://build.nvidia.com&quot;&gt;build.nvidia.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Đi đến Profile → API Keys → Generate API Key&lt;/li&gt;
&lt;li&gt;Đặt tên (ví dụ: &quot;free-coding-models&quot;), đặt expiry thành &quot;Never&quot;&lt;/li&gt;
&lt;li&gt;Copy — chỉ hiển thị một lần!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Groq&lt;/strong&gt; (6 mô hình, inference nhanh):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Đăng ký tại &lt;a href=&quot;https://console.groq.com&quot;&gt;console.groq.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Đi đến API Keys → Create API Key&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Cerebras&lt;/strong&gt; (3 mô hình, silicon ultra-nhanh):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Đăng ký tại &lt;a href=&quot;https://cloud.cerebras.ai&quot;&gt;cloud.cerebras.ai&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Đi đến API Keys → Create&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;OpenRouter&lt;/strong&gt; (mô hình &lt;code&gt;:free&lt;/code&gt;):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Đăng ký tại &lt;a href=&quot;https://openrouter.ai/keys&quot;&gt;openrouter.ai/keys&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Tạo API key (&lt;code&gt;sk-or-...&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Hugging Face Inference&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Đăng ký tại &lt;a href=&quot;https://huggingface.co/settings/tokens&quot;&gt;huggingface.co/settings/tokens&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Tạo Access Token (&lt;code&gt;hf_...&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Replicate&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Đăng ký tại &lt;a href=&quot;https://replicate.com/account/api-tokens&quot;&gt;replicate.com/account/api-tokens&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Tạo API token (&lt;code&gt;r8_...&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;DeepInfra&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Đăng ký tại &lt;a href=&quot;https://deepinfra.com/login&quot;&gt;deepinfra.com/login&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Tạo API key từ account dashboard của bạn&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Fireworks AI&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Đăng ký tại &lt;a href=&quot;https://fireworks.ai&quot;&gt;fireworks.ai&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Mở Settings → Access Tokens và tạo token&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Mistral Codestral&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Đăng ký tại &lt;a href=&quot;https://codestral.mistral.ai&quot;&gt;codestral.mistral.ai&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Đi đến API Keys → Create&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Hyperbolic&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Đăng ký tại &lt;a href=&quot;https://app.hyperbolic.ai/settings&quot;&gt;app.hyperbolic.ai/settings&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Tạo API key trong Settings&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Scaleway&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Đăng ký tại &lt;a href=&quot;https://console.scaleway.com/iam/api-keys&quot;&gt;console.scaleway.com/iam/api-keys&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Đi đến IAM → API Keys&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Google AI Studio&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Đăng ký tại &lt;a href=&quot;https://aistudio.google.com/apikey&quot;&gt;aistudio.google.com/apikey&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Tạo API key cho endpoints Gemini/Gemma&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;SiliconFlow&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Đăng ký tại &lt;a href=&quot;https://cloud.siliconflow.cn/account/ak&quot;&gt;cloud.siliconflow.cn/account/ak&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Tạo API key trong Account → API Keys&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Together AI&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Đăng ký tại &lt;a href=&quot;https://api.together.ai/settings/api-keys&quot;&gt;api.together.ai/settings/api-keys&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Tạo API key trong Settings&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Cloudflare Workers AI&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Đăng ký tại &lt;a href=&quot;https://dash.cloudflare.com&quot;&gt;dash.cloudflare.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Tạo API token với permissions Workers AI&lt;/li&gt;
&lt;li&gt;Export cả &lt;code&gt;CLOUDFLARE_API_TOKEN&lt;/code&gt; và &lt;code&gt;CLOUDFLARE_ACCOUNT_ID&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Perplexity API&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Đăng ký tại &lt;a href=&quot;https://www.perplexity.ai/settings/api&quot;&gt;perplexity.ai/settings/api&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Tạo API key (&lt;code&gt;PERPLEXITY_API_KEY&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Alibaba Cloud (DashScope)&lt;/strong&gt; (8 mô hình, Qwen3-Coder family):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Đăng ký tại &lt;a href=&quot;https://modelstudio.console.alibabacloud.com&quot;&gt;modelstudio.console.alibabacloud.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Kích hoạt Model Studio (1M tokens miễn phí mỗi mô hình, region Singapore, 90 ngày)&lt;/li&gt;
&lt;li&gt;Tạo API key (&lt;code&gt;DASHSCOPE_API_KEY&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;ZAI&lt;/strong&gt; (5 mô hình, GLM family):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Đăng ký tại &lt;a href=&quot;https://z.ai&quot;&gt;z.ai&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Đăng ký Coding Plan&lt;/li&gt;
&lt;li&gt;Lấy API key từ dashboard&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Free tiers&lt;/strong&gt; — mỗi nhà cung cấp expose dev/free tier với quota riêng. ZAI yêu cầu Coding Plan subscription.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2&gt;🤖 Mô hình Coding&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;160 mô hình coding&lt;/strong&gt; across 20 nhà cung cấp và 8 tiers, xếp hạng theo &lt;a href=&quot;https://www.swebench.com&quot;&gt;SWE-bench Verified&lt;/a&gt; — industry-standard benchmark đo lường GitHub issue resolution thực tế. Scores được self-reported bởi nhà cung cấp trừ khi được ghi chú.&lt;/p&gt;
&lt;h3&gt;Alibaba Cloud (DashScope) (8 mô hình)&lt;/h3&gt;
&lt;p&gt;| Tier | SWE-bench | Mô hình |
|------|-----------|-------|
| &lt;strong&gt;S+&lt;/strong&gt; ≥70% | Qwen3 Coder Plus (69.6%), Qwen3 Coder 480B (70.6%) |
| &lt;strong&gt;S&lt;/strong&gt; 60–70% | Qwen3 Coder Max (67.0%), Qwen3 Coder Next (65.0%), Qwen3 235B (70.0%), Qwen3 80B Instruct (65.0%) |
| &lt;strong&gt;A+&lt;/strong&gt; 50–60% | Qwen3 32B (50.0%) |
| &lt;strong&gt;A&lt;/strong&gt; 40–50% | Qwen2.5 Coder 32B (46.0%) |&lt;/p&gt;
&lt;h3&gt;ZAI Coding Plan (5 mô hình)&lt;/h3&gt;
&lt;p&gt;| Tier | SWE-bench | Mô hình |
|------|-----------|-------|
| &lt;strong&gt;S+&lt;/strong&gt; ≥70% | GLM-5 (77.8%), GLM-4.5 (75.0%), GLM-4.7 (73.8%), GLM-4.5-Air (72.0%), GLM-4.6 (70.0%) |&lt;/p&gt;
&lt;h3&gt;NVIDIA NIM (44 mô hình)&lt;/h3&gt;
&lt;p&gt;| Tier | SWE-bench | Mô hình |
|------|-----------|--------|
| &lt;strong&gt;S+&lt;/strong&gt; ≥70% | GLM 5 (77.8%), Kimi K2.5 (76.8%), Step 3.5 Flash (74.4%), MiniMax M2.1 (74.0%), GLM 4.7 (73.8%), DeepSeek V3.2 (73.1%), Devstral 2 (72.2%), Kimi K2 Thinking (71.3%), Qwen3 Coder 480B (70.6%), Qwen3 235B (70.0%) |
| &lt;strong&gt;S&lt;/strong&gt; 60–70% | MiniMax M2 (69.4%), DeepSeek V3.1 Terminus (68.4%), Qwen3 80B Thinking (68.0%), Qwen3.5 400B (68.0%), Kimi K2 Instruct (65.8%), Qwen3 80B Instruct (65.0%), DeepSeek V3.1 (62.0%), Llama 4 Maverick (62.0%), GPT OSS 120B (60.0%) |
| &lt;strong&gt;A+&lt;/strong&gt; 50–60% | Mistral Large 675B (58.0%), Nemotron Ultra 253B (56.0%), Colosseum 355B (52.0%), QwQ 32B (50.0%) |
| &lt;strong&gt;A&lt;/strong&gt; 40–50% | Nemotron Super 49B (49.0%), Mistral Medium 3 (48.0%), Qwen2.5 Coder 32B (46.0%), Magistral Small (45.0%), Llama 4 Scout (44.0%), Llama 3.1 405B (44.0%), Nemotron Nano 30B (43.0%), R1 Distill 32B (43.9%), GPT OSS 20B (42.0%) |
| &lt;strong&gt;A-&lt;/strong&gt; 35–40% | Llama 3.3 70B (39.5%), Seed OSS 36B (38.0%), R1 Distill 14B (37.7%), Stockmark 100B (36.0%) |
| &lt;strong&gt;B+&lt;/strong&gt; 30–35% | Ministral 14B (34.0%), Mixtral 8x22B (32.0%), Granite 34B Code (30.0%) |
| &lt;strong&gt;B&lt;/strong&gt; 20–30% | R1 Distill 8B (28.2%), R1 Distill 7B (22.6%) |
| &lt;strong&gt;C&lt;/strong&gt; {&apos;&amp;#x3C;&apos;}20% | Gemma 2 9B (18.0%), Phi 4 Mini (14.0%), Phi 3.5 Mini (12.0%) |&lt;/p&gt;
&lt;h3&gt;Groq (10 mô hình)&lt;/h3&gt;
&lt;p&gt;| Tier | SWE-bench | Mô hình |
|------|-----------|-------|
| &lt;strong&gt;S&lt;/strong&gt; 60–70% | Kimi K2 Instruct (65.8%), Llama 4 Maverick (62.0%) |
| &lt;strong&gt;A+&lt;/strong&gt; 50–60% | QwQ 32B (50.0%) |
| &lt;strong&gt;A&lt;/strong&gt; 40–50% | Llama 4 Scout (44.0%), R1 Distill 70B (43.9%) |
| &lt;strong&gt;A-&lt;/strong&gt; 35–40% | Llama 3.3 70B (39.5%) |&lt;/p&gt;
&lt;h3&gt;Cerebras (7 mô hình)&lt;/h3&gt;
&lt;p&gt;| Tier | SWE-bench | Mô hình |
|------|-----------|-------|
| &lt;strong&gt;A+&lt;/strong&gt; 50–60% | Qwen3 32B (50.0%) |
| &lt;strong&gt;A&lt;/strong&gt; 40–50% | Llama 4 Scout (44.0%) |
| &lt;strong&gt;A-&lt;/strong&gt; 35–40% | Llama 3.3 70B (39.5%) |&lt;/p&gt;
&lt;h3&gt;Thang tier&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;S+/S&lt;/strong&gt; — Elite frontier coders (≥60% SWE-bench), tốt nhất cho complex real-world tasks và refactors&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A+/A&lt;/strong&gt; — Alternatives tuyệt vời, mạnh ở hầu hết coding tasks&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A-/B+&lt;/strong&gt; — Performer solid, tốt cho targeted programming tasks&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;B/C&lt;/strong&gt; — Mô hình lightweight hoặc cũ hơn, tốt cho code completion trên constrained infra&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Lọc theo tier&lt;/h3&gt;
&lt;p&gt;Dùng &lt;code&gt;--tier&lt;/code&gt; để tập trung vào capability band cụ thể:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;free-coding-models --tier S     # Chỉ S+ và S (frontier models)
free-coding-models --tier A     # Chỉ A+, A, A- (solid performers)
free-coding-models --tier B     # Chỉ B+, B (lightweight options)
free-coding-models --tier C     # Chỉ C (edge/minimal models)
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;📊 Cột TUI&lt;/h2&gt;
&lt;p&gt;Bảng chính hiển thị một hàng mỗi mô hình với các cột sau:&lt;/p&gt;
&lt;p&gt;| Cột | Sort key | Mô tả |
|--------|----------|-------------|
| &lt;strong&gt;Rank&lt;/strong&gt; | &lt;code&gt;R&lt;/code&gt; | Vị trí dựa trên thứ tự sort hiện tại (huy chương cho top 3: 🥇🥈🥉) |
| &lt;strong&gt;Tier&lt;/strong&gt; | — | SWE-bench tier (S+, S, A+, A, A-, B+, B, C) |
| &lt;strong&gt;SWE%&lt;/strong&gt; | &lt;code&gt;S&lt;/code&gt; | SWE-bench Verified score — industry-standard cho coding |
| &lt;strong&gt;CTX&lt;/strong&gt; | &lt;code&gt;C&lt;/code&gt; | Kích thước context window (ví dụ: &lt;code&gt;128k&lt;/code&gt;) |
| &lt;strong&gt;Model&lt;/strong&gt; | &lt;code&gt;M&lt;/code&gt; | Tên hiển thị mô hình (favorites hiển thị ⭐ prefix) |
| &lt;strong&gt;Provider&lt;/strong&gt; | &lt;code&gt;O&lt;/code&gt; | Tên nhà cung cấp (NIM, Groq, v.v.) — nhấn &lt;code&gt;D&lt;/code&gt; để cycle provider filter |
| &lt;strong&gt;Latest Ping&lt;/strong&gt; | &lt;code&gt;L&lt;/code&gt; | Round-trip latency gần nhất bằng milliseconds |
| &lt;strong&gt;Avg Ping&lt;/strong&gt; | &lt;code&gt;A&lt;/code&gt; | Trung bình cuộn của TẤT CẢ ping thành công từ khi launch |
| &lt;strong&gt;Health&lt;/strong&gt; | &lt;code&gt;H&lt;/code&gt; | Trạng thái hiện tại: UP ✅, NO KEY 🔑, Timeout ⏳, Overloaded 🔥, Not Found 🚫 |
| &lt;strong&gt;Verdict&lt;/strong&gt; | &lt;code&gt;V&lt;/code&gt; | Health verdict dựa trên avg latency + stability analysis |
| &lt;strong&gt;Stability&lt;/strong&gt; | &lt;code&gt;B&lt;/code&gt; | Điểm consistency composite 0–100 (xem &lt;a href=&quot;#-%C4%91i%E1%BB%83m-%E1%BB%95n-%C4%91%E1%BB%8Bnh&quot;&gt;Stability Score&lt;/a&gt;) |
| &lt;strong&gt;Up%&lt;/strong&gt; | &lt;code&gt;U&lt;/code&gt; | Uptime — tỷ lệ phần trăm ping thành công |
| &lt;strong&gt;Used&lt;/strong&gt; | — | Tổng token prompt+completion đã tiêu thụ trong logs cho cặp nhà cung cấp/mô hình chính xác này, hiển thị bằng &lt;code&gt;k&lt;/code&gt; hoặc &lt;code&gt;M&lt;/code&gt; |&lt;/p&gt;
&lt;h3&gt;Giá trị Verdict&lt;/h3&gt;
&lt;p&gt;Cột Verdict kết hợp avg latency với stability analysis:&lt;/p&gt;
&lt;p&gt;| Verdict | Ý nghĩa |
|---------|---------|
| &lt;strong&gt;Perfect&lt;/strong&gt; | Avg &amp;#x3C; 400ms với p95/jitter ổn định |
| &lt;strong&gt;Normal&lt;/strong&gt; | Avg &amp;#x3C; 1000ms, responses nhất quán |
| &lt;strong&gt;Slow&lt;/strong&gt; | Avg 1000–2000ms |
| &lt;strong&gt;Spiky&lt;/strong&gt; | Avg tốt nhưng tail latency thất thường (p95 &gt;&gt; avg) |
| &lt;strong&gt;Very Slow&lt;/strong&gt; | Avg 2000–5000ms |
| &lt;strong&gt;Overloaded&lt;/strong&gt; | Server trả về 429/503 (rate limited hoặc capacity hit) |
| &lt;strong&gt;Unstable&lt;/strong&gt; | Trước đó up nhưng giờ timeout, hoặc avg &gt; 5000ms |
| &lt;strong&gt;Not Active&lt;/strong&gt; | Chưa có ping thành công |
| &lt;strong&gt;Pending&lt;/strong&gt; | Ping đầu tiên vẫn đang bay |&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;📐 Điểm Ổn Định&lt;/h2&gt;
&lt;p&gt;Cột &lt;strong&gt;Stability&lt;/strong&gt; (sort với phím &lt;code&gt;B&lt;/code&gt;) hiển thị điểm composite 0–100 trả lời: &lt;em&gt;&quot;Mô hình này nhất quán và dự đoán được như thế nào?&quot;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Avg latency một mình gây hiểu lầm — một mô hình avg 250ms mà ngẫu nhiên spike lên 6 giây &lt;em&gt;cảm giác&lt;/em&gt; chậm hơn trong thực tế so với mô hình 400ms ổn định. Điểm stability capture điều này.&lt;/p&gt;
&lt;h3&gt;Công thức&lt;/h3&gt;
&lt;p&gt;Bốn signals được normalize thành 0–100 mỗi cái, sau đó kết hợp với weights:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Stability = 0.30 × p95_score
          + 0.30 × jitter_score
          + 0.20 × spike_score
          + 0.20 × reliability_score
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;| Component | Weight | Đo lường gì | Cách normalize |
|-----------|--------|-------------|----------------|
| &lt;strong&gt;p95 latency&lt;/strong&gt; | 30% | Tail-latency spikes — 5% tệ nhất của response times | &lt;code&gt;100 × (1 - p95 / 5000)&lt;/code&gt;, clamped thành 0–100 |
| &lt;strong&gt;Jitter (σ)&lt;/strong&gt; | 30% | Response times thất thường — độ lệch chuẩn của ping times | &lt;code&gt;100 × (1 - jitter / 2000)&lt;/code&gt;, clamped thành 0–100 |
| &lt;strong&gt;Spike rate&lt;/strong&gt; | 20% | Fraction của pings trên 3000ms | &lt;code&gt;100 × (1 - spikes / total_pings)&lt;/code&gt; |
| &lt;strong&gt;Reliability&lt;/strong&gt; | 20% | Uptime — fraction của ping HTTP 200 thành công | Trực tiếp phần trăm uptime (0–100) |&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;📡 FCM Proxy V2&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;free-coding-models&lt;/code&gt; include một reverse proxy local merge tất cả API key nhà cung cấp của bạn vào một endpoint. Chế độ background service tùy chọn giữ nó chạy 24/7 — ngay cả không có TUI.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tắt mặc định&lt;/strong&gt; — bật trong Settings (&lt;code&gt;P&lt;/code&gt;) → Cài đặt FCM Proxy V2.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Proxy làm gì&lt;/h3&gt;
&lt;p&gt;| Tính năng | Mô tả |
|---------|-------------|
| &lt;strong&gt;Unified endpoint&lt;/strong&gt; | Một URL (&lt;code&gt;http://127.0.0.1:18045/v1&lt;/code&gt;) thay thế 20+ endpoints nhà cung cấp |
| &lt;strong&gt;Key rotation&lt;/strong&gt; | Tự động swap sang API key tiếp theo khi một key hit rate limits (429) |
| &lt;strong&gt;Usage tracking&lt;/strong&gt; | Theo dõi token consumption cho mỗi cặp nhà cung cấp/mô hình thời gian thực |
| &lt;strong&gt;Anthropic translation&lt;/strong&gt; | Claude Code gửi &lt;code&gt;POST /v1/messages&lt;/code&gt; — proxy dịch sang định dạng OpenAI upstream |
| &lt;strong&gt;Path normalization&lt;/strong&gt; | Chuyển đổi API paths không chuẩn (ZAI, Cloudflare) thành calls &lt;code&gt;/v1/&lt;/code&gt; chuẩn |&lt;/p&gt;
&lt;h3&gt;Chế độ In-process vs Background Service&lt;/h3&gt;
&lt;p&gt;| | In-process (mặc định) | Background Service (always-on) |
|---|---|---|
| &lt;strong&gt;Lifetime&lt;/strong&gt; | Bắt đầu/dừng với TUI | Tồn tại qua reboots |
| &lt;strong&gt;Use case&lt;/strong&gt; | Sessions nhanh | Truy cập 24/7 từ bất kỳ tool nào |
| &lt;strong&gt;Setup&lt;/strong&gt; | Toggle trong Settings | Cài đặt one-time qua TUI hoặc CLI |
| &lt;strong&gt;Port&lt;/strong&gt; | Ngẫu nhiên hoặc cấu hình | Ổn định (&lt;code&gt;18045&lt;/code&gt; mặc định) |
| &lt;strong&gt;Token&lt;/strong&gt; | Mới mỗi session | Bền vững (env files ở lại valid) |&lt;/p&gt;
&lt;h3&gt;Setup nhanh&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Qua TUI (khuyến nghị):&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Nhấn &lt;code&gt;P&lt;/code&gt; để mở Settings&lt;/li&gt;
&lt;li&gt;Chọn &lt;strong&gt;FCM Proxy V2 settings →&lt;/strong&gt; và nhấn Enter&lt;/li&gt;
&lt;li&gt;Bật &lt;strong&gt;Proxy mode&lt;/strong&gt;, sau đó chọn &lt;strong&gt;Install background service&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Qua CLI:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;free-coding-models daemon install     # Cài đặt + start như OS service
free-coding-models daemon status      # Kiểm tra trạng thái running
free-coding-models daemon restart     # Restart sau thay đổi config
free-coding-models daemon stop        # Dừng graceful (SIGTERM)
free-coding-models daemon uninstall   # Xóa OS service hoàn toàn
free-coding-models daemon logs        # Hiển thị service logs gần đây
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Để sanity-check trình duyệt nhanh, mở &lt;a href=&quot;http://127.0.0.1:18045/&quot;&gt;http://127.0.0.1:18045/&lt;/a&gt; hoặc &lt;a href=&quot;http://127.0.0.1:18045/v1/health&quot;&gt;http://127.0.0.1:18045/v1/health&lt;/a&gt; trong khi proxy đang chạy.&lt;/p&gt;
&lt;h3&gt;Quản lý service&lt;/h3&gt;
&lt;p&gt;Overlay &lt;strong&gt;FCM Proxy V2&lt;/strong&gt; chuyên dụng (truy cập qua &lt;code&gt;J&lt;/code&gt; từ TUI chính, hoặc Settings → Enter) cung cấp điều khiển đầy đủ:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Gợi ý công cụ hiện tại&lt;/strong&gt; — Hiển thị công cụ được chọn Z nào sẽ nhận proxy config persisted (khi chế độ đó hỗ trợ)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Toggle auto-sync&lt;/strong&gt; — Tự động viết provider &lt;code&gt;fcm-proxy&lt;/code&gt; vào config công cụ hiện tại khi proxy bắt đầu&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cleanup&lt;/strong&gt; — Xóa entries &lt;code&gt;fcm-proxy&lt;/code&gt; khỏi config công cụ hiện tại&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hiển thị trạng thái&lt;/strong&gt; — Running/Stopped/Stale/Unhealthy với PID, port, uptime, số lượng account/mô hình&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Phát hiện version mismatch&lt;/strong&gt; — cảnh báo nếu version service khác với version FCM đã cài đặt&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Restart&lt;/strong&gt; — stop + start qua OS service manager&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stop&lt;/strong&gt; — SIGTERM graceful (service có thể tự restart nếu đã cài đặt)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Force kill&lt;/strong&gt; — SIGKILL emergency cho processes stuck&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Xem logs&lt;/strong&gt; — 50 dòng cuối từ &lt;code&gt;~/.free-coding-models/daemon-stdout.log&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Hỗ trợ nền tảng&lt;/h3&gt;
&lt;p&gt;| Nền tảng | Loại service | Đường dẫn config |
|----------|-------------|-------------|
| macOS | &lt;code&gt;launchd&lt;/code&gt; LaunchAgent | &lt;code&gt;~/Library/LaunchAgents/com.fcm.proxy.plist&lt;/code&gt; |
| Linux | &lt;code&gt;systemd&lt;/code&gt; user service | &lt;code&gt;~/.config/systemd/user/fcm-proxy.service&lt;/code&gt; |
| Windows | Không hỗ trợ | Fallback sang proxy in-process |&lt;/p&gt;
&lt;h3&gt;Files config&lt;/h3&gt;
&lt;p&gt;| File | Mục đích |
|------|---------|
| &lt;code&gt;~/.free-coding-models.json&lt;/code&gt; | API keys, cài đặt proxy, service consent |
| &lt;code&gt;~/.free-coding-models/daemon.json&lt;/code&gt; | File trạng thái (PID, port, token) — ghi bởi background service |
| &lt;code&gt;~/.free-coding-models/daemon-stdout.log&lt;/code&gt; | Log output service |&lt;/p&gt;
&lt;p&gt;Trường &lt;code&gt;proxy.activeTool&lt;/code&gt; giờ chỉ legacy-only. FCM Proxy V2 tuân theo công cụ &lt;strong&gt;được chọn Z&lt;/strong&gt; hiện tại tự động bất cứ khi nào chế độ đó hỗ trợ proxy sync persisted.&lt;/p&gt;
&lt;h3&gt;Cleanup&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Từ overlay FCM Proxy V2: &lt;strong&gt;Clean &lt;code&gt;{tool}&lt;/code&gt; proxy config&lt;/strong&gt; — xóa entries &lt;code&gt;fcm-proxy&lt;/code&gt; khỏi công cụ hiện tại được chọn&lt;/li&gt;
&lt;li&gt;Hoặc: &lt;code&gt;free-coding-models --clean-proxy&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;An toàn&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Dev guard&lt;/strong&gt;: &lt;code&gt;installDaemon()&lt;/code&gt; bị chặn khi chạy từ git checkout — ngăn hardcoding local repo paths trong OS service files&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chỉ localhost&lt;/strong&gt;: Proxy listen trên &lt;code&gt;127.0.0.1&lt;/code&gt;, không bao giờ expose ra network&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Yêu cầu consent&lt;/strong&gt;: Cài đặt service yêu cầu user action rõ ràng — không bao giờ tự động cài đặt&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hot-reload&lt;/strong&gt;: Thay đổi config được pick up tự động không cần restart service&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;📜 Request Log Overlay&lt;/h2&gt;
&lt;p&gt;Nhấn &lt;strong&gt;&lt;code&gt;X&lt;/code&gt;&lt;/strong&gt; bất cứ lúc nào để mở dedicated request-log overlay.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Proxy-only accounting&lt;/strong&gt;: Entries được ghi khi requests flow qua multi-account proxy.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Token totals chính xác&lt;/strong&gt;: Overlay aggregate prompt+completion usage cho mỗi request proxied.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hiển thị mỗi request&lt;/strong&gt;: Bạn có thể kiểm tra nhà cung cấp, mô hình, status, token count, và latency cho các requests gần đây.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tái sử dụng bảng khởi động&lt;/strong&gt;: Cột &lt;code&gt;Used&lt;/code&gt; trong bảng chính được derive từ cùng file request log.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Dùng &lt;strong&gt;↑↓&lt;/strong&gt; để scroll và &lt;strong&gt;Esc&lt;/strong&gt; hoặc &lt;strong&gt;X&lt;/strong&gt; để quay lại bảng chính.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;🧰 Supported Tool Launchers&lt;/h2&gt;
&lt;p&gt;Bạn có thể sử dụng &lt;code&gt;free-coding-models&lt;/code&gt; với 12+ AI coding tools. Khi bạn chọn mô hình và nhấn Enter, công cụ tự động cấu hình và pre-select mô hình đã chọn của bạn:&lt;/p&gt;
&lt;p&gt;| Tool | Flag | Auto-Config |
|------|------|------------|
| OpenCode CLI | &lt;code&gt;--opencode&lt;/code&gt; | ~/.config/opencode/opencode.json |
| OpenCode Desktop | &lt;code&gt;--opencode-desktop&lt;/code&gt; | Mở Desktop app |
| OpenClaw | &lt;code&gt;--openclaw&lt;/code&gt; | ~/.openclaw/openclaw.json |
| Crush | &lt;code&gt;--crush&lt;/code&gt; | ~/.config/crush/crush.json |
| Goose | &lt;code&gt;--goose&lt;/code&gt; | ~/.config/goose/config.yaml + custom_providers/ |
| &lt;strong&gt;Aider&lt;/strong&gt; | &lt;code&gt;--aider&lt;/code&gt; | ~/.aider.conf.yml |
| &lt;strong&gt;Claude Code&lt;/strong&gt; ⚡ | &lt;code&gt;--claude-code&lt;/code&gt; | Yêu cầu FCM Proxy V2 |
| &lt;strong&gt;Codex&lt;/strong&gt; ⚡ | &lt;code&gt;--codex&lt;/code&gt; | Yêu cầu FCM Proxy V2 |
| &lt;strong&gt;Gemini&lt;/strong&gt; ⚡ | &lt;code&gt;--gemini&lt;/code&gt; | Yêu cầu FCM Proxy V2 |
| &lt;strong&gt;Qwen&lt;/strong&gt; | &lt;code&gt;--qwen&lt;/code&gt; | ~/.qwen/settings.json |
| &lt;strong&gt;OpenHands&lt;/strong&gt; | &lt;code&gt;--openhands&lt;/code&gt; | LLM_MODEL env var |
| &lt;strong&gt;Amp&lt;/strong&gt; | &lt;code&gt;--amp&lt;/code&gt; | ~/.config/amp/settings.json |
| &lt;strong&gt;Pi&lt;/strong&gt; | &lt;code&gt;--pi&lt;/code&gt; | ~/.pi/agent/settings.json |&lt;/p&gt;
&lt;p&gt;Nhấn &lt;strong&gt;Z&lt;/strong&gt; để cycle qua tất cả 13 chế độ công cụ trong TUI, hoặc dùng flags để bắt đầu ở chế độ ưa thích của bạn.&lt;/p&gt;
&lt;p&gt;⚡ = Yêu cầu FCM Proxy V2 background service (nhấn &lt;code&gt;J&lt;/code&gt; để bật). Các công cụ này không thể kết nối với nhà cung cấp miễn phí mà không có proxy.&lt;/p&gt;
&lt;p&gt;Hỗ trợ công cụ bên ngoài proxy-backed vẫn là beta. Mong đợi các cạnh khởi động/auth đôi khi trong khi CLI contracts của bên thứ ba vẫn đang settle.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Claude Code&lt;/code&gt; được launch với Claude alias thực (&lt;code&gt;--model sonnet&lt;/code&gt;) trong khi proxy map family Claude fake đó trở lại backend FCM đã chọn của bạn, điều này tránh selections local &lt;code&gt;gpt-oss-*&lt;/code&gt; stale breaking trước khi proxy được hit. &lt;code&gt;Codex&lt;/code&gt; được launch qua custom provider config rõ ràng nên nó ở lại API-key mode qua proxy. &lt;code&gt;Gemini&lt;/code&gt; proxy launches được version-gated: các build cũ như &lt;code&gt;0.33.0&lt;/code&gt; bị chặn với diagnostic rõ ràng thay vì bị misconfigured silent.&lt;/p&gt;
&lt;p&gt;Flow &lt;strong&gt;Install Endpoints&lt;/strong&gt; (phím &lt;code&gt;Y&lt;/code&gt;) giờ chỉ target các công cụ có persisted config contract ổn định. &lt;code&gt;Claude Code&lt;/code&gt;, &lt;code&gt;Codex&lt;/code&gt;, và &lt;code&gt;Gemini&lt;/code&gt; ở lại launcher-only và nên được bắt đầu trực tiếp từ FCM.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;🔌 Tích hợp OpenCode&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Cách dễ nhất&lt;/strong&gt; — để &lt;code&gt;free-coding-models&lt;/code&gt; làm mọi thứ:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Chạy&lt;/strong&gt;: &lt;code&gt;free-coding-models --opencode&lt;/code&gt; (hoặc launch không flag để dùng chế độ OpenCode CLI mặc định)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Đợi&lt;/strong&gt; các mô hình được ping (trạng thái xanh ✅)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Di chuyển&lt;/strong&gt; với ↑↓ mũi tên đến mô hình ưa thích của bạn&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nhấn Enter&lt;/strong&gt; — công cụ tự động:
&lt;ul&gt;
&lt;li&gt;Phát hiện nếu NVIDIA NIM được cấu hình trong OpenCode&lt;/li&gt;
&lt;li&gt;Đặt mô hình đã chọn của bạn làm mặc định trong &lt;code&gt;~/.config/opencode/opencode.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Launch OpenCode với mô hình pre-selected và sẵn sàng sử dụng&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;tmux sub-agent panes&lt;/h3&gt;
&lt;p&gt;Khi được launch từ &lt;code&gt;tmux&lt;/code&gt; session hiện có, &lt;code&gt;free-coding-models&lt;/code&gt; giờ tự động thêm argument OpenCode &lt;code&gt;--port&lt;/code&gt; nên OpenCode/oh-my-opencode có thể spawn sub-agents trong panes.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ưu tiên 1: reuse &lt;code&gt;OPENCODE_PORT&lt;/code&gt; nếu nó valid và free&lt;/li&gt;
&lt;li&gt;Ưu tiên 2: auto-pick port free đầu tiên trong &lt;code&gt;4096-5095&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Bạn có thể force port cụ thể:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;OPENCODE_PORT=4098 free-coding-models --opencode
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;ZAI provider proxy&lt;/h3&gt;
&lt;p&gt;OpenCode không native hỗ trợ định dạng API path của ZAI (&lt;code&gt;/api/coding/paas/v4/*&lt;/code&gt;). Khi bạn chọn mô hình ZAI, &lt;code&gt;free-coding-models&lt;/code&gt; tự động bắt đầu reverse proxy local dịch requests &lt;code&gt;/v1/*&lt;/code&gt; chuẩn của OpenCode sang API của ZAI. Điều này hoàn toàn trong suốt — chỉ cần chọn mô hình ZAI và nhấn Enter.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cách hoạt động:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;HTTP proxy localhost bắt đầu trên port ngẫu nhiên khả dụng&lt;/li&gt;
&lt;li&gt;OpenCode được cấu hình với provider &lt;code&gt;zai&lt;/code&gt; trỏ tới &lt;code&gt;http://localhost:&amp;#x3C;port&gt;/v1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Proxy rewrite &lt;code&gt;/v1/models&lt;/code&gt; thành &lt;code&gt;/api/coding/paas/v4/models&lt;/code&gt; và &lt;code&gt;/v1/chat/completions&lt;/code&gt; thành &lt;code&gt;/api/coding/paas/v4/chat/completions&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Khi OpenCode thoát, proxy tự động shutdown&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Không cần cấu hình manual — lifecycle proxy được quản lý hoàn toàn bởi &lt;code&gt;free-coding-models&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Cài đặt OpenCode Manual (Tùy chọn)&lt;/h3&gt;
&lt;p&gt;Tạo hoặc chỉnh sửa &lt;code&gt;~/.config/opencode/opencode.json&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;provider&quot;: {
    &quot;nvidia&quot;: {
      &quot;npm&quot;: &quot;@ai-sdk/openai-compatible&quot;,
      &quot;name&quot;: &quot;NVIDIA NIM&quot;,
      &quot;options&quot;: {
        &quot;baseURL&quot;: &quot;https://integrate.api.nvidia.com/v1&quot;,
        &quot;apiKey&quot;: &quot;{env:NVIDIA_API_KEY}&quot;
      }
    }
  },
  &quot;model&quot;: &quot;nvidia/deepseek-ai/deepseek-v3.2&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sau đó đặt environment variable:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;export NVIDIA_API_KEY=nvapi-xxxx-your-key-here
# Thêm vào ~/.bashrc hoặc ~/.zshrc để persistent
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Chạy &lt;code&gt;/models&lt;/code&gt; trong OpenCode và chọn provider &lt;strong&gt;NVIDIA NIM&lt;/strong&gt; và mô hình đã chọn của bạn.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Lưu ý:&lt;/strong&gt; Mô hình miễn phí có giới hạn usage dựa trên tier của NVIDIA — kiểm tra &lt;a href=&quot;https://build.nvidia.com&quot;&gt;build.nvidia.com&lt;/a&gt; cho quotas.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Fallback Cài đặt Tự động&lt;/h3&gt;
&lt;p&gt;Nếu NVIDIA NIM chưa được cấu hình trong OpenCode, công cụ:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hiển thị hướng dẫn cài đặt trong terminal của bạn&lt;/li&gt;
&lt;li&gt;Tạo file &lt;code&gt;prompt&lt;/code&gt; trong &lt;code&gt;$HOME/prompt&lt;/code&gt; với cấu hình chính xác&lt;/li&gt;
&lt;li&gt;Launch OpenCode, sẽ phát hiện và hiển thị prompt tự động&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;🦞 Tích hợp OpenClaw&lt;/h2&gt;
&lt;p&gt;OpenClaw là autonomous AI agent daemon. &lt;code&gt;free-coding-models&lt;/code&gt; có thể cấu hình nó để sử dụng mô hình NVIDIA NIM làm provider mặc định — không cần download hay setup local, mọi thứ chạy qua remote API NIM.&lt;/p&gt;
&lt;h3&gt;Quick Start&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;free-coding-models --openclaw
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hoặc nhấn &lt;strong&gt;&lt;code&gt;Z&lt;/code&gt;&lt;/strong&gt; trong TUI cho đến khi header hiển thị &lt;strong&gt;OpenClaw&lt;/strong&gt;, sau đó nhấn &lt;strong&gt;Enter&lt;/strong&gt; trên mô hình.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Đợi&lt;/strong&gt; các mô hình được ping&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Di chuyển&lt;/strong&gt; với ↑↓ mũi tên đến mô hình ưa thích của bạn&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nhấn Enter&lt;/strong&gt; — công cụ tự động:
&lt;ul&gt;
&lt;li&gt;Đọc &lt;code&gt;~/.openclaw/openclaw.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Thêm block provider &lt;code&gt;nvidia&lt;/code&gt; (NIM base URL + API key của bạn) nếu thiếu&lt;/li&gt;
&lt;li&gt;Đặt &lt;code&gt;agents.defaults.model.primary&lt;/code&gt; thành &lt;code&gt;nvidia/&amp;#x3C;model-id&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Lưu config và in các bước tiếp theo&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Những gì được ghi vào config OpenClaw&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;models&quot;: {
    &quot;providers&quot;: {
      &quot;nvidia&quot;: {
        &quot;baseUrl&quot;: &quot;https://integrate.api.nvidia.com/v1&quot;,
        &quot;api&quot;: &quot;openai-completions&quot;
      }
    }
  },
  &quot;env&quot;: {
    &quot;NVIDIA_API_KEY&quot;: &quot;nvapi-xxxx-your-key&quot;
  },
  &quot;agents&quot;: {
    &quot;defaults&quot;: {
      &quot;model&quot;: {
        &quot;primary&quot;: &quot;nvidia/deepseek-ai/deepseek-v3.2&quot;
      },
      &quot;models&quot;: {
        &quot;nvidia/deepseek-ai/deepseek-v3.2&quot;: {}
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Lưu ý:&lt;/strong&gt; &lt;code&gt;providers&lt;/code&gt; phải nested dưới &lt;code&gt;models.providers&lt;/code&gt; — không phải ở root config. Key &lt;code&gt;providers&lt;/code&gt; root-level bị OpenClaw bỏ qua.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Lưu ý:&lt;/strong&gt; Mô hình cũng phải được liệt kê trong &lt;code&gt;agents.defaults.models&lt;/code&gt; (allowlist). Không có entry này, OpenClaw reject mô hình với &lt;em&gt;&quot;not allowed&quot;&lt;/em&gt; ngay cả khi nó được đặt làm primary.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Sau khi cập nhật config OpenClaw&lt;/h3&gt;
&lt;p&gt;Gateway của OpenClaw &lt;strong&gt;auto-reloads&lt;/strong&gt; thay đổi file config (tùy thuộc vào &lt;code&gt;gateway.reload.mode&lt;/code&gt;). Để apply manual:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Apply qua CLI
openclaw models set nvidia/deepseek-ai/deepseek-v3.2

# Hoặc chạy lại setup wizard tương tác
openclaw configure
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Lưu ý:&lt;/strong&gt; &lt;code&gt;openclaw restart&lt;/code&gt; &lt;strong&gt;không&lt;/strong&gt; tồn tại như CLI command. Kill và relaunch process manual nếu bạn cần full restart.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Tại sao sử dụng mô hình NIM remote với OpenClaw?&lt;/strong&gt; NVIDIA NIM serve mô hình qua API nhanh — không cần GPU local, không giới hạn VRAM, credits miễn phí cho developers. Bạn có được frontier-class coding models (DeepSeek V3, Kimi K2, Qwen3 Coder) mà không cần download gì.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Patching OpenClaw cho hỗ trợ mô hình NVIDIA đầy đủ&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Vấn đề:&lt;/strong&gt; Mặc định, OpenClaw chỉ cho phép một vài mô hình NVIDIA cụ thể trong allowlist của nó. Nếu bạn cố sử dụng mô hình không có trong danh sách, bạn sẽ gặp lỗi này:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Model &quot;nvidia/mistralai/devstral-2-123b-instruct-2512&quot; is not allowed. Use /models to list providers, or /models &amp;#x3C;provider&gt; to list models.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Giải pháp:&lt;/strong&gt; Patch cấu hình OpenClaw để thêm TẤT CẢ 47 mô hình NVIDIA từ &lt;code&gt;free-coding-models&lt;/code&gt; vào allowlist:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Từ thư mục package free-coding-models
node patch-openclaw.js
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Script này:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Backup &lt;code&gt;~/.openclaw/agents/main/agent/models.json&lt;/code&gt; và &lt;code&gt;~/.openclaw/openclaw.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Thêm tất cả 47 mô hình NVIDIA với context window và token limits phù hợp&lt;/li&gt;
&lt;li&gt;Bảo toàn các mô hình và cấu hình hiện có&lt;/li&gt;
&lt;li&gt;In summary những gì được thêm&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Sau khi patch:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Restart OpenClaw gateway:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;systemctl --user restart openclaw-gateway
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Verify các mô hình khả dụng:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;free-coding-models --openclaw
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Chọn bất kỳ mô hình nào — không còn lỗi &quot;not allowed&quot;!&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Tại sao cần điều này:&lt;/strong&gt; OpenClaw sử dụng hệ thống allowlist nghiêm ngặt để ngăn typos và mô hình invalid. Script &lt;code&gt;patch-openclaw.js&lt;/code&gt; populate allowlist với tất cả mô hình NVIDIA hoạt động đã biết, vì vậy bạn có thể tự do chuyển đổi giữa chúng mà không cần chỉnh sửa file config manual.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;⚙️ Cách hoạt động&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;┌──────────────────────────────────────────────────────────────────┐
│  1. Vào alternate screen buffer (như vim/htop/less)              │
│  2. Ping TẤT CẢ mô hình song song                                │
│  3. Hiển thị bảng thời gian thực với Latest/Avg/Stability/Up%   │
│  4. Re-ping TẤT CẢ mô hình ở 2s khi khởi động, sau đó 10s       │
│     steady-state và 30s sau 5 phút idle trừ khi forced 4s với W │
│  5. Cập nhật rolling averages + stability scores mỗi mô hình    │
│  6. User có thể di chuyển với ↑↓ và chọn với Enter             │
│  7. Khi Enter (OpenCode): đặt mô hình, launch OpenCode          │
│  8. Khi Enter (OpenClaw): cập nhật ~/.openclaw/openclaw.json    │
└──────────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Kết quả:&lt;/strong&gt; Giao diện giám sát liên tục ở lại mở cho đến khi bạn chọn mô hình hoặc nhấn Ctrl+C. Rolling averages cung cấp dữ liệu latency dài hạn chính xác, điểm stability tiết lộ mô hình nào thực sự nhất quán so với spikey lừa dối, và bạn có thể cấu hình công cụ đã chọn của mình với một keystroke. Nếu terminal quá hẹp, app hiển thị cảnh báo căn giữa thay vì bảng truncated.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;📋 API Reference&lt;/h2&gt;
&lt;h3&gt;🎁 Premium Flag&lt;/h3&gt;
&lt;p&gt;Flag &lt;code&gt;--premium&lt;/code&gt; cung cấp quick view chỉ các mô hình &lt;strong&gt;S/S+ tier&lt;/strong&gt; elite với health hoàn hảo (&lt;strong&gt;UP&lt;/strong&gt;) và verdict tốt (&lt;strong&gt;Perfect&lt;/strong&gt;, &lt;strong&gt;Normal&lt;/strong&gt;, hoặc &lt;strong&gt;Slow&lt;/strong&gt;). Điều này hữu ích khi bạn muốn tập trung độc quyền vào các mô hình chất lượng cao nhất, đáng tin cậy nhất hiện khả dụng.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;free-coding-models --premium
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nó làm gì bên dưới:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Đặt &lt;code&gt;tierFilter&lt;/code&gt; thành &lt;code&gt;S&lt;/code&gt; (chỉ hiển thị mô hình S+ và S tier).&lt;/li&gt;
&lt;li&gt;Lọc ra bất kỳ mô hình nào không hiện &lt;strong&gt;UP&lt;/strong&gt; (ẩn 429, 410, auth fail, timeouts, v.v.).&lt;/li&gt;
&lt;li&gt;Lọc ra mô hình với verdicts kém (ẩn &lt;strong&gt;Spiky&lt;/strong&gt;, &lt;strong&gt;Very Slow&lt;/strong&gt;, &lt;strong&gt;Overloaded&lt;/strong&gt;, &lt;strong&gt;Unstable&lt;/strong&gt;, v.v.).&lt;/li&gt;
&lt;li&gt;Force sort column thành &lt;code&gt;verdict&lt;/code&gt; với thứ tự tăng dần, nên các mô hình được đánh giá tốt nhất xuất hiện ở trên cùng.&lt;/li&gt;
&lt;li&gt;Để các cài đặt khác không chạm, vì vậy bạn vẫn có thể kết hợp nó với các flag như &lt;code&gt;--json&lt;/code&gt; cho scripting.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Bạn có thể kết hợp &lt;code&gt;--premium&lt;/code&gt; với các flag khác (ví dụ: &lt;code&gt;--json --hide-unconfigured&lt;/code&gt;) để further tailor output.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;Environment variables (override file config):&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;| Variable | Mô tả |
|----------|-------------|
| &lt;code&gt;NVIDIA_API_KEY&lt;/code&gt; | Key NVIDIA NIM |
| &lt;code&gt;GROQ_API_KEY&lt;/code&gt; | Key Groq |
| &lt;code&gt;CEREBRAS_API_KEY&lt;/code&gt; | Key Cerebras |
| &lt;code&gt;SAMBANOVA_API_KEY&lt;/code&gt; | Key SambaNova |
| &lt;code&gt;OPENROUTER_API_KEY&lt;/code&gt; | Key OpenRouter |
| &lt;code&gt;HUGGINGFACE_API_KEY&lt;/code&gt; / &lt;code&gt;HF_TOKEN&lt;/code&gt; | Token Hugging Face |
| &lt;code&gt;REPLICATE_API_TOKEN&lt;/code&gt; | Token Replicate |
| &lt;code&gt;DEEPINFRA_API_KEY&lt;/code&gt; / &lt;code&gt;DEEPINFRA_TOKEN&lt;/code&gt; | Key DeepInfra |
| &lt;code&gt;CODESTRAL_API_KEY&lt;/code&gt; | Key Mistral Codestral |
| &lt;code&gt;HYPERBOLIC_API_KEY&lt;/code&gt; | Key Hyperbolic |
| &lt;code&gt;SCALEWAY_API_KEY&lt;/code&gt; | Key Scaleway |
| &lt;code&gt;GOOGLE_API_KEY&lt;/code&gt; | Key Google AI Studio |
| &lt;code&gt;SILICONFLOW_API_KEY&lt;/code&gt; | Key SiliconFlow |
| &lt;code&gt;TOGETHER_API_KEY&lt;/code&gt; | Key Together AI |
| &lt;code&gt;CLOUDFLARE_API_TOKEN&lt;/code&gt; / &lt;code&gt;CLOUDFLARE_API_KEY&lt;/code&gt; | Token/key Cloudflare Workers AI |
| &lt;code&gt;CLOUDFLARE_ACCOUNT_ID&lt;/code&gt; | Account ID Cloudflare (bắt buộc cho URL endpoint Workers AI) |
| &lt;code&gt;PERPLEXITY_API_KEY&lt;/code&gt; / &lt;code&gt;PPLX_API_KEY&lt;/code&gt; | Key Perplexity API |
| &lt;code&gt;ZAI_API_KEY&lt;/code&gt; | Key ZAI |
| &lt;code&gt;DASHSCOPE_API_KEY&lt;/code&gt; | Key Alibaba Cloud (DashScope) API |&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;File config:&lt;/strong&gt; &lt;code&gt;~/.free-coding-models.json&lt;/code&gt; (tự động tạo, permissions &lt;code&gt;0600&lt;/code&gt;)&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;apiKeys&quot;: {
    &quot;nvidia&quot;:   &quot;nvapi-xxx&quot;,
    &quot;groq&quot;:     &quot;gsk_xxx&quot;,
    &quot;cerebras&quot;: &quot;csk_xxx&quot;,
    &quot;openrouter&quot;: &quot;sk-or-xxx&quot;,
    &quot;huggingface&quot;: &quot;hf_xxx&quot;,
    &quot;replicate&quot;: &quot;r8_xxx&quot;,
    &quot;deepinfra&quot;: &quot;di_xxx&quot;,
    &quot;siliconflow&quot;: &quot;sk_xxx&quot;,
    &quot;together&quot;: &quot;together_xxx&quot;,
    &quot;cloudflare&quot;: &quot;cf_xxx&quot;,
    &quot;perplexity&quot;: &quot;pplx_xxx&quot;,
    &quot;zai&quot;:      &quot;zai-xxx&quot;
  },
  &quot;providers&quot;: {
    &quot;nvidia&quot;:   { &quot;enabled&quot;: true },
    &quot;groq&quot;:     { &quot;enabled&quot;: true },
    &quot;cerebras&quot;: { &quot;enabled&quot;: true },
    &quot;openrouter&quot;: { &quot;enabled&quot;: true },
    &quot;huggingface&quot;: { &quot;enabled&quot;: true },
    &quot;replicate&quot;: { &quot;enabled&quot;: true },
    &quot;deepinfra&quot;: { &quot;enabled&quot;: true },
    &quot;siliconflow&quot;: { &quot;enabled&quot;: true },
    &quot;together&quot;: { &quot;enabled&quot;: true },
    &quot;cloudflare&quot;: { &quot;enabled&quot;: true },
    &quot;perplexity&quot;: { &quot;enabled&quot;: true },
    &quot;zai&quot;:      { &quot;enabled&quot;: true }
   },
   &quot;settings&quot;: {
     &quot;hideUnconfiguredModels&quot;: true
   },
   &quot;favorites&quot;: [
     &quot;nvidia/deepseek-ai/deepseek-v3.2&quot;
   ]
 }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Cấu hình:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ping timeout&lt;/strong&gt;: 15 giây mỗi attempt (mô hình chậm có thêm thời gian)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ping cadence&lt;/strong&gt;: startup burst ở 2 giây trong 60s, sau đó 10 giây bình thường, 30 giây khi idle 5 phút, hoặc forced 4 giây qua &lt;code&gt;W&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Chế độ monitor&lt;/strong&gt;: Giao diện ở lại mở mãi mãi, nhấn Ctrl+C để thoát&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Flags:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;| Flag | Mô tả |
|------|-------------|
| &lt;em&gt;(không)&lt;/em&gt; | Bắt đầu ở chế độ OpenCode CLI |
| &lt;code&gt;--opencode&lt;/code&gt; | Chế độ OpenCode CLI — Enter launch OpenCode CLI với mô hình đã chọn |
| &lt;code&gt;--opencode-desktop&lt;/code&gt; | Chế độ OpenCode Desktop — Enter đặt mô hình và mở OpenCode Desktop |
| &lt;code&gt;--openclaw&lt;/code&gt; | Chế độ OpenClaw — Enter đặt mô hình đã chọn làm mặc định trong OpenClaw |
| &lt;code&gt;--crush&lt;/code&gt; | Chế độ Crush — Enter viết &lt;code&gt;crush.json&lt;/code&gt; và launch Crush |
| &lt;code&gt;--goose&lt;/code&gt; | Chế độ Goose — Enter launch Goose với env-based provider config |
| &lt;code&gt;--best&lt;/code&gt; | Chỉ hiển thị mô hình top-tier (A+, S, S+) |
| &lt;code&gt;--fiable&lt;/code&gt; | Phân tích 10 giây, xuất mô hình đáng tin cậy nhất dưới dạng &lt;code&gt;provider/model_id&lt;/code&gt; |
| &lt;code&gt;--json&lt;/code&gt; | Xuất kết quả dưới dạng JSON (cho scripting/automation, CI/CD, dashboards) |
| &lt;code&gt;--tier S&lt;/code&gt; | Chỉ hiển thị mô hình S+ và S tier |
| &lt;code&gt;--tier A&lt;/code&gt; | Chỉ hiển thị mô hình A+, A, A- tier |
| &lt;code&gt;--tier B&lt;/code&gt; | Chỉ hiển thị mô hình B+, B tier |
| &lt;code&gt;--tier C&lt;/code&gt; | Chỉ hiển thị mô hình C tier |
| &lt;code&gt;--profile &amp;#x3C;name&gt;&lt;/code&gt; | Load config profile đã lưu khi khởi động |
| &lt;code&gt;--recommend&lt;/code&gt; | Tự động mở overlay Smart Recommend khi bắt đầu |
| &lt;code&gt;--clean-proxy&lt;/code&gt; | Xóa config &lt;code&gt;fcm-proxy&lt;/code&gt; persisted khỏi OpenCode |&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Phím tắt (TUI chính):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;↑↓&lt;/strong&gt; — Di chuyển mô hình&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enter&lt;/strong&gt; — Chọn mô hình và launch công cụ target hiện tại từ header badge&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;R/S/C/M/O/L/A/H/V/B/U/G&lt;/strong&gt; — Sort theo Rank/SWE/Ctx/Model/Provider/Latest/Avg/Health/Verdict/Stability/Up%/Usage&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;F&lt;/strong&gt; — Toggle favorite trên mô hình đã chọn (⭐ trong cột Model, pinned ở trên cùng)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;T&lt;/strong&gt; — Cycle tier filter (All → S+ → S → A+ → A → A- → B+ → B → C → All)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;D&lt;/strong&gt; — Cycle provider filter (All → NIM → Groq → ...)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;E&lt;/strong&gt; — Toggle chế độ configured-only (bật mặc định, persisted qua sessions và profiles)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Z&lt;/strong&gt; — Cycle target tool (OpenCode CLI → Desktop → OpenClaw → Crush → Goose → Pi → Aider → Claude Code → Codex → Gemini → Qwen → OpenHands → Amp)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;X&lt;/strong&gt; — Toggle request logs (logs request proxied gần đây/token usage, lên đến 500 entries)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A (trong logs)&lt;/strong&gt; — Toggle giữa hiển thị 500 entries hoặc TẤT CẢ logs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P&lt;/strong&gt; — Mở Settings (quản lý API keys, toggles, updates, profiles)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Y&lt;/strong&gt; — Mở Install Endpoints (&lt;code&gt;provider → tool → connection mode → scope → models&lt;/code&gt;, Direct hoặc FCM Proxy V2)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Shift+P&lt;/strong&gt; — Cycle qua saved profiles (chuyển đổi cài đặt TUI trực tiếp)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Shift+S&lt;/strong&gt; — Lưu cài đặt TUI hiện tại làm profile được đặt tên (prompt inline)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Q&lt;/strong&gt; — Mở overlay Smart Recommend (tìm mô hình tốt nhất cho task của bạn)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;N&lt;/strong&gt; — Mở Changelog overlay (duyệt index của tất cả phiên bản, &lt;code&gt;Enter&lt;/code&gt; để xem chi tiết, &lt;code&gt;B&lt;/code&gt; để quay lại)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;W&lt;/strong&gt; — Cycle chế độ ping (&lt;code&gt;FAST&lt;/code&gt; 2s → &lt;code&gt;NORMAL&lt;/code&gt; 10s → &lt;code&gt;SLOW&lt;/code&gt; 30s → &lt;code&gt;FORCED&lt;/code&gt; 4s)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;J&lt;/strong&gt; — Mở cài đặt FCM Proxy V2 (hiển thị badge xanh lá &quot;Proxy On&quot; / đỏ &quot;Proxy Off&quot; trong footer)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;I&lt;/strong&gt; — Feedback, bugs &amp;#x26; requests&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;K / Esc&lt;/strong&gt; — Hiển thị overlay help / Đóng overlay&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ctrl+C&lt;/strong&gt; — Thoát&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nhấn &lt;strong&gt;K&lt;/strong&gt; giờ hiển thị reference in-app đầy đủ: hotkeys chính, hotkeys settings, và CLI flags với ví dụ sử dụng.&lt;/p&gt;
&lt;h3&gt;🔌 Install Endpoints (&lt;code&gt;Y&lt;/code&gt;)&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Y&lt;/code&gt; mở dedicated install flow cho các nhà cung cấp đã cấu hình. Flow 5 bước là:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Provider&lt;/strong&gt; — Chọn một nhà cung cấp đã có API key trong Settings&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tool&lt;/strong&gt; — Chọn công cụ target từ các install targets tương thích:
&lt;ul&gt;
&lt;li&gt;Config-based: &lt;code&gt;OpenCode CLI&lt;/code&gt;, &lt;code&gt;OpenCode Desktop&lt;/code&gt;, &lt;code&gt;OpenClaw&lt;/code&gt;, &lt;code&gt;Crush&lt;/code&gt;, &lt;code&gt;Goose&lt;/code&gt;, &lt;code&gt;Pi&lt;/code&gt;, &lt;code&gt;Aider&lt;/code&gt;, &lt;code&gt;Amp&lt;/code&gt;, &lt;code&gt;Qwen&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Env-file based: &lt;code&gt;OpenHands&lt;/code&gt; (ghi &lt;code&gt;~/.fcm-openhands-env&lt;/code&gt; — source nó trước khi launch)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Connection Mode&lt;/strong&gt; — Chọn cách công cụ kết nối với nhà cung cấp:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;⚡ Direct Provider&lt;/strong&gt; — kết nối API thuần, không có proxy&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;🔄 FCM Proxy V2&lt;/strong&gt; — route qua FCM Proxy V2 với key rotation và usage tracking&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scope&lt;/strong&gt; — Chọn &lt;code&gt;Install all models&lt;/code&gt; hoặc &lt;code&gt;Install selected models only&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Models&lt;/strong&gt; (nếu scope = selected) — Multi-select từng mô hình từ catalog nhà cung cấp&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Hành vi quan trọng:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Installs được ghi vào config công cụ target như entries FCM-managed (namespaced dưới &lt;code&gt;fcm-*&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Install all models&lt;/code&gt; là đường được khuyến nghị vì FCM có thể refresh catalog đó tự động trên các launches sau khi danh sách mô hình nhà cung cấp thay đổi&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Install selected models only&lt;/code&gt; hữu ích khi bạn muốn picker nhỏ hơn curated bên trong công cụ target&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OpenCode CLI&lt;/code&gt; và &lt;code&gt;OpenCode Desktop&lt;/code&gt; chia sẻ cùng &lt;code&gt;opencode.json&lt;/code&gt;, nên managed provider xuất hiện trong cả hai&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Claude Code&lt;/code&gt;, &lt;code&gt;Codex&lt;/code&gt;, và &lt;code&gt;Gemini&lt;/code&gt; là launcher-only trong flow này hiện tại. Dùng đường launcher &lt;code&gt;Enter&lt;/code&gt; bình thường nên FCM có thể apply proxy/runtime contract phù hợp tự động.&lt;/li&gt;
&lt;li&gt;Cho install targets env-based như &lt;code&gt;OpenHands&lt;/code&gt;, FCM ghi file helper sourceable tại &lt;code&gt;~/.fcm-{tool}-env&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Phím tắt (màn hình Settings — phím &lt;code&gt;P&lt;/code&gt;):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;↑↓&lt;/strong&gt; — Di chuyển nhà cung cấp, hàng maintenance, và hàng profile&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enter&lt;/strong&gt; — Chỉnh sửa API key inline, check/cài đặt update, hoặc load profile&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Space&lt;/strong&gt; — Toggle nhà cung cấp enabled/disabled&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;T&lt;/strong&gt; — Test API key nhà cung cấp hiện tại (fires live ping)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;U&lt;/strong&gt; — Check updates manual từ settings&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Backspace&lt;/strong&gt; — Xóa profile đã chọn (chỉ trên hàng profile)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Esc&lt;/strong&gt; — Đóng settings và quay lại TUI chính&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;📋 Config Profiles&lt;/h3&gt;
&lt;p&gt;Profiles cho phép bạn lưu và restore các cấu hình TUI khác nhau — hữu ích nếu bạn chuyển đổi giữa work/personal setups, tùy chọn tier khác nhau, hoặc muốn giữ danh sách favorites riêng.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Những gì được lưu trong profile:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Favorites (mô hình starred)&lt;/li&gt;
&lt;li&gt;Sort column và direction&lt;/li&gt;
&lt;li&gt;Tier filter&lt;/li&gt;
&lt;li&gt;Ping mode&lt;/li&gt;
&lt;li&gt;Configured-only filter&lt;/li&gt;
&lt;li&gt;API keys&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Lưu profile:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Cấu hình TUI theo cách bạn muốn (favorites, sort, tier, v.v.)&lt;/li&gt;
&lt;li&gt;Nhấn &lt;strong&gt;Shift+S&lt;/strong&gt; — prompt inline xuất hiện ở dưới cùng&lt;/li&gt;
&lt;li&gt;Gõ tên (ví dụ: &lt;code&gt;work&lt;/code&gt;, &lt;code&gt;fast-only&lt;/code&gt;, &lt;code&gt;presentation&lt;/code&gt;) và nhấn &lt;strong&gt;Enter&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Profile được lưu và trở thành profile active (hiển thị như badge tím trong header)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Chuyển đổi profiles:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Shift+P&lt;/strong&gt; trong bảng chính — cycle qua saved profiles (hoặc quay lại raw config)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--profile &amp;#x3C;name&gt;&lt;/code&gt;&lt;/strong&gt; — load profile cụ thể khi khởi động&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Quản lý profiles:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mở Settings (phím &lt;strong&gt;P&lt;/strong&gt;) — scroll xuống phần &lt;strong&gt;Profiles&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enter&lt;/strong&gt; trên hàng profile để load nó&lt;/li&gt;
&lt;li&gt;Trong khi profile active, chỉnh sửa favorites và API keys cập nhật profile active đó ngay lập tức&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Backspace&lt;/strong&gt; trên hàng profile để xóa nó&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Profiles được lưu bên trong &lt;code&gt;~/.free-coding-models.json&lt;/code&gt; dưới key &lt;code&gt;profiles&lt;/code&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;🔧 Development&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git clone https://github.com/vava-nessa/free-coding-models
cd free-coding-models
npm install
npm start -- YOUR_API_KEY
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Phát hành version mới&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Thực hiện thay đổi của bạn và commit chúng với message mô tả&lt;/li&gt;
&lt;li&gt;Cập nhật &lt;code&gt;CHANGELOG.md&lt;/code&gt; với entry version mới&lt;/li&gt;
&lt;li&gt;Bump &lt;code&gt;&quot;version&quot;&lt;/code&gt; trong &lt;code&gt;package.json&lt;/code&gt; (ví dụ: &lt;code&gt;0.1.3&lt;/code&gt; → &lt;code&gt;0.1.4&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Commit với &lt;strong&gt;chỉ số version&lt;/strong&gt; làm message:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git add .
git commit -m &quot;0.1.4&quot;
git push
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;GitHub Actions workflow tự động publish lên npm trên mọi push vào &lt;code&gt;main&lt;/code&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;📄 License&lt;/h2&gt;
&lt;p&gt;MIT © &lt;a href=&quot;https://github.com/vava-nessa&quot;&gt;vava&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;📬 Contribute&lt;/h2&gt;
&lt;p&gt;Chúng tôi chào đón đóng góp! Hãy thoải mái mở issues, submit pull requests, hoặc tham gia vào dự án.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; Tôi có thể sử dụng cái này với các nhà cung cấp khác không?
&lt;strong&gt;A:&lt;/strong&gt; Có, công cụ được thiết kế để mở rộng; xem source cho ví dụ về customizing endpoints.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; Các số latency chính xác như thế nào?
&lt;strong&gt;A:&lt;/strong&gt; Chúng đại diện cho round-trip times trung bình được đo trong quá trình testing; hiệu suất thực tế có thể khác nhau tùy thuộc vào điều kiện mạng.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; Tôi có cần download mô hình local cho OpenClaw không?
&lt;strong&gt;A:&lt;/strong&gt; Không — &lt;code&gt;free-coding-models&lt;/code&gt; cấu hình OpenClaw để sử dụng remote API của NVIDIA NIM, vì vậy các mô hình chạy trên infrastructure của NVIDIA. Không cần GPU hay setup local.&lt;/p&gt;
&lt;h2&gt;📧 Support&lt;/h2&gt;
&lt;p&gt;Cho các câu hỏi hoặc vấn đề, mở &lt;a href=&quot;https://github.com/vava-nessa/free-coding-models/issues&quot;&gt;GitHub issue&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;💬 Hãy thảo luận về dự án trên Discord: https://discord.gg/ZTNFHvvCkU&lt;/p&gt;
&lt;hr&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>Nhật ký technical interview NAB</title><link>https://astro-pure.js.org/vi/blog/nab-technical-interview-log</link><guid isPermaLink="true">https://astro-pure.js.org/vi/blog/nab-technical-interview-log</guid><description>Ghi lại các câu hỏi technical interview NAB để ôn tập lại từ English, CS, networking, database đến coding.</description><pubDate>Mon, 16 Mar 2026 11:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import { Aside, Steps, Collapse } from &apos;astro-pure/user&apos;&lt;/p&gt;
&lt;h2&gt;Vì sao tôi viết lại buổi phỏng vấn này?&lt;/h2&gt;
&lt;p&gt;Có những buổi phỏng vấn trôi qua xong là đầu óc rơi vào trạng thái: &lt;em&gt;&quot;ủa nãy mình đã trả lời cái gì vậy?&quot;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Vì thế tôi muốn lưu lại toàn bộ những gì đã được hỏi trong &lt;strong&gt;technical round NAB batch 18-2&lt;/strong&gt;. Mục tiêu không phải để khoe rằng mình được hỏi khó hay dễ, mà để biến buổi phỏng vấn thành một tài liệu ôn tập thật sự hữu ích cho những lần sau.&lt;/p&gt;
&lt;h2&gt;Tổng quan buổi technical round&lt;/h2&gt;
&lt;p&gt;Buổi phỏng vấn không chỉ xoay quanh code. Phạm vi câu hỏi trải dài từ:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;giới thiệu bản thân bằng tiếng Anh&lt;/li&gt;
&lt;li&gt;cách giao tiếp và từng lead team ra sao&lt;/li&gt;
&lt;li&gt;kiến thức nền tảng computer science&lt;/li&gt;
&lt;li&gt;data structure và algorithm&lt;/li&gt;
&lt;li&gt;networking và hạ tầng&lt;/li&gt;
&lt;li&gt;database, đặc biệt là PostgreSQL&lt;/li&gt;
&lt;li&gt;một bài coding nhỏ với stack&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Điều này cho thấy họ không tìm một người chỉ biết viết API. Họ muốn kiểm tra xem ứng viên có đủ góc nhìn của một backend engineer hay không.&lt;/p&gt;
&lt;h2&gt;1. Phần English và background&lt;/h2&gt;
&lt;p&gt;Phần mở đầu là giới thiệu về bản thân bằng tiếng Anh. Đây là đoạn tưởng nhẹ nhàng nhưng lại khá quan trọng, vì interviewer sẽ từ CV đào tiếp vào từng chi tiết.&lt;/p&gt;
&lt;h3&gt;Những ý tôi đã được hỏi&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Tech stack bản thân đang dùng&lt;/li&gt;
&lt;li&gt;Các project xuất hiện trong CV&lt;/li&gt;
&lt;li&gt;Những nơi từng thực tập&lt;/li&gt;
&lt;li&gt;Vai trò thực tế trong các dự án&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sau đó interviewer đi vào phần &lt;strong&gt;communication&lt;/strong&gt; vì trong CV có ghi từng đảm nhiệm vai trò &lt;strong&gt;tech lead&lt;/strong&gt; trong thời gian thực tập.&lt;/p&gt;
&lt;h3&gt;Câu hỏi đào sâu về communication&lt;/h3&gt;
&lt;p&gt;Họ hỏi về cách tôi lead team, cụ thể theo hướng:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;phân chia công việc như thế nào&lt;/li&gt;
&lt;li&gt;hỗ trợ member khi bị block ra sao&lt;/li&gt;
&lt;li&gt;xử lý coordination trong team thế nào&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Điểm này không đòi hỏi phải trả lời quá hoa mỹ. Điều họ muốn thấy là mình có thật sự từng làm việc với con người hay không, hay chỉ viết &quot;tech lead&quot; cho CV nhìn oách như áo khoác da trong phim.&lt;/p&gt;
&lt;h2&gt;2. Infrastructure: backend mà không biết hạ tầng thì hơi căng&lt;/h2&gt;
&lt;p&gt;Do CV có đề cập đến:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;tham gia &lt;strong&gt;AWS FCAJ&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;có &lt;strong&gt;homelab server&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;nên interviewer hỏi tiếp về cloud và infrastructure.&lt;/p&gt;
&lt;h3&gt;Những điểm họ muốn nghe&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Backend developer practice với cloud như thế nào&lt;/li&gt;
&lt;li&gt;Tôi đã làm gì với home server&lt;/li&gt;
&lt;li&gt;Tôi hiểu deployment, networking, reverse proxy, DNS hay không&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Điểm thú vị là interviewer có nhận xét rằng:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Dù là backend, kiến thức infrastructure vẫn quan trọng không kém.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Tôi thấy nhận xét này rất đúng. Ở nhiều môi trường, backend không thể chỉ biết ORM, controller và service layer. Chỉ cần một ngày phải deploy app, debug SSL, xử lý reverse proxy hoặc hiểu vì sao request đi không tới server là đã bước vào đất của infra rồi.&lt;/p&gt;
&lt;h2&gt;3. Computer Science: process, thread và memory&lt;/h2&gt;
&lt;p&gt;Sau phần background, buổi phỏng vấn chuyển sang các kiến thức nền tảng.&lt;/p&gt;
&lt;h3&gt;Process và thread&lt;/h3&gt;
&lt;p&gt;Các ý được hỏi gồm:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Process là gì&lt;/li&gt;
&lt;li&gt;Thread là gì&lt;/li&gt;
&lt;li&gt;Một process chứa nhiều thread ra sao&lt;/li&gt;
&lt;li&gt;Chúng chia sẻ tài nguyên như thế nào&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cách hiểu gọn:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Process&lt;/strong&gt; là một chương trình đang chạy, có không gian bộ nhớ riêng&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Thread&lt;/strong&gt; là luồng thực thi bên trong process&lt;/li&gt;
&lt;li&gt;Một process có thể chứa nhiều thread&lt;/li&gt;
&lt;li&gt;Các thread trong cùng process thường chia sẻ vùng nhớ chung của process&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Intel Hyper-Threading&lt;/h3&gt;
&lt;p&gt;Interviewer còn hỏi về &lt;strong&gt;Intel Hyper-Threading&lt;/strong&gt;. Đây là kiểu câu hỏi dùng để xem ứng viên có hiểu song song ở mức nền tảng hay không.&lt;/p&gt;
&lt;p&gt;Ý chính là:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;một physical core có thể xử lý như nhiều logical thread&lt;/li&gt;
&lt;li&gt;mục tiêu là tận dụng tài nguyên CPU tốt hơn&lt;/li&gt;
&lt;li&gt;nó không biến 1 core thành 2 core thật, nhưng giúp pipeline đỡ bị bỏ phí trong nhiều tình huống&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Memory allocation&lt;/h3&gt;
&lt;p&gt;Phần này gắn với câu chuyện process và thread:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;process có memory space riêng&lt;/li&gt;
&lt;li&gt;thread dùng chung một phần memory của process&lt;/li&gt;
&lt;li&gt;stack và heap là những ý nền tảng nên hiểu rõ&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;4. DSA: ArrayList và LinkedList&lt;/h2&gt;
&lt;p&gt;Đây là nhóm câu hỏi khá kinh điển nhưng rất dễ trả lời lệch nếu nói quá nhanh.&lt;/p&gt;
&lt;h3&gt;Các ý được hỏi&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Quan hệ &quot;cha con&quot; giữa các kiểu list&lt;/li&gt;
&lt;li&gt;Cách cấp phát bộ nhớ&lt;/li&gt;
&lt;li&gt;Độ phức tạp khi chèn phần tử&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;So sánh nhanh&lt;/h3&gt;
&lt;h4&gt;ArrayList&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;cấp phát theo vùng nhớ liên tục&lt;/li&gt;
&lt;li&gt;truy cập ngẫu nhiên nhanh&lt;/li&gt;
&lt;li&gt;chèn phần tử ở giữa thường phải dời phần tử phía sau&lt;/li&gt;
&lt;li&gt;vì vậy insert thường là &lt;strong&gt;O(n)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;LinkedList&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;mỗi node chứa data và reference đến node khác&lt;/li&gt;
&lt;li&gt;bộ nhớ không cần liên tục&lt;/li&gt;
&lt;li&gt;nếu đã có sẵn reference đến node cần chèn sau đó thì insert có thể là &lt;strong&gt;O(1)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;nhưng truy cập đến đúng vị trí thường phải duyệt nên lookup là &lt;strong&gt;O(n)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;5. Networking: từ homelab đến TLS termination&lt;/h2&gt;
&lt;p&gt;Đây là phần tôi thấy khá thú vị vì nó bám sát trải nghiệm thực tế hơn là lý thuyết sách giáo khoa.&lt;/p&gt;
&lt;h3&gt;Public IP và Cloudflare Tunnel&lt;/h3&gt;
&lt;p&gt;Do CV có ghi hosting homelab server nên interviewer hỏi về:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Public IP&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cloudflare Tunnel&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ý chính:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Nếu dùng &lt;strong&gt;Public IP&lt;/strong&gt;, server có thể được expose trực tiếp qua router, port forwarding và firewall rule&lt;/li&gt;
&lt;li&gt;Nếu dùng &lt;strong&gt;Cloudflare Tunnel&lt;/strong&gt;, dịch vụ nội bộ có thể được publish ra ngoài mà không cần mở port trực tiếp từ ISP vào server&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Câu hỏi này không chỉ kiểm tra định nghĩa mà còn kiểm tra xem mình đã thật sự &quot;vọc&quot; hạ tầng chưa.&lt;/p&gt;
&lt;h3&gt;DNS và cách ISP chặn website&lt;/h3&gt;
&lt;p&gt;Một câu hỏi khá hay là:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ISP làm thế nào để chặn truy cập website?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Đây là câu hỏi networking rất thực chiến. Một số hướng có thể nói:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;chặn ở tầng DNS&lt;/li&gt;
&lt;li&gt;trả về kết quả DNS sai hoặc không resolve&lt;/li&gt;
&lt;li&gt;chặn IP đích&lt;/li&gt;
&lt;li&gt;lọc lưu lượng ở các tầng mạng khác&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Điểm hay là interviewer không chỉ hỏi &quot;DNS là gì&quot; mà hỏi đến use case ngoài đời.&lt;/p&gt;
&lt;h3&gt;TLS termination, HTTPS và HTTP&lt;/h3&gt;
&lt;p&gt;Phần này xoay quanh cách traffic HTTPS được xử lý ở reverse proxy hoặc edge layer.&lt;/p&gt;
&lt;p&gt;Một flow rất điển hình là:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Client gửi request qua HTTPS&lt;/li&gt;
&lt;li&gt;Reverse proxy hoặc load balancer nhận kết nối TLS&lt;/li&gt;
&lt;li&gt;Thiết bị đó giải mã TLS&lt;/li&gt;
&lt;li&gt;Traffic có thể được chuyển tiếp vào backend qua HTTP nội bộ hoặc tiếp tục qua HTTPS&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Khái niệm này được gọi là &lt;strong&gt;TLS termination&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;SSL certificate và Let&apos;s Encrypt&lt;/h3&gt;
&lt;p&gt;Khi nhắc đến HTTPS, câu chuyện tự nhiên đi đến &lt;strong&gt;SSL certificate&lt;/strong&gt; và &lt;strong&gt;Let&apos;s Encrypt&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Đây là kiến thức khá thực dụng với người từng host app:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;cần certificate để trình duyệt tin tưởng kết nối HTTPS&lt;/li&gt;
&lt;li&gt;Let&apos;s Encrypt giúp cấp certificate miễn phí&lt;/li&gt;
&lt;li&gt;thường được dùng chung với NGINX, Caddy, Traefik hoặc Cloudflare setup&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;6. Database: PostgreSQL và các câu hỏi rất &quot;backend&quot;&lt;/h2&gt;
&lt;p&gt;Phần database tập trung vào các khái niệm quan hệ cơ bản và indexing.&lt;/p&gt;
&lt;h3&gt;Những khái niệm relational database cơ bản&lt;/h3&gt;
&lt;p&gt;Các ý được hỏi:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;table&lt;/li&gt;
&lt;li&gt;record&lt;/li&gt;
&lt;li&gt;row&lt;/li&gt;
&lt;li&gt;column&lt;/li&gt;
&lt;li&gt;composite key&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Đây là vùng kiến thức không khó nhưng rất dễ chủ quan. Vì phỏng vấn kỹ thuật thường thích lấy thứ tưởng cơ bản để xem ứng viên có nói chính xác không.&lt;/p&gt;
&lt;h3&gt;Composite key&lt;/h3&gt;
&lt;p&gt;Composite key là key được tạo từ nhiều cột thay vì một cột duy nhất.&lt;/p&gt;
&lt;p&gt;Ví dụ dễ hiểu là bảng quan hệ nhiều-nhiều, trong đó:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;studentId&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;courseId&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;có thể ghép lại thành khóa chính.&lt;/p&gt;
&lt;h3&gt;Indexing&lt;/h3&gt;
&lt;p&gt;Interviewer hỏi về:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Hash Index&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;B-tree Index&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Hash Index&lt;/h4&gt;
&lt;p&gt;Phù hợp với các truy vấn equality kiểu:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sql&quot;&gt;where email = &apos;a@example.com&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nó không mạnh cho range query.&lt;/p&gt;
&lt;h4&gt;B-tree Index&lt;/h4&gt;
&lt;p&gt;Đây là kiểu index phổ biến hơn rất nhiều vì hỗ trợ tốt các truy vấn:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;=&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;#x3C;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;between&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;order by&lt;/code&gt; trong nhiều tình huống&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Vì sao không tự động index tất cả?&lt;/h3&gt;
&lt;p&gt;Đây là một câu hỏi rất backend và rất thực tế.&lt;/p&gt;
&lt;p&gt;Lý do là vì index không miễn phí. Nó tạo ra trade-off giữa read và write:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;nhiều index hơn thì đọc nhanh hơn trong một số truy vấn&lt;/li&gt;
&lt;li&gt;nhưng insert, update, delete sẽ tốn thêm chi phí để cập nhật index&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nói vui thì database cũng không phải thánh. Bạn không thể bảo nó &quot;anh vừa muốn đọc nhanh, vừa muốn ghi nhanh, vừa muốn ít tốn tài nguyên, em tự cân đối giúp anh nhé&quot;.&lt;/p&gt;
&lt;h2&gt;7. Session pooling và Supabase&lt;/h2&gt;
&lt;p&gt;Do trong CV tôi có đề cập đến &lt;strong&gt;Supabase&lt;/strong&gt;, và tôi follow-up về vấn đề session pooling của Supabase, interviewer hỏi tiếp về connection pooling:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Backend nên tối ưu thế nào để hạn chế session?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Đây là câu hỏi chạm thẳng vào việc xây dựng ứng dụng thật.&lt;/p&gt;
&lt;h3&gt;Hướng suy nghĩ đúng&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;không mở kết nối database bừa bãi&lt;/li&gt;
&lt;li&gt;tận dụng connection pool hợp lý&lt;/li&gt;
&lt;li&gt;giảm các query không cần thiết&lt;/li&gt;
&lt;li&gt;batch query nếu phù hợp&lt;/li&gt;
&lt;li&gt;cache ở nơi thích hợp&lt;/li&gt;
&lt;li&gt;tránh để mỗi request tạo ra một đống session mới&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Điểm interviewer muốn thấy không chỉ là &quot;biết pooling là gì&quot;, mà là hiểu cách thiết kế backend sao cho tiết kiệm connection và ổn định hơn.&lt;/p&gt;
&lt;h2&gt;8. Coding: kiểm tra chuỗi ngoặc bằng stack&lt;/h2&gt;
&lt;p&gt;Phần code là một bài quen thuộc:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;&quot;{[()]}&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yêu cầu là kiểm tra chuỗi ngoặc có hợp lệ hay không.&lt;/p&gt;
&lt;h3&gt;Ý tưởng&lt;/h3&gt;
&lt;p&gt;Dùng &lt;strong&gt;stack&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;gặp ngoặc mở thì push vào stack&lt;/li&gt;
&lt;li&gt;gặp ngoặc đóng thì pop phần tử trên cùng ra để so sánh&lt;/li&gt;
&lt;li&gt;nếu mismatch hoặc stack rỗng quá sớm thì invalid&lt;/li&gt;
&lt;li&gt;đi hết chuỗi mà stack rỗng thì valid&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Ví dụ C#&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-csharp&quot;&gt;public static bool IsValid(string input)
{
    var stack = new Stack&amp;#x3C;char&gt;();

    foreach (var ch in input)
    {
        if (ch == &apos;(&apos; || ch == &apos;[&apos; || ch == &apos;{&apos;)
        {
            stack.Push(ch);
            continue;
        }

        if (stack.Count == 0)
        {
            return false;
        }

        var top = stack.Pop();

        var isMismatch =
            (ch == &apos;)&apos; &amp;#x26;&amp;#x26; top != &apos;(&apos;) ||
            (ch == &apos;]&apos; &amp;#x26;&amp;#x26; top != &apos;[&apos;) ||
            (ch == &apos;}&apos; &amp;#x26;&amp;#x26; top != &apos;{&apos;);

        if (isMismatch)
        {
            return false;
        }
    }

    return stack.Count == 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Vì sao bài này hay xuất hiện?&lt;/h3&gt;
&lt;p&gt;Vì nó kiểm tra được nhiều thứ cùng lúc:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;hiểu stack hay không&lt;/li&gt;
&lt;li&gt;xử lý condition branch có gọn không&lt;/li&gt;
&lt;li&gt;có quên edge case không&lt;/li&gt;
&lt;li&gt;có giữ bình tĩnh khi code live không&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;9. Tôi học được gì từ buổi phỏng vấn này?&lt;/h2&gt;
&lt;p&gt;Sau khi nhìn lại, tôi thấy buổi phỏng vấn này phản ánh khá rõ hình mẫu của một backend candidate mà doanh nghiệp mong đợi.&lt;/p&gt;
&lt;h3&gt;Không chỉ code&lt;/h3&gt;
&lt;p&gt;Bạn cần có khả năng nói về:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;dự án mình từng làm&lt;/li&gt;
&lt;li&gt;vai trò thực tế trong team&lt;/li&gt;
&lt;li&gt;cách giao tiếp và phối hợp&lt;/li&gt;
&lt;li&gt;cách nhìn hệ thống từ infra đến database&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Không chỉ thuộc định nghĩa&lt;/h3&gt;
&lt;p&gt;Nhiều câu hỏi không dừng ở mức &quot;định nghĩa X là gì&quot; mà đi tiếp đến:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;dùng trong thực tế ra sao&lt;/li&gt;
&lt;li&gt;trade-off là gì&lt;/li&gt;
&lt;li&gt;nếu gặp constraint thì tối ưu thế nào&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Không chỉ biết framework&lt;/h3&gt;
&lt;p&gt;Ở một mức nào đó, framework chỉ là lớp áo. Bên dưới vẫn là:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;process&lt;/li&gt;
&lt;li&gt;thread&lt;/li&gt;
&lt;li&gt;memory&lt;/li&gt;
&lt;li&gt;data structure&lt;/li&gt;
&lt;li&gt;networking&lt;/li&gt;
&lt;li&gt;database&lt;/li&gt;
&lt;li&gt;problem solving&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Đó mới là phần xương sống.&lt;/p&gt;
&lt;h2&gt;10. Những chủ đề tôi nên ôn lại sau buổi hôm nay&lt;/h2&gt;
&lt;p&gt;Sau buổi này, tôi muốn ôn lại kỹ hơn các mảng sau:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;process, thread, context switching, memory model&lt;/li&gt;
&lt;li&gt;ArrayList và LinkedList theo đúng bản chất cấu trúc dữ liệu&lt;/li&gt;
&lt;li&gt;DNS, TLS, reverse proxy, tunnel&lt;/li&gt;
&lt;li&gt;PostgreSQL indexing strategy&lt;/li&gt;
&lt;li&gt;connection pooling và giới hạn session trong backend service&lt;/li&gt;
&lt;li&gt;các bài stack / queue / string parsing kiểu phỏng vấn&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Kết&lt;/h2&gt;
&lt;p&gt;Tôi thích những buổi phỏng vấn kiểu này vì nó cho mình thấy rất rõ một điều: backend không phải chỉ là viết API rồi chờ frontend gọi. Một backend engineer tốt cần có nền tảng CS, tư duy hệ thống, hiểu networking, database và cả cách trao đổi với con người.&lt;/p&gt;
&lt;p&gt;Buổi technical round NAB batch 18-2 là một lời nhắc khá rõ rằng hành trình học backend vẫn còn rộng hơn nhiều so với những gì nằm trong một framework cụ thể.&lt;/p&gt;
&lt;p&gt;Và vâng, bài stack ngoặc kia đúng là kiểu bài &quot;nhìn hiền nhưng dễ làm tay run&quot; nếu bị nhìn chằm chằm trong lúc code.&lt;/p&gt;</content:encoded><h:img src="/_astro/background.DibZQbS-.jpg"/><enclosure url="/_astro/background.DibZQbS-.jpg"/></item><item><title>Cheatsheet combo 9Router cho daily use</title><link>https://astro-pure.js.org/vi/blog/9router-combo-cheatsheet</link><guid isPermaLink="true">https://astro-pure.js.org/vi/blog/9router-combo-cheatsheet</guid><description>Một cheatsheet thực chiến để chọn đúng combo 9Router mỗi ngày cho code, reasoning, review, design và vision.</description><pubDate>Mon, 16 Mar 2026 08:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import { Aside, Tabs, TabItem, Steps, Collapse } from &apos;astro-pure/user&apos;&lt;/p&gt;
&lt;h2&gt;Vì sao tôi cần một cheatsheet combo?&lt;/h2&gt;
&lt;p&gt;Khi số lượng model tăng lên, vấn đề không còn là “model nào mạnh nhất” mà là &lt;strong&gt;model nào hợp vai nhất cho từng việc&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Với 9Router, mình không muốn mỗi lần làm việc lại phải ngồi nhớ:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;combo nào hợp để code nhanh&lt;/li&gt;
&lt;li&gt;combo nào hợp để nghĩ sâu&lt;/li&gt;
&lt;li&gt;combo nào hợp để review&lt;/li&gt;
&lt;li&gt;combo nào hợp để đọc ảnh hoặc screenshot&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Bài này là bản ghi chú thực chiến để &lt;strong&gt;mở lên và chọn combo trong vài giây&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;Cách tôi chia combo&lt;/h2&gt;
&lt;h2&gt;Bản đồ chọn nhanh&lt;/h2&gt;
&lt;h2&gt;1. &lt;code&gt;coding-light&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Dùng khi&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;code thường ngày&lt;/li&gt;
&lt;li&gt;CRUD&lt;/li&gt;
&lt;li&gt;sửa bug vừa&lt;/li&gt;
&lt;li&gt;scaffold nhanh&lt;/li&gt;
&lt;li&gt;refactor nhẹ&lt;/li&gt;
&lt;li&gt;agent edit code liên tục&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Tính cách của combo này&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Đây là combo &lt;strong&gt;coder-first&lt;/strong&gt;. Mục tiêu là viết code nhanh, ổn định, không kéo các model thiên reasoning vào làm task bị “nặng đầu” không cần thiết.&lt;/p&gt;
&lt;h3&gt;Models&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;qw/qwen3-coder-plus&lt;/code&gt; — chủ lực code, cân bằng tốt giữa chất lượng và tốc độ&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kr/qwen3-coder-next&lt;/code&gt; — hợp agent coding, mạnh trong flow nhiều bước&lt;/li&gt;
&lt;li&gt;&lt;code&gt;if/qwen3-coder-plus&lt;/code&gt; — backup coder cùng họ tư duy với Qwen coder&lt;/li&gt;
&lt;li&gt;&lt;code&gt;qw/qwen3-coder-flash&lt;/code&gt; — nhanh nhất nhóm, hợp patch nhỏ và việc ngắn&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Câu thần chú&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Code bình thường, không cần triết học, cứ &lt;code&gt;coding-light&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;2. &lt;code&gt;coding-hard&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Dùng khi&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;feature khó&lt;/li&gt;
&lt;li&gt;refactor nhiều file&lt;/li&gt;
&lt;li&gt;bug logic khó&lt;/li&gt;
&lt;li&gt;task vừa cần code vừa cần nghĩ&lt;/li&gt;
&lt;li&gt;agent phải plan rồi mới sửa&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Tính cách của combo này&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Đây là combo &lt;strong&gt;engineering mode&lt;/strong&gt;. Không chỉ viết code, nó còn đủ não để suy nghĩ trước khi ra patch.&lt;/p&gt;
&lt;h3&gt;Models&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;qw/qwen3-coder-plus&lt;/code&gt; — người viết code chính&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kr/claude-sonnet-4.5&lt;/code&gt; — planner/reviewer, mạnh ở cấu trúc và giải thích&lt;/li&gt;
&lt;li&gt;&lt;code&gt;if/deepseek-v3.2&lt;/code&gt; — reasoning phụ trợ, nối logic khá ổn&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kr/qwen3-coder-next&lt;/code&gt; — coder bổ sung, hợp task kéo dài nhiều bước&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Câu thần chú&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Code khó, nhiều bước, cần vừa làm vừa nghĩ → &lt;code&gt;coding-hard&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;3. &lt;code&gt;reasoning&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Dùng khi&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;tìm root cause&lt;/li&gt;
&lt;li&gt;debug rất khó&lt;/li&gt;
&lt;li&gt;phân tích log dài&lt;/li&gt;
&lt;li&gt;tranh luận giải pháp&lt;/li&gt;
&lt;li&gt;thuật toán hoặc luồng logic phức tạp&lt;/li&gt;
&lt;li&gt;chưa muốn code ngay&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Tính cách của combo này&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Đây là combo dành cho những lúc bạn cần nói:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Khoan, chưa sửa. Ngồi xuống và nghĩ đã.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Models&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;if/deepseek-r1&lt;/code&gt; — đào sâu logic, rất hợp tìm nguyên nhân gốc&lt;/li&gt;
&lt;li&gt;&lt;code&gt;if/kimi-k2&lt;/code&gt; — giữ context dài, tổng hợp được nhiều thông tin&lt;/li&gt;
&lt;li&gt;&lt;code&gt;if/qwen3-max&lt;/code&gt; — reasoning cân bằng, đa dụng, dễ giao việc&lt;/li&gt;
&lt;li&gt;&lt;code&gt;if/qwen3-235b-a22b-thinking-2507&lt;/code&gt; — thinker chuyên sâu, hợp phản biện và nghĩ dai&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Câu thần chú&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Bài toán chưa rõ nguyên nhân thì đừng chạm code, dùng &lt;code&gt;reasoning&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Chọn &lt;code&gt;reasoning&lt;/code&gt; trước nếu bạn đang ở một trong các tình huống sau:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Có nhiều giả thuyết nhưng chưa biết giả thuyết nào đúng&lt;/li&gt;
&lt;li&gt;Đã sửa vài lần mà bug vẫn quay lại&lt;/li&gt;
&lt;li&gt;Log rất dài, dính nhiều service hoặc nhiều tầng&lt;/li&gt;
&lt;li&gt;Bạn muốn mô hình phân tích trước khi đụng vào code&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;4. &lt;code&gt;architect&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Dùng khi&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;viết spec&lt;/li&gt;
&lt;li&gt;đề xuất kiến trúc&lt;/li&gt;
&lt;li&gt;chia module hoặc service&lt;/li&gt;
&lt;li&gt;chọn pattern&lt;/li&gt;
&lt;li&gt;viết doc, proposal, design note&lt;/li&gt;
&lt;li&gt;so sánh phương án&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Tính cách của combo này&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Đây là combo dành cho &lt;strong&gt;design và diễn đạt&lt;/strong&gt;. Nó không nhằm ra patch nhanh, mà nhằm ra quyết định tốt và viết ra tài liệu dễ đọc.&lt;/p&gt;
&lt;h3&gt;Models&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;kr/claude-sonnet-4.5&lt;/code&gt; — viết mạch lạc, cấu trúc đẹp, rất hợp design/spec&lt;/li&gt;
&lt;li&gt;&lt;code&gt;if/kimi-k2&lt;/code&gt; — giữ context dài, tổng hợp tài liệu tốt&lt;/li&gt;
&lt;li&gt;&lt;code&gt;if/qwen3-max&lt;/code&gt; — cân bằng giữa tư duy và tính thực dụng&lt;/li&gt;
&lt;li&gt;&lt;code&gt;if/deepseek-r1&lt;/code&gt; — phản biện logic, soi lỗ hổng kiến trúc&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Câu thần chú&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Viết spec, design, proposal hoặc architecture note → &lt;code&gt;architect&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;5. &lt;code&gt;eazy&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Dùng khi&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;hỏi nhanh&lt;/li&gt;
&lt;li&gt;transform text&lt;/li&gt;
&lt;li&gt;sửa snippet ngắn&lt;/li&gt;
&lt;li&gt;brainstorm nhẹ&lt;/li&gt;
&lt;li&gt;chat thường ngày&lt;/li&gt;
&lt;li&gt;task nhỏ nhưng nhiều&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Tính cách của combo này&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Đây là combo &lt;strong&gt;fast lane&lt;/strong&gt;. Không phải lúc nào cũng cần gọi dàn não lớn ra họp. Nhiều việc chỉ cần một combo nhanh, gọn, đủ thông minh là xong.&lt;/p&gt;
&lt;h3&gt;Models&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gc/gemini-3-flash-preview&lt;/code&gt; — rất nhanh, hợp hỏi đáp và task thường ngày&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kr/claude-haiku-4.5&lt;/code&gt; — gọn, nhanh, ổn cho text và general chat&lt;/li&gt;
&lt;li&gt;&lt;code&gt;if/deepseek-v3.2&lt;/code&gt; — nhanh nhưng vẫn có não, hợp task hơi kỹ thuật&lt;/li&gt;
&lt;li&gt;&lt;code&gt;qw/qwen3-coder-flash&lt;/code&gt; — nhanh cho code snippet hoặc patch nhỏ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Câu thần chú&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Việc lặt vặt, cần tốc độ, không cần overkill → &lt;code&gt;eazy&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;6. &lt;code&gt;vision&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Dùng khi&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;đọc screenshot lỗi&lt;/li&gt;
&lt;li&gt;phân tích UI&lt;/li&gt;
&lt;li&gt;xem diagram&lt;/li&gt;
&lt;li&gt;ảnh kèm text&lt;/li&gt;
&lt;li&gt;nhìn giao diện rồi suy ra flow hoặc code&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Tính cách của combo này&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Đây là combo cho mọi thứ có yếu tố hình ảnh. Khi có screenshot, UI, sơ đồ hoặc ảnh chụp lỗi, dùng đúng combo vision sẽ giúp model bớt đoán mò.&lt;/p&gt;
&lt;h3&gt;Models&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;if/qwen3-vl-plus&lt;/code&gt; — vision chủ lực, hợp ảnh và phân tích kỹ thuật&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gc/gemini-3-pro-preview&lt;/code&gt; — multimodal mạnh, hợp ảnh + reasoning&lt;/li&gt;
&lt;li&gt;&lt;code&gt;qw/vision-model&lt;/code&gt; — fallback vision, thêm một góc nhìn dự phòng&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Câu thần chú&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Có ảnh thì đừng ép combo text-only đoán mò. Cứ &lt;code&gt;vision&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;7. &lt;code&gt;review&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Dùng khi&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;review PR&lt;/li&gt;
&lt;li&gt;audit code&lt;/li&gt;
&lt;li&gt;phản biện giải pháp&lt;/li&gt;
&lt;li&gt;check edge case&lt;/li&gt;
&lt;li&gt;soi bug tiềm ẩn&lt;/li&gt;
&lt;li&gt;verify output từ combo khác&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Tính cách của combo này&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Đây là combo dành cho việc &lt;strong&gt;ngồi soi&lt;/strong&gt;. Không phải tạo ra lời giải đầu tiên, mà là kiểm tra xem lời giải đó có gì đáng nghi hay không.&lt;/p&gt;
&lt;h3&gt;Models&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;kr/claude-sonnet-4.5&lt;/code&gt; — review mạch lạc, nhận xét rõ ràng, dễ đọc&lt;/li&gt;
&lt;li&gt;&lt;code&gt;if/deepseek-r1&lt;/code&gt; — soi logic sâu, hợp tìm lỗi ẩn&lt;/li&gt;
&lt;li&gt;&lt;code&gt;if/qwen3-max&lt;/code&gt; — reviewer cân bằng, thực dụng&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Câu thần chú&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Đã có lời giải rồi, giờ cần soi nó → &lt;code&gt;review&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Workflow thực chiến&lt;/h2&gt;
&lt;h3&gt;Case 1: Làm feature backend&lt;/h3&gt;
&lt;p&gt;Bắt đầu với &lt;code&gt;coding-light&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Nếu task bắt đầu có một trong các dấu hiệu sau:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;nhiều file&lt;/li&gt;
&lt;li&gt;flow phức tạp&lt;/li&gt;
&lt;li&gt;agent cần plan trước&lt;/li&gt;
&lt;li&gt;sửa một chỗ kéo theo ba chỗ khác&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;thì chuyển lên &lt;code&gt;coding-hard&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Case 2: Bug khó&lt;/h3&gt;
&lt;p&gt;Bắt đầu với &lt;code&gt;reasoning&lt;/code&gt; để tìm nguyên nhân gốc.&lt;/p&gt;
&lt;p&gt;Sau khi đã rõ hướng sửa, chuyển sang &lt;code&gt;coding-hard&lt;/code&gt; để ra patch. Cách này thường đỡ hơn rất nhiều so với kiểu &quot;sửa theo cảm giác&quot;.&lt;/p&gt;
&lt;h3&gt;Case 3: Viết tài liệu kiến trúc&lt;/h3&gt;
&lt;p&gt;Dùng &lt;code&gt;architect&lt;/code&gt; để ra hướng tiếp cận, lựa chọn pattern và viết spec.&lt;/p&gt;
&lt;p&gt;Khi xong bản đầu tiên, ném qua &lt;code&gt;review&lt;/code&gt; để tự phản biện.&lt;/p&gt;
&lt;h3&gt;Case 4: Có screenshot hoặc ảnh&lt;/h3&gt;
&lt;p&gt;Bắt đầu bằng &lt;code&gt;vision&lt;/code&gt;. Sau khi đã hiểu ảnh hoặc flow UI, nếu cần sửa code thì chuyển sang &lt;code&gt;coding-light&lt;/code&gt; hoặc &lt;code&gt;coding-hard&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Case 5: Có code rồi nhưng chưa thật sự tin&lt;/h3&gt;
&lt;p&gt;Dùng &lt;code&gt;review&lt;/code&gt;. Đây là bước rất đáng giá khi bạn muốn check edge case, smell, hoặc rủi ro trước khi merge.&lt;/p&gt;
&lt;h2&gt;Bản pocket note&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;coding-light  = code thường ngày
coding-hard   = code khó, nhiều bước
reasoning     = nghĩ sâu, tìm root cause
architect     = spec, design, proposal
eazy          = hỏi nhanh, task nhỏ
vision        = ảnh, UI, screenshot
review        = soi lại lời giải / PR / edge case
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Kết luận&lt;/h2&gt;
&lt;p&gt;Mấu chốt không nằm ở việc model nào mạnh nhất, mà nằm ở việc &lt;strong&gt;đặt đúng model vào đúng vai&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Cheatsheet này giúp mình giảm thời gian do dự mỗi khi chọn combo:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;cần code nhanh thì không gọi nhầm thinker&lt;/li&gt;
&lt;li&gt;cần root cause thì không vội quăng vào coder&lt;/li&gt;
&lt;li&gt;cần review thì không dùng combo chat thường ngày&lt;/li&gt;
&lt;li&gt;có ảnh thì không bắt model text-only đoán từ không khí&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nếu bạn cũng đang dùng nhiều combo trong 9Router, hãy coi đây như một &lt;strong&gt;playbook mini&lt;/strong&gt;: mở lên, chọn đúng lane, rồi làm việc.&lt;/p&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>9Router và headless coder agent</title><link>https://astro-pure.js.org/vi/blog/9router-headless-coder-agents</link><guid isPermaLink="true">https://astro-pure.js.org/vi/blog/9router-headless-coder-agents</guid><description>Cách hiểu 9Router, headless coder agent, và quy trình kết nối thực tế với VS Code.</description><pubDate>Sun, 15 Mar 2026 14:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import { Aside, Steps, Tabs, TabItem, Collapse } from &apos;astro-pure/user&apos;
import { GithubCard, LinkPreview } from &apos;astro-pure/advanced&apos;&lt;/p&gt;
&lt;h2&gt;Từ AI Supporting sang AI-Driven&lt;/h2&gt;
&lt;p&gt;Rất nhiều developer bắt đầu với kiểu dùng AI như một &lt;strong&gt;trợ lý gõ code&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GitHub Copilot để autocomplete&lt;/li&gt;
&lt;li&gt;ChatGPT để hỏi logic&lt;/li&gt;
&lt;li&gt;đôi lúc paste error vào chat rồi cầu nguyện&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Kiểu này mình gọi là &lt;strong&gt;AI Supporting&lt;/strong&gt;: dev vẫn suy nghĩ chính, AI chỉ hỗ trợ một phần nhỏ.&lt;/p&gt;
&lt;p&gt;Khi chuyển sang &lt;strong&gt;AI-Driven&lt;/strong&gt;, vai trò của AI đổi hẳn:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;đọc codebase&lt;/li&gt;
&lt;li&gt;đề xuất kế hoạch&lt;/li&gt;
&lt;li&gt;sửa nhiều file&lt;/li&gt;
&lt;li&gt;chạy command&lt;/li&gt;
&lt;li&gt;lặp lại cho đến khi task hoàn thành&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Đó là lý do các tool như &lt;strong&gt;Cline&lt;/strong&gt;, &lt;strong&gt;Continue Agent&lt;/strong&gt;, &lt;strong&gt;Codex CLI&lt;/strong&gt;, hay các IDE như &lt;strong&gt;Kiro&lt;/strong&gt; bắt đầu được chú ý mạnh. Chúng không chỉ viết vài dòng code cho đẹp đội hình. Chúng bắt đầu tham gia vào cả workflow phát triển phần mềm.&lt;/p&gt;
&lt;h2&gt;Headless coder agent là gì?&lt;/h2&gt;
&lt;p&gt;Khi nói &quot;headless coder agent&quot;, mình đang nói tới nhóm công cụ có thể nhận một yêu cầu tự nhiên như:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Add Redis caching for the product API and update tests
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;rồi tự:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;đọc repo&lt;/li&gt;
&lt;li&gt;tìm file liên quan&lt;/li&gt;
&lt;li&gt;sửa code&lt;/li&gt;
&lt;li&gt;chạy build hoặc test&lt;/li&gt;
&lt;li&gt;báo lại những gì đã thay đổi&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Điểm quan trọng là: &lt;strong&gt;agent không phải LLM&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Một hệ thống AI coding thường có 3 lớp:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;IDE / CLI
  ↓
Agent
  ↓
LLM hoặc Router
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Trong đó:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Agent&lt;/strong&gt; là thứ điều phối hành động&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLM&lt;/strong&gt; là bộ não sinh ra reasoning và code&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Router&lt;/strong&gt; là lớp định tuyến model, fallback quota, gom nhiều provider vào một endpoint&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;9Router là gì?&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/decolua/9router&quot;&gt;9Router&lt;/a&gt; là một &lt;strong&gt;local AI router&lt;/strong&gt; cung cấp &lt;strong&gt;OpenAI-compatible API&lt;/strong&gt; tại local host, để các tool như Cline, Codex, Copilot, Cursor, OpenCode hay OpenClaw có thể gọi vào một endpoint duy nhất.&lt;/p&gt;
&lt;p&gt;Theo README của project, luồng quick start cơ bản là:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;chạy 9Router local&lt;/li&gt;
&lt;li&gt;dashboard mở ở &lt;code&gt;http://localhost:20128&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;API endpoint là &lt;code&gt;http://localhost:20128/v1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;kết nối provider trong dashboard&lt;/li&gt;
&lt;li&gt;dùng endpoint đó trong tool AI của bạn&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Điểm hấp dẫn nhất của 9Router là ý tưởng:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;một endpoint duy nhất&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;nhiều provider phía sau&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;combo fallback khi hết quota hoặc lỗi&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Vì sao lớp router này đáng giá?&lt;/h2&gt;
&lt;p&gt;Nếu không có router, workflow thường trông như sau:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Hết quota Claude
→ đổi extension
→ đổi provider
→ đổi API key
→ đổi model
→ mất context
→ hơi điên
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Còn nếu có router:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;VS Code / Cline
  ↓
9Router
  ↓
Claude / Gemini / Qwen / DeepSeek / ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;thì IDE chỉ biết một model alias hoặc một combo. Khi provider A hết quota, router có thể rơi xuống provider B.&lt;/p&gt;
&lt;h2&gt;Smart routing của 9Router thực sự là gì?&lt;/h2&gt;
&lt;p&gt;Đây là chỗ nhiều người mới rất dễ hiểu nhầm.&lt;/p&gt;
&lt;p&gt;Trong trải nghiệm thực tế với UI hiện tại của 9Router:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Providers&lt;/strong&gt; là nơi kết nối tài khoản hoặc credential&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Proxy Pools&lt;/strong&gt; là proxy mạng, không phải routing logic cho model&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Combos&lt;/strong&gt; mới là nơi bạn tạo chuỗi &lt;strong&gt;fallback / priority&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nói ngắn gọn:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Proxy Pools&lt;/strong&gt;: HTTP/SOCKS proxy&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Combos&lt;/strong&gt;: ghép nhiều model theo thứ tự ưu tiên&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Một combo kiểu &lt;code&gt;code&lt;/code&gt; có thể trông như sau:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;1. kr/claude-sonnet-4.5
2. kr/qwen3-coder-next
3. qw/qwen3-coder-plus
4. qw/qwen3-coder-flash
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Khi đó request sẽ thử model đầu tiên trước. Nếu fail, timeout, hoặc hết quota, router sẽ rơi xuống model sau.&lt;/p&gt;
&lt;h2&gt;Một lưu ý rất quan trọng về &quot;smart&quot;&lt;/h2&gt;
&lt;p&gt;Tính đến &lt;strong&gt;tháng 3/2026&lt;/strong&gt;, phần public docs của 9Router mô tả rất rõ:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OpenAI-compatible API&lt;/li&gt;
&lt;li&gt;smart fallback&lt;/li&gt;
&lt;li&gt;multi-provider routing&lt;/li&gt;
&lt;li&gt;combo-based routing&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nhưng mình &lt;strong&gt;chưa thấy tài liệu chính thức public nào nói rõ&lt;/strong&gt; rằng 9Router đang tự phân loại prompt theo ngữ nghĩa kiểu:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;prompt code → Qwen&lt;/li&gt;
&lt;li&gt;prompt reasoning → Claude&lt;/li&gt;
&lt;li&gt;prompt ngắn → Gemini&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thứ có thật và dùng được ngay là:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;fallback theo thứ tự&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;chia combo theo use case&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;map Plan/Act trong agent sang các combo khác nhau&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Đây là khác biệt nhỏ nhưng quan trọng. Đừng kỳ vọng một &quot;LLM thần thánh tự đoán mọi thứ&quot;. Hãy cấu hình theo ý đồ của mình.&lt;/p&gt;
&lt;h2&gt;Cline và Continue: khác nhau thế nào?&lt;/h2&gt;
&lt;p&gt;Cả &lt;strong&gt;Cline&lt;/strong&gt; lẫn &lt;strong&gt;Continue&lt;/strong&gt; đều có thể đóng vai trò AI coding assistant/agent trong VS Code, nhưng triết lý dùng hơi khác nhau.&lt;/p&gt;
&lt;h3&gt;Cline&lt;/h3&gt;
&lt;p&gt;Cline thiên về &lt;strong&gt;agentic workflow&lt;/strong&gt; hơn:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;đọc file&lt;/li&gt;
&lt;li&gt;sửa file&lt;/li&gt;
&lt;li&gt;chạy terminal&lt;/li&gt;
&lt;li&gt;có tư duy &lt;code&gt;Plan&lt;/code&gt; và &lt;code&gt;Act&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;hỗ trợ &lt;strong&gt;OpenAI-compatible API&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Điểm này khiến nó hợp với 9Router một cách gần như tự nhiên.&lt;/p&gt;
&lt;h3&gt;Continue&lt;/h3&gt;
&lt;p&gt;Continue linh hoạt hơn ở vai trò &lt;strong&gt;AI toolbox trong IDE&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;autocomplete&lt;/li&gt;
&lt;li&gt;edit&lt;/li&gt;
&lt;li&gt;chat&lt;/li&gt;
&lt;li&gt;agent mode&lt;/li&gt;
&lt;li&gt;cấu hình nhiều provider và model khác nhau&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nếu bạn muốn một hệ sinh thái AI trong VS Code đa dạng hơn, Continue rất đáng thử. Nếu bạn muốn cảm giác &quot;AI làm task rõ ràng, từng bước&quot;, Cline thường trực diện hơn.&lt;/p&gt;
&lt;h2&gt;Kiro IDE đứng ở đâu trong bức tranh này?&lt;/h2&gt;
&lt;p&gt;Kiro là một &lt;strong&gt;AI-native IDE&lt;/strong&gt; xây trên &lt;strong&gt;Code OSS&lt;/strong&gt;, nhấn mạnh vào &lt;strong&gt;spec-driven development&lt;/strong&gt;. Theo tài liệu của họ, Kiro muốn đưa AI vào quy trình có cấu trúc hơn:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;requirements&lt;/li&gt;
&lt;li&gt;design&lt;/li&gt;
&lt;li&gt;tasks&lt;/li&gt;
&lt;li&gt;code&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Điểm này khiến Kiro khác với kiểu &quot;vibe coding rồi sửa sau&quot;. Nó cố gắng kéo AI từ trạng thái &quot;viết code nhanh&quot; sang &quot;tham gia cả vòng đời triển khai&quot;.&lt;/p&gt;
&lt;p&gt;Điều thú vị là: ngay cả khi bạn &lt;strong&gt;không dùng Kiro&lt;/strong&gt;, bạn vẫn có thể học được từ triết lý đó và áp dụng vào VS Code + Cline + 9Router:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;combo &lt;code&gt;plan&lt;/code&gt; cho reasoning&lt;/li&gt;
&lt;li&gt;combo &lt;code&gt;code&lt;/code&gt; cho implementation&lt;/li&gt;
&lt;li&gt;combo &lt;code&gt;fast&lt;/code&gt; cho hỏi nhanh&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Kiến trúc thực chiến mình khuyên dùng&lt;/h2&gt;
&lt;p&gt;Nếu bạn đang ở VS Code và muốn đi từ dễ tới mạnh, kiến trúc này khá hợp lý:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;VS Code
  ├─ Cline
  ├─ Continue (optional)
  └─ Copilot (optional)
        ↓
      9Router
        ↓
   Combos / Providers
        ↓
Claude / Qwen / Gemini / DeepSeek / ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Tư duy ở đây là:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cline&lt;/strong&gt; cho task execution&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Continue&lt;/strong&gt; cho chat/edit linh hoạt&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;9Router&lt;/strong&gt; cho fallback và thống nhất endpoint&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Cách nối Cline với 9Router&lt;/h2&gt;
&lt;p&gt;Ví dụ cấu hình trong Cline:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Provider: OpenAI Compatible
Base URL: http://localhost:20128/v1
API Key: &amp;#x3C;your-9router-key&gt;
Model ID: code
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sau đó Cline sẽ không cần biết model thật ở phía sau là Claude, Qwen hay Gemini. Nó chỉ biết một cái tên như &lt;code&gt;code&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Gợi ý 3 combo thực dụng&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;plan
1. kr/claude-sonnet-4.5
2. kr/deepseek-3.2
3. qw/qwen3-coder-plus

code
1. kr/qwen3-coder-next
2. qw/qwen3-coder-plus
3. qw/qwen3-coder-flash

fast
1. cline/gemini-3.1-flash-lite-preview
2. qw/qwen3-coder-flash
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Tận dụng Plan / Act trong Cline&lt;/h3&gt;
&lt;p&gt;Nếu bạn dùng Cline, đây là pattern rất ngon:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Plan mode → plan
Act mode  → code
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ý tưởng:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;khi cần suy nghĩ kiến trúc hoặc lập kế hoạch → dùng model reasoning mạnh&lt;/li&gt;
&lt;li&gt;khi cần sửa code hàng loạt hoặc generate code → dùng model coding nhanh và rẻ hơn&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Continue có nối với 9Router được không?&lt;/h2&gt;
&lt;p&gt;Có, miễn là workflow của bạn dùng &lt;strong&gt;OpenAI-compatible endpoint&lt;/strong&gt; hoặc provider phù hợp. Ý tưởng giống hệt:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;trỏ tới endpoint local của 9Router&lt;/li&gt;
&lt;li&gt;dùng model alias hoặc combo từ router&lt;/li&gt;
&lt;li&gt;để router xử lý fallback và quota&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nếu bạn thích Continue vì chat/edit/autocomplete đa dạng hơn, router vẫn có giá trị như cũ: gom mọi thứ về một endpoint.&lt;/p&gt;
&lt;h2&gt;Nên viết một bài hay nhiều bài?&lt;/h2&gt;
&lt;p&gt;Mình nghiêng về &lt;strong&gt;series 3 bài&lt;/strong&gt; thay vì một bài all-in-one.&lt;/p&gt;
&lt;h3&gt;Bài 1 — bài nền tảng&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;9Router và headless coder agent&lt;/strong&gt;
Tập trung giải thích:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AI Supporting vs AI-Driven&lt;/li&gt;
&lt;li&gt;agent là gì&lt;/li&gt;
&lt;li&gt;router là gì&lt;/li&gt;
&lt;li&gt;vì sao cần 9Router&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Bài 2 — bài thực hành&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Kết nối Cline/Continue với 9Router trên VS Code&lt;/strong&gt;
Tập trung vào:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;cách cấu hình endpoint&lt;/li&gt;
&lt;li&gt;model alias&lt;/li&gt;
&lt;li&gt;combo&lt;/li&gt;
&lt;li&gt;fallback&lt;/li&gt;
&lt;li&gt;lỗi thường gặp&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Bài 3 — bài chiến lược&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Thiết kế workflow AI coding không lệ thuộc quota&lt;/strong&gt;
Tập trung vào:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;plan/code/fast combo&lt;/li&gt;
&lt;li&gt;đổi model mà không đổi IDE&lt;/li&gt;
&lt;li&gt;cách phân vai reasoning và coding&lt;/li&gt;
&lt;li&gt;khi nào dùng Cline, Continue, Kiro&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Kết luận&lt;/h2&gt;
&lt;p&gt;Nếu phải tóm gọn toàn bộ câu chuyện trong một ý:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;9Router không phải AI, mà là lớp router giúp các AI coding tool sống sót khi quota và provider trở mặt như người yêu cũ.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Còn &lt;strong&gt;headless coder agent&lt;/strong&gt; là bước tiến từ kiểu dùng AI để autocomplete sang kiểu dùng AI để tham gia thật vào quy trình phát triển phần mềm.&lt;/p&gt;
&lt;p&gt;Với setup đúng, bạn có thể giữ nguyên:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IDE&lt;/li&gt;
&lt;li&gt;extension&lt;/li&gt;
&lt;li&gt;workflow&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;nhưng thay đổi hoàn toàn độ linh hoạt phía sau bằng một local router và vài combo hợp lý.&lt;/p&gt;
&lt;h2&gt;Tài liệu chính thức nên đọc thêm&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/decolua/9router&quot;&gt;9Router README&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.cline.bot/provider-config/openai-compatible&quot;&gt;Cline: OpenAI Compatible provider&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.continue.dev/ide-extensions/agent/quick-start&quot;&gt;Continue Agent Quick Start&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kiro.dev/faq/&quot;&gt;Kiro FAQ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kiro.dev/blog/introducing-kiro/&quot;&gt;Kiro: Introducing Kiro&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><h:img src="/_astro/thumbnail.Cx18cRmB.jpg"/><enclosure url="/_astro/thumbnail.Cx18cRmB.jpg"/></item><item><title>Chạy OpenClaw trên ZimaOS với Portainer</title><link>https://astro-pure.js.org/vi/blog/openclaw-zimaos-portainer</link><guid isPermaLink="true">https://astro-pure.js.org/vi/blog/openclaw-zimaos-portainer</guid><description>Cách mình triển khai OpenClaw trên ZimaOS bằng Portainer, những lỗi gặp phải, và Docker Compose stack cuối cùng.</description><pubDate>Sun, 15 Mar 2026 08:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import { Aside, Steps, Collapse } from &apos;astro-pure/user&apos;
import { GithubCard, LinkPreview } from &apos;astro-pure/advanced&apos;&lt;/p&gt;
&lt;h2&gt;Vì sao mình thử cái này&lt;/h2&gt;
&lt;p&gt;Mình muốn chạy OpenClaw trên máy ZimaOS bằng &lt;strong&gt;Portainer&lt;/strong&gt; với một Docker Compose stack duy nhất.&lt;/p&gt;
&lt;p&gt;Nghe thì đơn giản, nhưng ZimaOS thiên về &lt;strong&gt;container-centric&lt;/strong&gt; hơn nhiều so với một distro Linux đầy đủ. Trong thực tế, điều đó có nghĩa là kiểu setup thông thường — &quot;chạy script helper, tạo thư mục trên host, mount đường dẫn ngẫu nhiên dưới &lt;code&gt;/home/...&lt;/code&gt;&quot; — chính là lúc mọi thứ bắt đầu phiền phức.&lt;/p&gt;
&lt;p&gt;Nên bài viết này không phải giới thiệu OpenClaw chung chung. Đây là ghi chép thực tế về:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OpenClaw là gì&lt;/li&gt;
&lt;li&gt;vì sao flow cài đặt mặc định không phù hợp với môi trường của mình&lt;/li&gt;
&lt;li&gt;mình đã thay đổi gì cho ZimaOS + Portainer&lt;/li&gt;
&lt;li&gt;compose stack đã khiến gateway container khởi động thành công&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;OpenClaw là gì?&lt;/h2&gt;
&lt;p&gt;OpenClaw là một dự án coding agent mã nguồn mở với đường cài đặt Docker chính thức và container image prebuilt được publish trên GHCR.&lt;/p&gt;
&lt;p&gt;Tài liệu Docker chính thức mô tả setup xoay quanh:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;openclaw-gateway&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;openclaw-cli&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Điều này quan trọng, vì ngoài kia cũng có các image bên thứ ba và biến thể packaging downstream. Nếu bạn muốn giữ gần với upstream, hãy bắt đầu từ image chính thức và tài liệu chính thức.&lt;/p&gt;
&lt;h2&gt;Vấn đề: Flow Docker chính thức vs thực tế ZimaOS&lt;/h2&gt;
&lt;p&gt;Tài liệu chính thức giả định môi trường Docker nơi việc chạy helper scripts và lệnh onboarding là chấp nhận được.&lt;/p&gt;
&lt;p&gt;Điều đó ổn trên một máy Linux bình thường.&lt;/p&gt;
&lt;p&gt;Nhưng trên ZimaOS thì không vui lắm.&lt;/p&gt;
&lt;p&gt;Các ràng buộc của mình:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;không dùng bash setup flow&lt;/li&gt;
&lt;li&gt;không cài đặt command-line-first&lt;/li&gt;
&lt;li&gt;triển khai qua &lt;strong&gt;Portainer&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;tránh host bind mounts dễ hỏng khi có thể&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Điều này ngay lập tức đẩy mình sang một chiến lược khác.&lt;/p&gt;
&lt;h2&gt;Những gì mình tìm thấy trong repository&lt;/h2&gt;
&lt;p&gt;Khi kiểm tra repository và tài liệu chính thức, một điều trở nên rõ ràng: repo chứa nhiều file liên quan đến Docker, nhưng mô hình mental quan trọng thì đơn giản hơn vẻ ngoài.&lt;/p&gt;
&lt;p&gt;File compose chính là &lt;code&gt;docker-compose.yml&lt;/code&gt;, còn &lt;code&gt;docker-compose.extra.yml&lt;/code&gt; nên hiểu là lớp override gắn với setup flow.&lt;/p&gt;
&lt;p&gt;Với triển khai Portainer-first, bước thực tế là xây dựng một &lt;strong&gt;compose stack tự chứa duy nhất&lt;/strong&gt; bao gồm những phần bạn thực sự cần mà không phụ thuộc vào helper script.&lt;/p&gt;
&lt;p&gt;Flow Docker upstream vẫn nghiêng về onboarding và các bước CLI-oriented. Với môi trường NAS container-centric, điều đó tạo ma sát nhanh chóng. Mình chỉ muốn baseline ổn định tối thiểu trước: pull image, tạo stack, publish ports, và để gateway khởi động.
&lt;/p&gt;
&lt;h2&gt;Sai lầm đầu tiên&lt;/h2&gt;
&lt;p&gt;Bản năng đầu tiên của mình là tối ưu cho setup 9Router tương lai và chuẩn bị sẵn shared external Docker network.&lt;/p&gt;
&lt;p&gt;Trông có vẻ thông minh.&lt;/p&gt;
&lt;p&gt;Nhưng không phải.&lt;/p&gt;
&lt;p&gt;Ngay khi dùng external network trước khi network đó thực sự tồn tại, stack ngừng trơn tru. Thêm vào đó, mình vẫn chưa chạy 9Router, nên mình đang tối ưu kiến trúc sớm thay vì chỉ đơn giản là khiến OpenClaw khởi động.&lt;/p&gt;
&lt;p&gt;Bước đúng hơn là đơn giản hóa:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;bỏ dependency external-network&lt;/li&gt;
&lt;li&gt;dùng bridge network bình thường&lt;/li&gt;
&lt;li&gt;đưa &lt;code&gt;openclaw-gateway&lt;/code&gt; vào trạng thái khởi động ổn định trước&lt;/li&gt;
&lt;li&gt;hoãn tích hợp 9Router sang sau&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Compose Stack hoạt động tốt hơn&lt;/h2&gt;
&lt;p&gt;Đây là compose stack mình cuối cùng dùng làm baseline thực tế cho ZimaOS + Portainer:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;services:
  openclaw-gateway:
    image: ghcr.io/openclaw/openclaw:latest
    container_name: openclaw-gateway
    user: &quot;1000:1000&quot;
    environment:
      HOME: /home/node
      TERM: xterm-256color
      OPENCLAW_GATEWAY_TOKEN: &quot;ocw_change_this_to_a_long_random_token&quot;

    volumes:
      - openclaw-home:/home/node
      - openclaw-config:/home/node/.openclaw

    ports:
      - &quot;18789:18789&quot;
      - &quot;18790:18790&quot;

    init: true
    restart: unless-stopped

    command:
      - node
      - dist/index.js
      - gateway
      - --bind
      - lan
      - --port
      - &quot;18789&quot;

    networks:
      - ai-router

  openclaw-cli:
    image: ghcr.io/openclaw/openclaw:latest
    container_name: openclaw-cli
    user: &quot;1000:1000&quot;
    environment:
      HOME: /home/node
      TERM: xterm-256color
      OPENCLAW_GATEWAY_TOKEN: &quot;ocw_change_this_to_a-long-random-token&quot;

    volumes:
      - openclaw-home:/home/node
      - openclaw-config:/home/node/.openclaw

    network_mode: &quot;service:openclaw-gateway&quot;

    cap_drop:
      - NET_RAW
      - NET_ADMIN

    security_opt:
      - no-new-privileges:true

    profiles:
      - tools

networks:
  ai-router:
    driver: bridge

volumes:
  openclaw-home:
  openclaw-config:
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Vì sao phiên bản này hợp lý hơn&lt;/h2&gt;
&lt;p&gt;Một số lựa chọn ở đây là có chủ đích.&lt;/p&gt;
&lt;h3&gt;Chỉ dùng image chính thức&lt;/h3&gt;
&lt;p&gt;Image là:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;ghcr.io/openclaw/openclaw:latest
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Giữ triển khai đồng bộ với upstream thay vì lớp packaging bên thứ ba.&lt;/p&gt;
&lt;h3&gt;Named volumes thay vì host bind mounts&lt;/h3&gt;
&lt;p&gt;Với môi trường NAS container-first, named volumes đơn giản là ít phiền hơn. Chúng tránh được lớp vấn đề kinh điển &quot;đường dẫn này read-only&quot; hoặc &quot;sao thư mục host không tồn tại đúng cách script mong đợi?&quot;&lt;/p&gt;
&lt;h3&gt;Chưa dùng external network&lt;/h3&gt;
&lt;p&gt;Shared external network hữu ích sau này, đặc biệt khi muốn OpenClaw nói chuyện với container 9Router riêng qua service name ổn định.&lt;/p&gt;
&lt;p&gt;Nhưng trước đó, nó chỉ là thêm một thứ có thể fail.&lt;/p&gt;
&lt;h3&gt;Gateway trước, mọi thứ khác sau&lt;/h3&gt;
&lt;p&gt;Mục tiêu trước mắt không phải &quot;full agent workflow với onboarding hoàn hảo.&quot;&lt;/p&gt;
&lt;p&gt;Đơn giản hơn nhiều:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Stack có thể pull image chính thức, tạo container, publish ports, và đưa gateway vào trạng thái khởi động hợp lệ không?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Khi thấy stack tạo thành công và &lt;code&gt;openclaw-gateway&lt;/code&gt; ở trạng thái &lt;code&gt;starting&lt;/code&gt; với ports đã publish, đó đã là tiến bộ có ý nghĩa.&lt;/p&gt;
&lt;h2&gt;Lưu ý thật lòng&lt;/h2&gt;
&lt;p&gt;Đây là phần dễ giấu trong tutorial và tốt hơn nhiều nếu nói thẳng:&lt;/p&gt;
&lt;p&gt;Ngay cả khi container khởi động đúng, bạn vẫn có thể gặp bước authentication, pairing, hoặc onboarding sau đó.&lt;/p&gt;
&lt;p&gt;Đó không phải lỗi riêng của ZimaOS. Đó là một phần thực tế Docker hiện tại của dự án này.&lt;/p&gt;
&lt;h2&gt;Bước tiếp theo&lt;/h2&gt;
&lt;p&gt;Bước tiếp theo của mình sẽ là triển khai &lt;strong&gt;9Router&lt;/strong&gt; trong container riêng và kết nối OpenClaw với nó qua cấu hình provider tương thích OpenAI.&lt;/p&gt;
&lt;p&gt;Đó là loại setup mà shared Docker network thực sự trở nên hữu ích. Nhưng nên coi đó là &lt;strong&gt;phase hai&lt;/strong&gt; sau khi base stack đã ổn định.&lt;/p&gt;
&lt;h2&gt;Kết luận&lt;/h2&gt;
&lt;p&gt;Setup này dạy mình một điều hữu ích:&lt;/p&gt;
&lt;p&gt;Nhiều Docker tutorial giả định máy Linux bình thường với shell access, host paths ghi được, và kiên nhẫn cho helper scripts.&lt;/p&gt;
&lt;p&gt;ZimaOS thay đổi phương trình đó.&lt;/p&gt;
&lt;p&gt;Và chính vì vậy, một compose stack nhỏ, nhàm chán, đồng bộ upstream có thể giá trị hơn một setup &quot;feature-complete&quot; sụp đổ dưới các giả định môi trường.&lt;/p&gt;
&lt;p&gt;Nếu mục tiêu của bạn là thử nghiệm OpenClaw trên home server container-centric, hãy bắt đầu từ mức tối thiểu, chứng minh gateway khởi động được, rồi iterate từ đó.&lt;/p&gt;
&lt;p&gt;Con đường đó chậm hơn khoảng mười phút và nhanh hơn cho ba giờ tiếp theo.&lt;/p&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>Tips to improve concentration</title><link>https://astro-pure.js.org/vi/blog/improve-concentration</link><guid isPermaLink="true">https://astro-pure.js.org/vi/blog/improve-concentration</guid><description>Mindfulness, cognitive training, and a healthy lifestyle may help sharpen your focus.</description><pubDate>Sat, 10 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import { Aside } from &apos;astro-pure/user&apos;&lt;/p&gt;
&lt;p&gt;You&apos;re trying to concentrate, but your mind is wandering or you&apos;re easily distracted. What happened to the laser-sharp focus you once enjoyed? As we age, we tend to have more difficulty filtering out stimuli that are not relevant to the task at hand.&lt;/p&gt;
&lt;h2&gt;What&apos;s fogging up focus?&lt;/h2&gt;
&lt;p&gt;Like a computer that slows with use, the brain accumulates wear and tear that affects processing. This can be caused by a number of physiological stressors such as inflammation, injury to blood vessels (especially if you have high blood pressure), the buildup of abnormal proteins, and naturally occurring brain shrinkage.&lt;/p&gt;
&lt;p&gt;The following factors can also affect your concentration.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Underlying conditions.&lt;/strong&gt; Depression or sleep disorders (such as sleep apnea) can undermine your ability to concentrate. So can the effects of vision or hearing loss. You waste precious cognitive resources when you spend too much time trying to make out what&apos;s written on a page or just hear what someone is saying.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Medication side effects.&lt;/strong&gt; Some drugs, especially anticholinergics (such as treatments for incontinence, depression, or allergies), can slow processing speed and your ability to think clearly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Excessive drinking.&lt;/strong&gt; Having too much alcohol impairs thinking and causes interrupted sleep, which affects concentration.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Information overload.&lt;/strong&gt; We are bombarded with information from TVs, computers, and messages such as texts or emails. When there&apos;s too much material, it burdens our filtering system and it&apos;s easy to get distracted.&lt;/p&gt;
&lt;h2&gt;Strategies to stay focused&lt;/h2&gt;
&lt;p&gt;To improve attention, consider the following strategies.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Mindfulness.&lt;/strong&gt; &quot;Mindfulness is about focusing attention on the present moment, and practicing mindfulness has been shown to rewire the brain so that attention is stronger in everyday life,&quot; says Kim Willment, a neuropsychologist with Brigham and Women&apos;s Hospital. She recommends sitting still for a few minutes each day, closing your eyes, and focusing on your breathing as well as the sounds and sensations around you.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cognitive training.&lt;/strong&gt; Computerized cognitive training games aim to improve your response times and attention. Evidence that this works has been mixed. &quot;The goal of playing these games is not to get better at them, but to get better in the cognitive activities of everyday life,&quot; Willment says. &quot;But there is evidence that a person&apos;s ability to pay attention can be improved by progressively pushing the person to higher levels of performance. So if you reach a certain level of sustained attention, pushing it to the next level can help improve it, and this may translate to everyday life.&quot;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A healthier lifestyle.&lt;/strong&gt; Many aspects of a healthy lifestyle can help attention, starting with sleep and exercise. There is a direct link between exercise and cognitive ability, especially attention. When you exercise, you increase the availability of brain chemicals that promote new brain connections, reduce stress, and improve sleep. And when we sleep, we reduce stress hormones that can be harmful to the brain, and we clear out proteins that injure it.&lt;/p&gt;
&lt;p&gt;Aim for seven to eight hours of sleep each night, and 150 minutes per week of aerobic exercise, such as brisk walking.&lt;/p&gt;
&lt;p&gt;Other healthy steps to improve focus: eat a Mediterranean-style diet, which has been shown to support brain health; treat underlying conditions; and change medications that may be affecting your ability to focus.&lt;/p&gt;
&lt;p&gt;Getting older is out of your control, but healthier living is something you determine, and it may improve concentration.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Article from: &lt;a href=&quot;https://www.health.harvard.edu/mind-and-mood/tips-to-improve-concentration&quot;&gt;Harvard Health Publishing&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded><h:img src="/_astro/thumbnail.1GZ294Dz.jpg"/><enclosure url="/_astro/thumbnail.1GZ294Dz.jpg"/></item><item><title>Using MDX</title><link>https://astro-pure.js.org/vi/blog/using-mdx</link><guid isPermaLink="true">https://astro-pure.js.org/vi/blog/using-mdx</guid><description>Learning how to use MDX in Astro</description><pubDate>Sun, 01 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This theme comes with the &lt;a href=&quot;https://docs.astro.build/en/guides/integrations-guide/mdx/&quot;&gt;@astrojs/mdx&lt;/a&gt; integration installed and configured in your &lt;code&gt;astro.config.ts&lt;/code&gt; config file. If you prefer not to use MDX, you can disable support by removing the integration from your config file.&lt;/p&gt;
&lt;h2&gt;Why MDX?&lt;/h2&gt;
&lt;p&gt;MDX is a special flavor of Markdown that supports embedded JavaScript &amp;#x26; JSX syntax. This unlocks the ability to &lt;a href=&quot;https://docs.astro.build/en/guides/markdown-content/#mdx-features&quot;&gt;mix JavaScript and UI Components into your Markdown content&lt;/a&gt; for things like interactive charts or alerts.&lt;/p&gt;
&lt;p&gt;If you have existing content authored in MDX, this integration will hopefully make migrating to Astro a breeze.&lt;/p&gt;
&lt;h2&gt;Example&lt;/h2&gt;
&lt;p&gt;Here is how you import and use a UI component inside of MDX.&lt;br&gt;
When you open this page in the browser, you should see the clickable button below.&lt;/p&gt;
&lt;p&gt;import { Button } from &apos;astro-pure/user&apos;&lt;/p&gt;
&lt;p&gt;Click Me&lt;/p&gt;
&lt;h2&gt;More Links&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://mdxjs.com/docs/what-is-mdx&quot;&gt;MDX Syntax Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.astro.build/en/guides/markdown-content/#markdown-and-mdx-pages&quot;&gt;Astro Usage Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;a href=&quot;https://docs.astro.build/en/reference/directives-reference/#client-directives&quot;&gt;Client Directives&lt;/a&gt; are still required to create interactive components. Otherwise, all components in your MDX will render as static HTML (no JavaScript) by default.&lt;/li&gt;
&lt;/ul&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>What Is 3D Rendering? Complete Guide to 3D Visualization</title><link>https://astro-pure.js.org/vi/blog/3d-rendering</link><guid isPermaLink="true">https://astro-pure.js.org/vi/blog/3d-rendering</guid><description>3D imagery has the power to bring cinematic visions to life and help accurately plan tomorrow’s cityscapes. Here, 3D expert Ricardo Ortiz explains how it works.</description><pubDate>Sun, 09 Feb 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;3D rendering is all around us. From huge action movies to car commercials to previews of upcoming buildings or product designs, 3D visualization has become so widespread and realistic that you probably don’t even know it’s there.&lt;/p&gt;
&lt;p&gt;In this introductory piece, Chaos’ Ricardo Ortiz explains the basics of 3D rendering, from the computational methods that create imagery to the artistic techniques that create great computer-generated (CG) content and its various uses.&lt;/p&gt;
&lt;h2&gt;What is 3D Rendering?&lt;/h2&gt;
&lt;p&gt;Put simply, 3D rendering is the process of using a computer to generate a 2D image from a digital three-dimensional scene.&lt;/p&gt;
&lt;p&gt;To generate an image, specific methodologies and special software and hardware are used. Therefore, we need to understand that 3D rendering is a process—the one that builds the image.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://astro-pure.js.org/_astro/nikola-arsov-still-life-interior-design-vray-3ds-max-05-930px.DoY3_oVo_Z1nNwxU.webp&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;h2&gt;Types of 3D rendering&lt;/h2&gt;
&lt;p&gt;We can create different types of rendered image; they can be realistic or non-realistic.&lt;/p&gt;
&lt;p&gt;A realistic image could be an architectural interior that looks like a photograph, a product-design image such as a piece of furniture, or an automotive rendering of a car. On the other hand, we can create a non-realistic image such as an outline-type diagram or a cartoon-style image with a traditional 2D look. Technically, we can visualize anything we can imagine.&lt;/p&gt;
&lt;h2&gt;How is 3D rendering used?&lt;/h2&gt;
&lt;p&gt;3D rendering is an essential technique for many industries including architecture, product design, advertising, video games and visual effects for film, TV and animation.&lt;/p&gt;
&lt;p&gt;In design and architecture, renders allow creative people to communicate their ideas in a clear and transparent way. A render gives them the chance to evaluate their proposals, experiment with materials, conduct studies and contextualize their designs in the real world before they are built or manufactured.&lt;/p&gt;
&lt;p&gt;For the media and entertainment industries, 3D rendering is fundamental to the creation of sequences and animations that tell stories, whether we’re watching an animated movie, a period drama, or an action sequence with explosions, ships from the future, exotic locales, or extraterrestrial creatures.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://astro-pure.js.org/_astro/thanos-dd-single-image-004a.DUX4VGf-_ZVCMNM.webp&quot; alt=&quot;alt text&quot;&gt;&lt;/p&gt;
&lt;p&gt;Over the past few years, the evolution of computer graphics in these industries has replaced traditional techniques. For example, special effects are being replaced by visual effects, which means stunt people no longer risk their lives in car crashes.&lt;/p&gt;
&lt;p&gt;In advertising, I would dare to say that 90% of automotive commercials are CG—or even more. In the architecture industry, many traditional techniques to create representations, such as scale models, have been replaced with photorealistic imagery to ensure we can see exactly how something will look once it’s built.&lt;/p&gt;
&lt;p&gt;Accelerating processes, reducing costs and the demand for better quality results have helped technology evolve. Hardware is more powerful than ever and the switch to CG was inevitable.&lt;/p&gt;
&lt;h2&gt;How is a 3D rendered image generated?&lt;/h2&gt;
&lt;p&gt;Two pieces of software, with different characteristics, are used to computer-generate images and animations: render engines and game engines. Render engines use a technique called ray tracing, while game engines use a technique called rasterization—and some engines mix both techniques, but we will talk about that later on.&lt;/p&gt;</content:encoded><h:img src="/_astro/thumbnail.DzZDiYKA.jpg"/><enclosure url="/_astro/thumbnail.DzZDiYKA.jpg"/></item><item><title>The Impact of Technology on the Music World</title><link>https://astro-pure.js.org/vi/blog/music-journey</link><guid isPermaLink="true">https://astro-pure.js.org/vi/blog/music-journey</guid><description>The evolution of music is a symphony of creativity, rhythm, and technology.</description><pubDate>Sat, 30 Nov 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The evolution of music is a symphony of creativity, rhythm, and technology. From the humble beginnings of acoustic instruments to the present-day digital era, the relationship between music and technology has been transformative. In this article, we will explore the historical milestones, digital revolution, and emerging technologies that have shaped the music world. Join us on a journey through the chords of innovation as we discuss how technology has changed music.&lt;/p&gt;
&lt;h2&gt;Historical Perspective&lt;/h2&gt;
&lt;p&gt;The marriage of music and technology dates back centuries, with pivotal moments shaping the industry. The invention of the phonograph by Thomas Edison in the late 19th century marked the first time music could be recorded and replayed. Subsequent milestones, such as the electric guitar and the synthesizer, revolutionized music creation, paving the way for new genres and sounds.&lt;/p&gt;
&lt;p&gt;These technological leaps didn&apos;t merely shape the musical landscape of their time but laid a foundation for the continuous evolution of the intersection between music and technology. As artists embraced these innovations, they unlocked new avenues for creativity, paving the way for diverse sounds and genres that have become integral to the vibrant tapestry of the modern music industry. The historical perspective illuminates the symbiotic relationship between music and technology, highlighting the transformative impact that each innovation has had on the way we create, consume, and experience music.&lt;/p&gt;
&lt;h2&gt;Digital Revolution&lt;/h2&gt;
&lt;p&gt;The digital revolution has been a seismic shift in the music industry, altering how music is consumed, distributed, and produced. The transition from physical formats like CDs and vinyl to digital formats such as MP3s and streaming services has democratized access to music. The ease of streaming has transformed how listeners discover and enjoy music, challenging traditional revenue models while offering unparalleled convenience.&lt;/p&gt;
&lt;h2&gt;Technology in Music Consumption and Distribution&lt;/h2&gt;
&lt;p&gt;Streaming services have become the heartbeat of music consumption, causing a decline in traditional music stores. The accessibility of music online has reshaped distribution channels, impacting both artists and record labels. While it provides exposure to a global audience, it also poses challenges regarding fair compensation for artists. The dynamics of the industry are evolving, reflecting the intricate dance between technology and music.
Music Production and Creation&lt;/p&gt;
&lt;p&gt;The advent of digital audio workstations (DAWs), software instruments, and electronic production techniques has democratized music creation. Artists now have powerful tools at their fingertips, enabling them to experiment with sounds, collaborate remotely, and produce music independently. This technological shift has broken down barriers, allowing for a diverse array of voices to be heard in the ever-expanding realm of music.&lt;/p&gt;</content:encoded><h:img src="/_astro/thumbnail.Cx18cRmB.jpg"/><enclosure url="/_astro/thumbnail.Cx18cRmB.jpg"/></item><item><title>Markdown Syntax Support</title><link>https://astro-pure.js.org/vi/blog/markdown</link><guid isPermaLink="true">https://astro-pure.js.org/vi/blog/markdown</guid><description>Markdown is a lightweight markup language.</description><pubDate>Wed, 26 Jul 2023 08:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Basic Syntax&lt;/h2&gt;
&lt;p&gt;Markdown is a lightweight and easy-to-use syntax for styling your writing.&lt;/p&gt;
&lt;h3&gt;Headers&lt;/h3&gt;
&lt;p&gt;When the content of the article is extensive, you can use headers to segment:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;# Header 1

## Header 2

## Large Header

### Small Header
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Header previews would disrupt the structure of the article, so they are not displayed here.&lt;/p&gt;
&lt;h3&gt;Bold and Italics&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;_Italic text_ and **Bold text**, together will be **_Bold Italic text_**
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Italic text&lt;/em&gt; and &lt;strong&gt;Bold text&lt;/strong&gt;, together will be &lt;strong&gt;&lt;em&gt;Bold Italic text&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;Links&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;Text link [Link Name](http://link-url)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt;Text link &lt;a href=&quot;http://link-url&quot;&gt;Link Name&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Inline Code&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;This is an `inline code`
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt;This is an &lt;code&gt;inline code&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;Code Blocks&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;```js
// calculate fibonacci
function fibonacci(n) {
  if (n &amp;#x3C;= 1) return 1
  const result = fibonacci(n - 1) + fibonacci(n - 2) // [\!code --]
  return fibonacci(n - 1) + fibonacci(n - 2) // [\!code ++]
}
```
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;// calculate fibonacci
function fibonacci(n) {
  if (n &amp;#x3C;= 1) return 1
  const result = fibonacci(n - 1) + fibonacci(n - 2) // [!code --]
  return fibonacci(n - 1) + fibonacci(n - 2) // [!code ++]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Currently using shiki as the code highlighting plugin. For supported languages, refer to &lt;a href=&quot;https://shiki.matsu.io/languages.html&quot;&gt;Shiki: Languages&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Inline Formula&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;This is an inline formula $e^{i\pi} + 1 = 0$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt;This is an inline formula $e^{i\pi} + 1 = 0$&lt;/p&gt;
&lt;h3&gt;Formula Blocks&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;$$
\hat{f}(\xi) = \int_{-\infty}^{\infty} f(x) e^{-2\pi i x \xi} \, dx
$$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt;$$
\hat{f}(\xi) = \int_{-\infty}^{\infty} f(x) e^{-2\pi i x \xi} , dx
$$&lt;/p&gt;
&lt;p&gt;Currently using KaTeX as the math formula plugin. For supported syntax, refer to &lt;a href=&quot;https://katex.org/docs/supported.html&quot;&gt;KaTeX Supported Functions&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;Images&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;![CWorld](https://cravatar.cn/avatar/1ffe42aa45a6b1444a786b1f32dfa8aa?s=200)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cravatar.cn/avatar/1ffe42aa45a6b1444a786b1f32dfa8aa?s=200&quot; alt=&quot;CWorld&quot;&gt;&lt;/p&gt;
&lt;h4&gt;Strikethrough&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;~~Strikethrough~~
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt;~~Strikethrough~~&lt;/p&gt;
&lt;h3&gt;Lists&lt;/h3&gt;
&lt;p&gt;Regular unordered list&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;- 1
- 2
- 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1&lt;/li&gt;
&lt;li&gt;2&lt;/li&gt;
&lt;li&gt;3&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Regular ordered list&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;1. GPT-4
2. Claude Opus
3. LLaMa
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;GPT-4&lt;/li&gt;
&lt;li&gt;Claude Opus&lt;/li&gt;
&lt;li&gt;LLaMa&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can continue to nest syntax within lists.&lt;/p&gt;
&lt;h3&gt;Blockquotes&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;&gt; Gunshot, thunder, sword rise. A scene of flowers and blood.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Gunshot, thunder, sword rise. A scene of flowers and blood.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You can continue to nest syntax within blockquotes.&lt;/p&gt;
&lt;h3&gt;Line Breaks&lt;/h3&gt;
&lt;p&gt;Markdown needs a blank line to separate paragraphs.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;If you don&apos;t leave a blank line
it will be in one paragraph

First paragraph

Second paragraph
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt;If you don&apos;t leave a blank line
it will be in one paragraph&lt;/p&gt;
&lt;p&gt;First paragraph&lt;/p&gt;
&lt;p&gt;Second paragraph&lt;/p&gt;
&lt;h3&gt;Separators&lt;/h3&gt;
&lt;p&gt;If you have the habit of writing separators, you can start a new line and enter three dashes &lt;code&gt;---&lt;/code&gt; or asterisks &lt;code&gt;***&lt;/code&gt;. Leave a blank line before and after when there are paragraphs:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;---
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Advanced Techniques&lt;/h2&gt;
&lt;h3&gt;Inline HTML Elements&lt;/h3&gt;
&lt;p&gt;Currently, only some inline HTML elements are supported, including &lt;code&gt;&amp;#x3C;kdb&gt; &amp;#x3C;b&gt; &amp;#x3C;i&gt; &amp;#x3C;em&gt; &amp;#x3C;sup&gt; &amp;#x3C;sub&gt; &amp;#x3C;br&gt;&lt;/code&gt;, such as&lt;/p&gt;
&lt;h4&gt;Key Display&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;Use &amp;#x3C;kbd&gt;Ctrl&amp;#x3C;/kbd&gt; + &amp;#x3C;kbd&gt;Alt&amp;#x3C;/kbd&gt; + &amp;#x3C;kbd&gt;Del&amp;#x3C;/kbd&gt; to reboot the computer
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt;Use Ctrl + Alt + Del to reboot the computer&lt;/p&gt;
&lt;h4&gt;Bold Italics&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;&amp;#x3C;b&gt; Markdown also applies here, such as _bold_ &amp;#x3C;/b&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt; Markdown also applies here, such as &lt;em&gt;bold&lt;/em&gt; &lt;/p&gt;
&lt;h3&gt;Other HTML Writing&lt;/h3&gt;
&lt;h4&gt;Foldable Blocks&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;&amp;#x3C;details&gt;&amp;#x3C;summary&gt;Click to expand&amp;#x3C;/summary&gt;It is hidden&amp;#x3C;/details&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;h3&gt;Tables&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;| Header1  | Header2  |
| -------- | -------- |
| Content1 | Content2 |
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt;| Header1  | Header2  |
| -------- | -------- |
| Content1 | Content2 |&lt;/p&gt;
&lt;h3&gt;Footnotes&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;Use [^footnote] to add a footnote at the point of reference.

Then, at the end of the document, add the content of the footnote (it will be rendered at the end of the article by default).

[^footnote]: Here is the content of the footnote
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt;Use [^footnote] to add a footnote at the point of reference.&lt;/p&gt;
&lt;p&gt;Then, at the end of the document, add the content of the footnote (it will be rendered at the end of the article by default).&lt;/p&gt;
&lt;p&gt;[^footnote]: Here is the content of the footnote&lt;/p&gt;
&lt;h3&gt;To-Do Lists&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;- [ ] Incomplete task
- [x] Completed task
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[ ] Incomplete task&lt;/li&gt;
&lt;li&gt;[x] Completed task&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Symbol Escaping&lt;/h3&gt;
&lt;p&gt;If you need to use markdown symbols like _ # * in your description but don&apos;t want them to be escaped, you can add a backslash before these symbols, such as &lt;code&gt;\_&lt;/code&gt; &lt;code&gt;\#&lt;/code&gt; &lt;code&gt;\*&lt;/code&gt; to avoid it.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-markdown&quot;&gt;\_Don&apos;t want the text here to be italic\_

\*\*Don&apos;t want the text here to be bold\*\*
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Preview:&lt;/p&gt;
&lt;p&gt;_Don&apos;t want the text here to be italic_&lt;/p&gt;
&lt;p&gt;**Don&apos;t want the text here to be bold**&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Embedding Astro Components&lt;/h2&gt;
&lt;p&gt;See &lt;a href=&quot;/docs/integrations/components&quot;&gt;User Components&lt;/a&gt; and &lt;a href=&quot;/docs/integrations/advanced&quot;&gt;Advanced Components&lt;/a&gt; for details.&lt;/p&gt;</content:encoded><h:img src="/_astro/thumbnail.HAXFr_hw.jpg"/><enclosure url="/_astro/thumbnail.HAXFr_hw.jpg"/></item></channel></rss>