<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[MakeXYZ Fun]]></title><description><![CDATA[Trải nghiệm, Ý tưởng, Kiến thức]]></description><link>https://makexyz.fun/</link><image><url>https://makexyz.fun/favicon.png</url><title>MakeXYZ Fun</title><link>https://makexyz.fun/</link></image><generator>Ghost 4.36</generator><lastBuildDate>Thu, 23 Apr 2026 09:47:12 GMT</lastBuildDate><atom:link href="https://makexyz.fun/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[MCP, Rules, Skills & Workflows trong Antigravity IDE]]></title><description><![CDATA[Hướng dẫn đầy đủ về bốn cơ chế mở rộng của Antigravity — từ khái niệm đến cách phối hợp trong dự án SwiftUI thực tế.]]></description><link>https://makexyz.fun/mcp-rules-skills-workflows-trong-antigravity-ide/</link><guid isPermaLink="false">69db936ad334dbad362bbdfc</guid><category><![CDATA[AI]]></category><dc:creator><![CDATA[Tony Phạm]]></dc:creator><pubDate>Sun, 12 Apr 2026 12:44:19 GMT</pubDate><content:encoded><![CDATA[<blockquote>H&#x1B0;&#x1EDB;ng d&#x1EAB;n &#x111;&#x1EA7;y &#x111;&#x1EE7; v&#x1EC1; b&#x1ED1;n c&#x1A1; ch&#x1EBF; m&#x1EDF; r&#x1ED9;ng c&#x1EE7;a Antigravity &#x2014; t&#x1EEB; kh&#xE1;i ni&#x1EC7;m &#x111;&#x1EBF;n c&#xE1;ch ph&#x1ED1;i h&#x1EE3;p trong d&#x1EF1; &#xE1;n SwiftUI th&#x1EF1;c t&#x1EBF;.</blockquote><hr><h2 id="m%E1%BB%A5c-l%E1%BB%A5c">M&#x1EE5;c l&#x1EE5;c</h2><ol><li><a href="https://claude.ai/chat/7aab279c-0a2b-42f9-a106-cfa6ff8d69da#1-t%E1%BB%95ng-quan">T&#x1ED5;ng quan &#x2014; b&#x1ED1;n c&#x1A1; ch&#x1EBF; m&#x1EDF; r&#x1ED9;ng</a></li><li><a href="https://claude.ai/chat/7aab279c-0a2b-42f9-a106-cfa6ff8d69da#2-mcp--model-context-protocol">MCP &#x2014; b&#xE0;n tay c&#x1EE7;a agent</a></li><li><a href="https://claude.ai/chat/7aab279c-0a2b-42f9-a106-cfa6ff8d69da#3-rules--lu%E1%BA%ADt-h%C3%A0nh-vi">Rules &#x2014; lu&#x1EAD;t h&#xE0;nh vi</a></li><li><a href="https://claude.ai/chat/7aab279c-0a2b-42f9-a106-cfa6ff8d69da#4-skills--chuy%C3%AAn-gia-theo-y%C3%AAu-c%E1%BA%A7u">Skills &#x2014; chuy&#xEA;n gia theo y&#xEA;u c&#x1EA7;u</a></li><li><a href="https://claude.ai/chat/7aab279c-0a2b-42f9-a106-cfa6ff8d69da#5-workflows--ng%C6%B0%E1%BB%9Di-%C4%91i%E1%BB%81u-ph%E1%BB%91i">Workflows &#x2014; ng&#x1B0;&#x1EDD;i &#x111;i&#x1EC1;u ph&#x1ED1;i</a></li><li><a href="https://claude.ai/chat/7aab279c-0a2b-42f9-a106-cfa6ff8d69da#6-so-s%C3%A1nh-v%C3%A0-%C4%91i%E1%BB%83m-giao">So s&#xE1;nh v&#xE0; &#x111;i&#x1EC3;m giao</a></li><li><a href="https://claude.ai/chat/7aab279c-0a2b-42f9-a106-cfa6ff8d69da#7-m%C3%B4-h%C3%ACnh-ph%E1%BB%91i-h%E1%BB%A3p">M&#xF4; h&#xEC;nh ph&#x1ED1;i h&#x1EE3;p</a></li><li><a href="https://claude.ai/chat/7aab279c-0a2b-42f9-a106-cfa6ff8d69da#8-thi%E1%BA%BFt-l%E1%BA%ADp-th%E1%BB%B1c-t%E1%BA%BF-cho-swiftui">Thi&#x1EBF;t l&#x1EAD;p th&#x1EF1;c t&#x1EBF; cho SwiftUI</a></li><li><a href="https://claude.ai/chat/7aab279c-0a2b-42f9-a106-cfa6ff8d69da#9-nh%E1%BB%AFng-%C4%91i%E1%BB%81u-c%E1%BA%A7n-bi%E1%BA%BFt">Nh&#x1EEF;ng &#x111;i&#x1EC1;u c&#x1EA7;n bi&#x1EBF;t</a></li></ol><hr><h2 id="1-t%E1%BB%95ng-quan">1. T&#x1ED5;ng quan</h2><p>Antigravity cung c&#x1EA5;p b&#x1ED1;n c&#x1A1; ch&#x1EBF; &#x111;&#x1EC3; m&#x1EDF; r&#x1ED9;ng kh&#x1EA3; n&#x103;ng c&#x1EE7;a AI agent: <strong>MCP</strong>, <strong>Rules</strong>, <strong>Skills</strong>, v&#xE0; <strong>Workflows</strong>. Ch&#xFA;ng kh&#xF4;ng ph&#x1EA3;i l&#xE0; b&#x1ED1;n c&#xE1;ch kh&#xE1;c nhau &#x111;&#x1EC3; l&#xE0;m c&#xF9;ng m&#x1ED9;t vi&#x1EC7;c &#x2014; m&#x1ED7;i c&#x1A1; ch&#x1EBF; c&#xF3; vai tr&#xF2; ri&#xEA;ng bi&#x1EC7;t v&#xE0; c&#xE1;ch ph&#x1ED1;i h&#x1EE3;p c&#x1EE5; th&#x1EC3;.</p><!--kg-card-begin: html--><table>
<thead>
<tr>
<th>C&#x1A1; ch&#x1EBF;</th>
<th>Vai tr&#xF2;</th>
<th>Ph&#xE9;p &#x1EA9;n d&#x1EE5;</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>MCP</strong></td>
<td>K&#x1EBF;t n&#x1ED1;i agent v&#x1EDB;i tool b&#xEA;n ngo&#xE0;i</td>
<td>B&#xE0;n tay &#x2014; th&#x1EF1;c thi h&#xE0;nh &#x111;&#x1ED9;ng</td>
</tr>
<tr>
<td><strong>Rules</strong></td>
<td>Quy t&#x1EAF;c lu&#xF4;n hi&#x1EC7;n di&#x1EC7;n trong context</td>
<td>Giao th&#x1EE9;c &#x2014; lu&#x1EAD;t b&#x1EA5;t bi&#x1EBF;n</td>
</tr>
<tr>
<td><strong>Skills</strong></td>
<td>Ki&#x1EBF;n th&#x1EE9;c chuy&#xEA;n s&#xE2;u &#x111;&#x1B0;&#x1EE3;c load khi c&#x1EA7;n</td>
<td>Chuy&#xEA;n gia &#x2014; g&#x1ECD;i v&#xE0;o khi c&#x1EA7;n</td>
</tr>
<tr>
<td><strong>Workflows</strong></td>
<td>Chu&#x1ED7;i b&#x1B0;&#x1EDB;c c&#x1ED1; &#x111;&#x1ECB;nh, k&#xED;ch ho&#x1EA1;t b&#x1EB1;ng <code>/</code></td>
<td>Quy tr&#xEC;nh &#x2014; &#x111;i&#x1EC1;u ph&#x1ED1;i c&#xE1;c b&#x1B0;&#x1EDB;c</td>
</tr>
</tbody>
</table><!--kg-card-end: html--><blockquote><strong>Ph&#xE9;p &#x1EA9;n d&#x1EE5; to&#xE0;n c&#x1EA3;nh:</strong> T&#x1B0;&#x1EDF;ng t&#x1B0;&#x1EE3;ng m&#x1ED9;t &#x111;&#x1ED9;i ph&#x1EAB;u thu&#x1EAD;t: MCP l&#xE0; b&#x1ED9; d&#x1EE5;ng c&#x1EE5;, Rules l&#xE0; giao th&#x1EE9;c y t&#x1EBF; ph&#x1EA3;i lu&#xF4;n tu&#xE2;n th&#x1EE7;, Skills l&#xE0; chuy&#xEA;n khoa c&#x1EE7;a t&#x1EEB;ng b&#xE1;c s&#x129;, Workflows l&#xE0; quy tr&#xEC;nh ph&#x1EAB;u thu&#x1EAD;t &#x111;&#x1B0;&#x1EE3;c l&#xEA;n k&#x1EBF; ho&#x1EA1;ch tr&#x1B0;&#x1EDB;c.</blockquote><hr><h2 id="2-mcp-%E2%80%94-model-context-protocol">2. MCP &#x2014; Model Context Protocol</h2><p>MCP l&#xE0; giao th&#x1EE9;c chu&#x1EA9;n m&#x1EDF; cho ph&#xE9;p AI agent k&#x1EBF;t n&#x1ED1;i v&#x1EDB;i c&#xF4;ng c&#x1EE5; b&#xEA;n ngo&#xE0;i theo c&#xE1;ch nh&#x1EA5;t qu&#xE1;n. Trong Antigravity, agent s&#x1EED; d&#x1EE5;ng MCP &#x111;&#x1EC3; th&#x1EF1;c s&#x1EF1; <em>l&#xE0;m</em> vi&#x1EC7;c &#x2014; kh&#xF4;ng ch&#x1EC9; &#x111;&#x1EC1; xu&#x1EA5;t code.</p><h3 id="hai-ki%E1%BA%BFn-tr%C3%BAc-tri%E1%BB%83n-khai">Hai ki&#x1EBF;n tr&#xFA;c tri&#x1EC3;n khai</h3><p><strong>Local stdio</strong> &#x2014; ph&#x1ED5; bi&#x1EBF;n nh&#x1EA5;t cho iOS/macOS dev. Antigravity spawn m&#x1ED9;t child process tr&#xEA;n m&#xE1;y, giao ti&#x1EBF;p qua stdin/stdout. Kh&#xF4;ng c&#x1EA7;n server t&#x1EEB; xa, kh&#xF4;ng c&#x1EA7;n internet:</p><pre><code>Antigravity IDE  &#x2500;&#x2500;stdio&#x2500;&#x2500;&#x25B6;  npx xcodebuildmcp  &#x2500;&#x2500;&#x25B6;  xcodebuild / Xcode
(MCP client)                 (MCP server, local)       (actual tool)
</code></pre><p><strong>Remote URL</strong> &#x2014; d&#xF9;ng cho cloud services. Giao ti&#x1EBF;p qua HTTP/SSE v&#x1EDB;i server th&#x1EAD;t &#x1EDF; xa:</p><pre><code>Antigravity IDE  &#x2500;&#x2500;HTTP/SSE&#x2500;&#x2500;&#x25B6;  gcal.mcp.claude.com  &#x2500;&#x2500;&#x25B6;  Google API
(MCP client)                    (MCP server, remote)        (external service)
</code></pre><h3 id="c%C3%A1c-mcp-thi%E1%BA%BFt-y%E1%BA%BFu-cho-swiftui">C&#xE1;c MCP thi&#x1EBF;t y&#x1EBF;u cho SwiftUI</h3><!--kg-card-begin: html--><table>
<thead>
<tr>
<th>MCP</th>
<th>Ch&#x1EE9;c n&#x103;ng</th>
<th>C&#xE0;i &#x111;&#x1EB7;t</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>XcodeBuildMCP</strong></td>
<td>Build, test, debug, LLDB, simulator, real device &#x2014; 59 tools</td>
<td><code>npx xcodebuildmcp@latest mcp</code></td>
</tr>
<tr>
<td><strong>Xcode Native MCP</strong></td>
<td>Apple built-in (Xcode 26.3+), 20 tools, Swift REPL, SwiftUI Preview</td>
<td><code>xcrun mcpbridge</code></td>
</tr>
<tr>
<td><strong>Apple Docs MCP</strong></td>
<td>Tra c&#x1EE9;u Swift/SwiftUI docs, WWDC 2014&#x2013;2025, offline</td>
<td><code>npx @kimsungwhee/apple-docs-mcp</code></td>
</tr>
<tr>
<td><strong>swift-mcp</strong></td>
<td>&quot;Senior iOS dev&quot; &#x1EA3;o &#x2014; best practices, patterns, Core Data</td>
<td><code>npx swift-mcp</code></td>
</tr>
<tr>
<td><strong>swift-patterns-mcp</strong></td>
<td>Patterns t&#x1EEB; Swift by Sundell, SwiftLee v&#xE0; c&#x1ED9;ng &#x111;&#x1ED3;ng</td>
<td><code>npx swift-patterns-mcp@latest</code></td>
</tr>
</tbody>
</table><!--kg-card-end: html--><h3 id="c%E1%BA%A5u-h%C3%ACnh-mcpconfigjson">C&#x1EA5;u h&#xEC;nh mcp_config.json</h3><pre><code class="language-json">{
  &quot;mcpServers&quot;: {
    &quot;XcodeBuildMCP&quot;: {
      &quot;command&quot;: &quot;npx&quot;,
      &quot;args&quot;: [&quot;-y&quot;, &quot;xcodebuildmcp@latest&quot;, &quot;mcp&quot;]
    },
    &quot;xcode-native&quot;: {
      &quot;command&quot;: &quot;xcrun&quot;,
      &quot;args&quot;: [&quot;mcpbridge&quot;]
    },
    &quot;apple-docs&quot;: {
      &quot;command&quot;: &quot;npx&quot;,
      &quot;args&quot;: [&quot;-y&quot;, &quot;@kimsungwhee/apple-docs-mcp&quot;]
    },
    &quot;swift-mcp&quot;: {
      &quot;command&quot;: &quot;npx&quot;,
      &quot;args&quot;: [&quot;-y&quot;, &quot;swift-mcp&quot;]
    }
  }
}
</code></pre><blockquote>&#x26A0;&#xFE0F; <strong>L&#x1B0;u &#xFD;:</strong> Antigravity <strong>kh&#xF4;ng h&#x1ED7; tr&#x1EE3;</strong> <code>${workspaceFolder}</code>. Lu&#xF4;n d&#xF9;ng &#x111;&#x1B0;&#x1EDD;ng d&#x1EAB;n tuy&#x1EC7;t &#x111;&#x1ED1;i trong m&#x1ECD;i c&#x1EA5;u h&#xEC;nh MCP.</blockquote><h3 id="c%C3%A1ch-k%C3%ADch-ho%E1%BA%A1t">C&#xE1;ch k&#xED;ch ho&#x1EA1;t</h3><p>Sau khi c&#x1EA5;u h&#xEC;nh, agent t&#x1EF1; &#x111;&#x1ED9;ng g&#x1ECD;i tool khi c&#x1EA7;n. B&#x1EA1;n c&#x169;ng c&#xF3; th&#x1EC3; g&#x1ECD;i th&#x1EE7; c&#xF4;ng b&#x1EB1;ng <code>@ten-mcp</code> trong chat, ho&#x1EB7;c c&#xE0;i qua <strong>MCP Store</strong> (<code>...</code> &#x2192; <code>MCP Servers</code> &#x2192; <code>MCP Store</code>).</p><hr><h2 id="3-rules-%E2%80%94-lu%E1%BA%ADt-h%C3%A0nh-vi">3. Rules &#x2014; Lu&#x1EAD;t h&#xE0;nh vi</h2><p>Rules l&#xE0; v&#x103;n b&#x1EA3;n h&#x1B0;&#x1EDB;ng d&#x1EAB;n &#x111;&#x1B0;&#x1EE3;c inject v&#xE0;o context c&#x1EE7;a agent. Ch&#xFA;ng &#x111;&#x1ECB;nh h&#xEC;nh c&#xE1;ch agent vi&#x1EBF;t code, ki&#x1EBF;n tr&#xFA;c, v&#xE0; style m&#xE0; kh&#xF4;ng c&#x1EA7;n nh&#x1EAF;c l&#x1EA1;i m&#x1ED7;i l&#x1EA7;n.</p><h3 id="ba-lo%E1%BA%A1i-trigger">Ba lo&#x1EA1;i trigger</h3><p><strong><code>always_on</code></strong> &#x2014; Inject v&#xE0;o context m&#x1ECD;i l&#xFA;c, d&#xF9; h&#x1ECF;i g&#xEC;. D&#xF9;ng th&#x1EAD;t ti&#x1EBF;t ki&#x1EC7;m, ch&#x1EC9; cho quy t&#x1EAF;c c&#x1EF1;c k&#x1EF3; quan tr&#x1ECD;ng (v&#xED; d&#x1EE5;: &quot;kh&#xF4;ng bao gi&#x1EDD; commit secret key&quot;):</p><pre><code class="language-yaml"># .agent/rules/swift-standards.md
---
trigger: always_on
---
# Quy t&#x1EAF;c Swift to&#xE0;n c&#x1EE5;c
Lu&#xF4;n d&#xF9;ng Swift 6 concurrency.
Kh&#xF4;ng d&#xF9;ng DispatchQueue tr&#x1EF1;c ti&#x1EBF;p.
</code></pre><p><strong><code>model_decision</code></strong> &#x2014; Agent &#x111;&#x1ECD;c <code>description</code> v&#xE0; <em>t&#x1EF1; quy&#x1EBF;t &#x111;&#x1ECB;nh</em> c&#xF3; load rule kh&#xF4;ng d&#x1EF1;a tr&#xEA;n y&#xEA;u c&#x1EA7;u hi&#x1EC7;n t&#x1EA1;i. &#x110;&#xE2;y l&#xE0; c&#xE1;ch d&#xF9;ng ph&#x1ED5; bi&#x1EBF;n nh&#x1EA5;t:</p><pre><code class="language-yaml"># .agent/rules/mvvm-rules.md
---
trigger: model_decision
description: Quy t&#x1EAF;c ki&#x1EBF;n tr&#xFA;c MVVM cho SwiftUI.
             D&#xF9;ng khi t&#x1EA1;o ViewModel, state management.
---
# MVVM Rules
D&#xF9;ng @Observable thay ObservableObject.
Kh&#xF4;ng import SwiftUI trong ViewModel.
</code></pre><p><strong><code>file_match</code></strong> &#x2014; Ch&#x1EC9; b&#x1EAD;t khi ng&#x1B0;&#x1EDD;i d&#xF9;ng &#x111;ang m&#x1EDF; file kh&#x1EDB;p pattern:</p><pre><code class="language-yaml"># .agent/rules/swift-files.md
---
trigger: file_match
glob: &quot;**/*.swift&quot;
---
# Swift file rules
D&#xF9;ng guard let cho early returns.
&#x1AF;u ti&#xEA;n struct tr&#x1B0;&#x1EDB;c class.
</code></pre><blockquote><strong>Model Decision &#x2014; c&#x1A1; ch&#x1EBF; th&#xF4;ng minh:</strong> Khi b&#x1EA1;n h&#x1ECF;i v&#x1EC1; ViewModel, agent th&#x1EA5;y description kh&#x1EDB;p v&#xE0; load rule. Khi h&#x1ECF;i v&#x1EC1; build error, agent b&#x1ECF; qua &#x2014; ti&#x1EBF;t ki&#x1EC7;m context window. &#x110;&#xE2;y l&#xE0; phi&#xEA;n b&#x1EA3;n nh&#x1EB9; h&#x1A1;n c&#x1EE7;a Skills: ch&#x1EC9; text, kh&#xF4;ng c&#xF3; scripts hay assets.</blockquote><h3 id="v%E1%BB%8B-tr%C3%AD-file">V&#x1ECB; tr&#xED; file</h3><!--kg-card-begin: html--><table>
<thead>
<tr>
<th>Ph&#x1EA1;m vi</th>
<th>&#x110;&#x1B0;&#x1EDD;ng d&#x1EAB;n</th>
</tr>
</thead>
<tbody>
<tr>
<td>Global (t&#x1EA5;t c&#x1EA3; project)</td>
<td><code>~/.gemini/antigravity/rules/</code></td>
</tr>
<tr>
<td>Per-workspace</td>
<td><code>.agent/rules/</code></td>
</tr>
</tbody>
</table><!--kg-card-end: html--><hr><h2 id="4-skills-%E2%80%94-chuy%C3%AAn-gia-theo-y%C3%AAu-c%E1%BA%A7u">4. Skills &#x2014; Chuy&#xEA;n gia theo y&#xEA;u c&#x1EA7;u</h2><p>Skills l&#xE0; g&#xF3;i ki&#x1EBF;n th&#x1EE9;c chuy&#xEA;n s&#xE2;u &#x111;&#x1B0;&#x1EE3;c load v&#xE0;o context <em>ch&#x1EC9; khi c&#x1EA7;n</em>. Agent &#x111;&#x1ECD;c metadata c&#x1EE7;a t&#x1EA5;t c&#x1EA3; skills, r&#x1ED3;i t&#x1EF1; quy&#x1EBF;t &#x111;&#x1ECB;nh load c&#xE1;i n&#xE0;o d&#x1EF1;a tr&#xEA;n intent c&#x1EE7;a ng&#x1B0;&#x1EDD;i d&#xF9;ng &#x2014; kh&#xF4;ng c&#x1EA7;n slash command, kh&#xF4;ng c&#x1EA7;n mention t&#xEA;n.</p><h3 id="c%E1%BA%A5u-tr%C3%BAc-th%C6%B0-m%E1%BB%A5c">C&#x1EA5;u tr&#xFA;c th&#x1B0; m&#x1EE5;c</h3><pre><code>.agent/skills/
&#x2514;&#x2500;&#x2500; mvvm-swiftui/
    &#x251C;&#x2500;&#x2500; SKILL.md            &#x2190; b&#x1EAF;t bu&#x1ED9;c, brain c&#x1EE7;a skill
    &#x251C;&#x2500;&#x2500; scripts/
    &#x2502;   &#x2514;&#x2500;&#x2500; gen_viewmodel.sh    &#x2190; script t&#xF9;y ch&#x1ECD;n
    &#x2514;&#x2500;&#x2500; resources/
        &#x2514;&#x2500;&#x2500; templates/          &#x2190; template t&#xF9;y ch&#x1ECD;n
</code></pre><h3 id="v%C3%AD-d%E1%BB%A5-skillmd">V&#xED; d&#x1EE5; SKILL.md</h3><pre><code class="language-markdown">---
name: mvvm-swiftui
description: Ki&#x1EBF;n tr&#xFA;c MVVM cho SwiftUI v&#x1EDB;i @Observable,
             SwiftData, v&#xE0; async/await. D&#xF9;ng khi t&#x1EA1;o
             ViewModel, state management, data flow.
---

# MVVM SwiftUI Skill

## ViewModel pattern
- D&#xF9;ng @Observable macro (kh&#xF4;ng ObservableObject)
- Kh&#xF4;ng import SwiftUI trong ViewModel
- Ch&#x1EC9; import Foundation v&#xE0; domain types
- Mark class v&#x1EDB;i @MainActor n&#x1EBF;u c&#x1EA7;n async work

## State management
- @State: local UI state trong View
- @Bindable: truy&#x1EC1;n ViewModel v&#xE0;o child View
- Environment: dependency injection to&#xE0;n app

## V&#xED; d&#x1EE5; chu&#x1EA9;n

```swift
@Observable
class LoginViewModel {
    var email = &quot;&quot;
    var password = &quot;&quot;
    var isLoading = false

    private let authService: AuthServiceProtocol

    init(authService: AuthServiceProtocol) {
        self.authService = authService
    }

    func login() async { ... }
}
</code></pre><pre><code>
&gt; **Progressive Disclosure:** M&#x1ED7;i session, Antigravity ch&#x1EC9; load *metadata* (name + description) c&#x1EE7;a t&#x1EA5;t c&#x1EA3; skills &#x2014; kh&#xF4;ng ph&#x1EA3;i to&#xE0;n b&#x1ED9; n&#x1ED9;i dung. Khi b&#x1EA1;n h&#x1ECF;i v&#x1EC1; MVVM, agent m&#x1EDB;i load &#x111;&#x1EA7;y &#x111;&#x1EE7; `SKILL.md`. &#x110;i&#x1EC1;u n&#xE0;y gi&#x1EEF; context window g&#x1ECD;n, tr&#xE1;nh &quot;tool bloat&quot;.

### Skills c&#xF3; th&#x1EC3; l&#xE0;m g&#xEC; ngo&#xE0;i ki&#x1EBF;n th&#x1EE9;c?

Khi c&#xF3; th&#x1B0; m&#x1EE5;c `scripts/`, agent c&#xF3; th&#x1EC3; th&#x1EF1;c thi script bash/python &#x111;&#x1EC3; th&#x1EF1;c hi&#x1EC7;n h&#xE0;nh &#x111;&#x1ED9;ng th&#x1EF1;c t&#x1EBF; &#x2014; &#x111;&#x1ECD;c schema database, g&#x1ECD;i API n&#x1ED9;i b&#x1ED9;, generate file t&#x1EEB; template. &#x110;&#xE2;y l&#xE0; &#x111;i&#x1EC3;m kh&#xE1;c bi&#x1EC7;t l&#x1EDB;n v&#x1EDB;i Rules (ch&#x1EC9; l&#xE0; text).

### V&#x1ECB; tr&#xED; file

| Ph&#x1EA1;m vi | &#x110;&#x1B0;&#x1EDD;ng d&#x1EAB;n |
|---|---|
| Global (t&#x1EA5;t c&#x1EA3; project) | `~/.gemini/antigravity/skills/` |
| Per-workspace | `.agent/skills/` |

---

## 5. Workflows &#x2014; Ng&#x1B0;&#x1EDD;i &#x111;i&#x1EC1;u ph&#x1ED1;i

Workflows l&#xE0; chu&#x1ED7;i b&#x1B0;&#x1EDB;c c&#xF3; th&#x1EE9; t&#x1EF1; c&#x1ED1; &#x111;&#x1ECB;nh, &#x111;&#x1B0;&#x1EE3;c k&#xED;ch ho&#x1EA1;t khi ng&#x1B0;&#x1EDD;i d&#xF9;ng g&#xF5; slash command. Ch&#xFA;ng &#x111;&#xF3;ng vai tr&#xF2; orchestrator &#x2014; &#x111;i&#x1EC1;u ph&#x1ED1;i Skills, MCP tools, v&#xE0; l&#x1EC7;nh terminal.

### B&#x1ED1;n c&#xFA; ph&#xE1;p c&#x1ED1;t l&#xF5;i (AgentKit 2.0)

| C&#xFA; ph&#xE1;p | Ch&#x1EE9;c n&#x103;ng | Ghi ch&#xFA; |
|---|---|---|
| `// turbo &apos;l&#x1EC7;nh&apos;` | Ch&#x1EA1;y l&#x1EC7;nh terminal t&#x1EF1; &#x111;&#x1ED9;ng, kh&#xF4;ng h&#x1ECF;i | Kh&#xF4;ng c&#xF3; `turbo` &#x2192; agent h&#x1ECF;i tr&#x1B0;&#x1EDB;c |
| `// run workflow: name` | G&#x1ECD;i sub-workflow | Sub-workflow v&#x1EAB;n ch&#x1EA1;y &#x111;&#x1ED9;c l&#x1EAD;p &#x111;&#x1B0;&#x1EE3;c |
| `// parallel &#x2026; // end parallel` | Ch&#x1EA1;y c&#xE1;c b&#x1B0;&#x1EDB;c &#x111;&#x1ED3;ng th&#x1EDD;i | D&#xF9;ng cho b&#x1B0;&#x1EDB;c &#x111;&#x1ED9;c l&#x1EAD;p nhau |
| `// if [&#x111;i&#x1EC1;u ki&#x1EC7;n] &#x2026; // end if` | R&#x1EBD; nh&#xE1;nh c&#xF3; &#x111;i&#x1EC1;u ki&#x1EC7;n | Agent &#x111;&#xE1;nh gi&#xE1; &#x1EDF; runtime |

### V&#xED; d&#x1EE5; workflow &#x111;&#x1EA7;y &#x111;&#x1EE7;

```markdown
---
description: CI pipeline cho SwiftUI &#x2014; lint, test, build, deploy
---

1. Resolve Swift packages // turbo &apos;swift package resolve&apos;

// parallel
2. Ch&#x1EA1;y SwiftLint // turbo &apos;swiftlint lint&apos;
3. Ch&#x1EA1;y unit tests // turbo &apos;xcodebuild test -scheme MyApp&apos;
// end parallel

// if c&#xF3; l&#x1ED7;i lint ho&#x1EB7;c test fail
4. D&#x1EEB;ng v&#xE0; b&#xE1;o c&#xE1;o l&#x1ED7;i chi ti&#x1EBF;t
// end if

5. D&#xF9;ng mvvm-swiftui skill &#x111;&#x1EC3; review ViewModel trong diff

// run workflow: build-archive

// if branch l&#xE0; main
// run workflow: publish-testflight
// end if
</code></pre><h3 id="v%E1%BB%8B-tr%C3%AD-file-1">V&#x1ECB; tr&#xED; file</h3><!--kg-card-begin: html--><table>
<thead>
<tr>
<th>Ph&#x1EA1;m vi</th>
<th>&#x110;&#x1B0;&#x1EDD;ng d&#x1EAB;n</th>
</tr>
</thead>
<tbody>
<tr>
<td>Global (t&#x1EA5;t c&#x1EA3; project)</td>
<td><code>~/.gemini/antigravity/workflows/</code></td>
</tr>
<tr>
<td>Per-workspace</td>
<td><code>.agent/workflows/</code></td>
</tr>
</tbody>
</table><!--kg-card-end: html--><hr><h2 id="6-so-s%C3%A1nh-v%C3%A0-%C4%91i%E1%BB%83m-giao">6. So s&#xE1;nh v&#xE0; &#x111;i&#x1EC3;m giao</h2><h3 id="b%E1%BA%A3ng-so-s%C3%A1nh">B&#x1EA3;ng so s&#xE1;nh</h3><!--kg-card-begin: html--><table>
<thead>
<tr>
<th>Ti&#xEA;u ch&#xED;</th>
<th>MCP</th>
<th>Rules</th>
<th>Skills</th>
<th>Workflows</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Vai tr&#xF2;</strong></td>
<td>K&#x1EBF;t n&#x1ED1;i tool ngo&#xE0;i</td>
<td>Lu&#x1EAD;t b&#x1EA5;t bi&#x1EBF;n</td>
<td>Ki&#x1EBF;n th&#x1EE9;c chuy&#xEA;n s&#xE2;u</td>
<td>Chu&#x1ED7;i b&#x1B0;&#x1EDB;c c&#x1ED1; &#x111;&#x1ECB;nh</td>
</tr>
<tr>
<td><strong>K&#xED;ch ho&#x1EA1;t</strong></td>
<td>Agent t&#x1EF1; g&#x1ECD;i ho&#x1EB7;c <code>@</code></td>
<td>Lu&#xF4;n b&#x1EAD;t ho&#x1EB7;c c&#xF3; &#x111;i&#x1EC1;u ki&#x1EC7;n</td>
<td>Agent t&#x1EF1; detect t&#x1EEB; intent</td>
<td>Ng&#x1B0;&#x1EDD;i d&#xF9;ng g&#xF5; <code>/</code></td>
</tr>
<tr>
<td><strong>Ch&#x1EE9;a l&#x1EC7;nh?</strong></td>
<td>L&#xE0; tool/function</td>
<td>Kh&#xF4;ng</td>
<td>C&#xF3; (<code>scripts/</code>)</td>
<td>C&#xF3; (<code>// turbo</code>)</td>
</tr>
<tr>
<td><strong>Th&#x1EE9; t&#x1EF1; b&#x1B0;&#x1EDB;c</strong></td>
<td>Kh&#xF4;ng c&#xF3;</td>
<td>Kh&#xF4;ng c&#xF3;</td>
<td>Linh ho&#x1EA1;t</td>
<td>C&#x1ED1; &#x111;&#x1ECB;nh</td>
</tr>
<tr>
<td><strong>V&#x1ECB; tr&#xED; file</strong></td>
<td><code>mcp_config.json</code></td>
<td><code>.agent/rules/</code></td>
<td><code>.agent/skills/</code></td>
<td><code>.agent/workflows/</code></td>
</tr>
</tbody>
</table><!--kg-card-end: html--><h3 id="%C4%91i%E1%BB%83m-giao-v%C3%A0-c%C3%A1ch-ph%C3%A2n-bi%E1%BB%87t">&#x110;i&#x1EC3;m giao v&#xE0; c&#xE1;ch ph&#xE2;n bi&#x1EC7;t</h3><p>Skills v&#xE0; Workflows &#x111;&#x1EC1;u c&#xF3; th&#x1EC3; ch&#x1EE9;a c&#xE1;c b&#x1B0;&#x1EDB;c tu&#x1EA7;n t&#x1EF1;. Ranh gi&#x1EDB;i n&#x1EB1;m &#x1EDF; <strong>hai tr&#x1EE5;c</strong>:</p><p><strong>Ai k&#xED;ch ho&#x1EA1;t?</strong></p><ul><li>Ng&#x1B0;&#x1EDD;i d&#xF9;ng ch&#x1EE7; &#x111;&#x1ED9;ng g&#x1ECD;i &#x2192; <strong>Workflow</strong></li><li>Agent t&#x1EF1; ph&#xE1;t hi&#x1EC7;n &#x2192; <strong>Skill</strong></li></ul><p><strong>N&#x1ED9;i dung l&#xE0; g&#xEC;?</strong></p><ul><li>&quot;C&#xE1;ch t&#x1B0; duy, pattern, ki&#x1EBF;n th&#x1EE9;c&quot; &#x2192; <strong>Skill</strong></li><li>&quot;Chu&#x1ED7;i l&#x1EC7;nh c&#x1EE5; th&#x1EC3;, th&#x1EE9; t&#x1EF1; c&#x1EE9;ng&quot; &#x2192; <strong>Workflow</strong></li></ul><blockquote>&#x26A0;&#xFE0F; <strong>D&#x1EA5;u hi&#x1EC7;u c&#x1EA7;n t&#xE1;ch ra:</strong> N&#x1EBF;u b&#x1EA1;n &#x111;ang vi&#x1EBF;t l&#x1EC7;nh terminal trong Skill, ho&#x1EB7;c vi&#x1EBF;t ki&#x1EBF;n th&#x1EE9;c MVVM d&#xE0;i trong Workflow &#x2014; &#x111;&#xF3; l&#xE0; d&#x1EA5;u hi&#x1EC7;u c&#x1EA7;n t&#xE1;ch ra &#x111;&#xFA;ng ch&#x1ED7;.</blockquote><hr><h2 id="7-m%C3%B4-h%C3%ACnh-ph%E1%BB%91i-h%E1%BB%A3p">7. M&#xF4; h&#xEC;nh ph&#x1ED1;i h&#x1EE3;p</h2><p>Chi&#x1EC1;u orchestration &#x111;&#x1B0;&#x1EE3;c thi&#x1EBF;t k&#x1EBF; <strong>m&#x1ED9;t chi&#x1EC1;u</strong>: Workflow g&#x1ECD;i Skill, kh&#xF4;ng ph&#x1EA3;i ng&#x1B0;&#x1EE3;c l&#x1EA1;i. &#x110;&#xE2;y l&#xE0; thi&#x1EBF;t k&#x1EBF; c&#xF3; ch&#x1EE7; &#x111;&#xED;ch &#x2014; Skill l&#xE0; chuy&#xEA;n gia th&#x1EE5; &#x111;&#x1ED9;ng, kh&#xF4;ng ph&#x1EA3;i actor &#x111;i&#x1EC1;u ph&#x1ED1;i.</p><pre><code>Lu&#x1ED3;ng ch&#xED;nh th&#x1EE9;c:
Workflow  &#x2500;&#x2500;g&#x1ECD;i&#x2500;&#x2500;&#x25B6;  Skill A          &#x2713; ch&#xED;nh th&#x1EE9;c
Workflow  &#x2500;&#x2500;g&#x1ECD;i&#x2500;&#x2500;&#x25B6;  Skill B          &#x2713; ch&#xED;nh th&#x1EE9;c
Workflow  &#x2500;&#x2500;g&#x1ECD;i&#x2500;&#x2500;&#x25B6;  Workflow          &#x2713; qua // run workflow:
Skill     &#x2500;&#x2500;ch&#x1EA1;y&#x2500;&#x2500;&#x25B6; script.sh         &#x2713; ch&#xED;nh th&#x1EE9;c

Kh&#xF4;ng ch&#xED;nh th&#x1EE9;c (workaround):
Skill     &#x2500;&#x2500;&quot;g&#x1EE3;i &#xFD;&quot;&#x2500;&#x2500;&#x25B6; Workflow       &#x25B3; semantic, agent c&#xF3; th&#x1EC3; kh&#xF4;ng l&#xE0;m theo
</code></pre><h3 id="best-practice-workflow-l%C3%A0-orchestrator-skill-l%C3%A0-specialist">Best practice: Workflow l&#xE0; orchestrator, Skill l&#xE0; specialist</h3><pre><code class="language-markdown"># .agent/workflows/ship-feature.md
---
description: Ship m&#x1ED9;t feature ho&#xE0;n ch&#x1EC9;nh &#x2014; review, build, publish
---

1. Ki&#x1EC3;m tra kh&#xF4;ng c&#xF3; uncommitted changes // turbo &apos;git status&apos;

// parallel
2. Lint v&#xE0; format // turbo &apos;swiftlint lint &amp;&amp; swift-format .&apos;
3. Ch&#x1EA1;y test suite // turbo &apos;xcodebuild test&apos;
// end parallel

4. D&#xF9;ng mvvm-swiftui skill &#x111;&#x1EC3; review ViewModel m&#x1EDB;i
5. D&#xF9;ng accessibility-audit skill &#x111;&#x1EC3; ki&#x1EC3;m tra View m&#x1EDB;i

// if t&#x1EA5;t c&#x1EA3; passed
// run workflow: build-archive
// run workflow: publish-testflight
// end if
</code></pre><h3 id="khi-n%C3%A0o-d%C3%B9ng-c%C3%A1i-g%C3%AC">Khi n&#xE0;o d&#xF9;ng c&#xE1;i g&#xEC;</h3><!--kg-card-begin: html--><table>
<thead>
<tr>
<th>Ch&#x1EC9; d&#xF9;ng</th>
<th>Khi</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Skill</strong></td>
<td>N&#x1ED9;i dung l&#xE0; &quot;c&#xE1;ch l&#xE0;m &#x111;&#xFA;ng&quot; &#x2014; pattern, heuristic, nguy&#xEA;n t&#x1EAF;c ki&#x1EBF;n tr&#xFA;c</td>
</tr>
<tr>
<td><strong>Workflow</strong></td>
<td>C&#xF3; th&#x1EE9; t&#x1EF1; c&#x1EE9;ng, kh&#xF4;ng &#x111;&#x1B0;&#x1EE3;c b&#x1ECF; b&#x1B0;&#x1EDB;c; c&#xF3; l&#x1EC7;nh terminal th&#x1EF1;c thi</td>
</tr>
<tr>
<td><strong>C&#x1EA3; hai</strong></td>
<td>Workflow c&#x1EA7;n ph&#xE1;n &#x111;o&#xE1;n th&#xF4;ng minh &#x1EDF; m&#x1ED9;t b&#x1B0;&#x1EDB;c &#x2192; nh&#xFA;ng Skill v&#xE0;o b&#x1B0;&#x1EDB;c &#x111;&#xF3;</td>
</tr>
<tr>
<td><strong>Kh&#xF4;ng n&#xEA;n</strong></td>
<td>&#x110;&#x1EB7;t l&#x1EC7;nh terminal trong Skill; &#x111;&#x1EB7;t ki&#x1EBF;n th&#x1EE9;c MVVM d&#xE0;i trong Workflow</td>
</tr>
</tbody>
</table><!--kg-card-end: html--><hr><h2 id="8-thi%E1%BA%BFt-l%E1%BA%ADp-th%E1%BB%B1c-t%E1%BA%BF-cho-swiftui">8. Thi&#x1EBF;t l&#x1EAD;p th&#x1EF1;c t&#x1EBF; cho SwiftUI</h2><h3 id="c%E1%BA%A5u-tr%C3%BAc-th%C6%B0-m%E1%BB%A5c-%C4%91%E1%BB%81-xu%E1%BA%A5t">C&#x1EA5;u tr&#xFA;c th&#x1B0; m&#x1EE5;c &#x111;&#x1EC1; xu&#x1EA5;t</h3><pre><code>project-root/
&#x251C;&#x2500;&#x2500; .agent/
&#x2502;   &#x251C;&#x2500;&#x2500; rules/
&#x2502;   &#x2502;   &#x251C;&#x2500;&#x2500; swift-standards.md      &#x2190; always_on: Swift 6, async/await
&#x2502;   &#x2502;   &#x251C;&#x2500;&#x2500; mvvm-rules.md           &#x2190; model_decision: MVVM patterns
&#x2502;   &#x2502;   &#x2514;&#x2500;&#x2500; swift-files.md          &#x2190; file_match: **/*.swift
&#x2502;   &#x2502;
&#x2502;   &#x251C;&#x2500;&#x2500; skills/
&#x2502;   &#x2502;   &#x251C;&#x2500;&#x2500; mvvm-swiftui/           &#x2190; @Observable, ViewModel, state
&#x2502;   &#x2502;   &#x251C;&#x2500;&#x2500; swiftdata-patterns/     &#x2190; SwiftData, migrations
&#x2502;   &#x2502;   &#x251C;&#x2500;&#x2500; swift-concurrency/      &#x2190; async/await, actors
&#x2502;   &#x2502;   &#x2514;&#x2500;&#x2500; accessibility-audit/    &#x2190; VoiceOver, Dynamic Type
&#x2502;   &#x2502;
&#x2502;   &#x2514;&#x2500;&#x2500; workflows/
&#x2502;       &#x251C;&#x2500;&#x2500; scaffold.md             &#x2190; /scaffold: t&#x1EA1;o View + VM + Tests
&#x2502;       &#x251C;&#x2500;&#x2500; review.md               &#x2190; /review: lint + MVVM check
&#x2502;       &#x251C;&#x2500;&#x2500; build-archive.md        &#x2190; /build-archive
&#x2502;       &#x251C;&#x2500;&#x2500; publish-testflight.md   &#x2190; /publish-testflight
&#x2502;       &#x2514;&#x2500;&#x2500; ci.md                   &#x2190; /ci: g&#x1ECD;i review + build + publish
&#x2502;
&#x2514;&#x2500;&#x2500; mcp_config.json                 &#x2190; XcodeBuildMCP, Apple Docs, swift-mcp
</code></pre><h3 id="workflow-scaffold-%E2%80%94-v%C3%AD-d%E1%BB%A5-th%E1%BB%B1c-t%E1%BA%BF">Workflow /scaffold &#x2014; v&#xED; d&#x1EE5; th&#x1EF1;c t&#x1EBF;</h3><pre><code class="language-markdown">---
description: T&#x1EA1;o SwiftUI View + ViewModel + Preview + Tests cho m&#x1ED9;t feature m&#x1EDB;i
---

1. H&#x1ECF;i t&#xEA;n feature v&#xE0; m&#xF4; t&#x1EA3; ng&#x1EAF;n (n&#x1EBF;u ch&#x1B0;a c&#xF3; trong prompt)

2. D&#xF9;ng mvvm-swiftui skill &#x111;&#x1EC3; thi&#x1EBF;t k&#x1EBF; ViewModel tr&#x1B0;&#x1EDB;c khi code

// parallel
3. T&#x1EA1;o {FeatureName}ViewModel.swift trong Models/
4. T&#x1EA1;o {FeatureName}View.swift trong Views/
// end parallel

5. T&#x1EA1;o {FeatureName}Tests.swift v&#x1EDB;i &#xED;t nh&#x1EA5;t 3 test cases

6. Build &#x111;&#x1EC3; ki&#x1EC3;m tra compile // turbo &apos;xcodebuild build -scheme MyApp&apos;

// if build th&#x1EA5;t b&#x1EA1;i
7. Ph&#xE2;n t&#xED;ch l&#x1ED7;i v&#xE0; fix t&#x1EF1; &#x111;&#x1ED9;ng
// end if
</code></pre><h3 id="workflow-review-%E2%80%94-t%C3%ADch-h%E1%BB%A3p-skill-v%C3%A0o-pipeline">Workflow /review &#x2014; t&#xED;ch h&#x1EE3;p skill v&#xE0;o pipeline</h3><pre><code class="language-markdown">---
description: Code review SwiftUI tr&#x1B0;&#x1EDB;c khi merge &#x2014; lint, MVVM, accessibility
---

// parallel
1. Ch&#x1EA1;y SwiftLint // turbo &apos;swiftlint lint&apos;
2. Build ki&#x1EC3;m tra compile // turbo &apos;xcodebuild build&apos;
// end parallel

3. D&#xF9;ng mvvm-swiftui skill &#x111;&#x1EC3; &#x111;&#xE1;nh gi&#xE1; ViewModel trong diff
4. D&#xF9;ng accessibility-audit skill &#x111;&#x1EC3; ki&#x1EC3;m tra View m&#x1EDB;i

5. T&#x1ED5;ng h&#x1EE3;p v&#xE0; report nh&#x1EEF;ng v&#x1EA5;n &#x111;&#x1EC1; c&#x1EA7;n fix theo m&#x1EE9;c &#x111;&#x1ED9; &#x1B0;u ti&#xEA;n
</code></pre><hr><h2 id="9-nh%E1%BB%AFng-%C4%91i%E1%BB%81u-c%E1%BA%A7n-bi%E1%BA%BFt">9. Nh&#x1EEF;ng &#x111;i&#x1EC1;u c&#x1EA7;n bi&#x1EBF;t</h2><h3 id="workflow-kh%C3%B4ng-deterministic">Workflow kh&#xF4;ng deterministic</h3><p>Workflow l&#xE0; instruction cho LLM, kh&#xF4;ng ph&#x1EA3;i bash script. Agent c&#xF3; th&#x1EC3; di&#x1EC5;n gi&#x1EA3;i kh&#xE1;c &#x111;i t&#xF9;y context. Khi c&#x1EA7;n k&#x1EBF;t qu&#x1EA3; ch&#xED;nh x&#xE1;c, d&#xF9;ng <code>// turbo</code> v&#x1EDB;i l&#x1EC7;nh c&#x1EE5; th&#x1EC3; thay v&#xEC; instruction t&#x1EF1; nhi&#xEA;n m&#x1A1; h&#x1ED3;.</p><p>&#x274C; M&#x1A1; h&#x1ED3;:</p><pre><code class="language-markdown">3. Ki&#x1EC3;m tra xem code c&#xF3; v&#x1EA5;n &#x111;&#x1EC1; g&#xEC; kh&#xF4;ng
</code></pre><p>&#x2705; C&#x1EE5; th&#x1EC3;:</p><pre><code class="language-markdown">3. Ch&#x1EA1;y SwiftLint v&#xE0; b&#xE1;o c&#xE1;o violations // turbo &apos;swiftlint lint --reporter json&apos;
</code></pre><h3 id="workflow-kh%C3%B4ng-c%C3%B3-memory-gi%E1%BB%AFa-c%C3%A1c-l%E1%BA%A7n-ch%E1%BA%A1y">Workflow kh&#xF4;ng c&#xF3; memory gi&#x1EEF;a c&#xE1;c l&#x1EA7;n ch&#x1EA1;y</h3><p>M&#x1ED7;i l&#x1EA7;n g&#xF5; <code>/ten-workflow</code> l&#xE0; session m&#x1EDB;i ho&#xE0;n to&#xE0;n. Agent kh&#xF4;ng nh&#x1EDB; l&#x1EA7;n tr&#x1B0;&#x1EDB;c k&#x1EBF;t qu&#x1EA3; ra sao, l&#x1ED7;i g&#xEC; &#x111;&#xE3; x&#x1EA3;y ra. N&#x1EBF;u mu&#x1ED1;n gi&#x1EEF; context, l&#x1B0;u v&#xE0;o file trong project ho&#x1EB7;c truy&#x1EC1;n qua prompt.</p><h3 id="turbo-v%C3%A0-quy%E1%BB%81n-t%E1%BB%B1-ch%E1%BB%A7"><code>// turbo</code> v&#xE0; quy&#x1EC1;n t&#x1EF1; ch&#x1EE7;</h3><p>Kh&#xF4;ng c&#xF3; <code>// turbo</code> &#x2192; agent d&#x1EEB;ng h&#x1ECF;i b&#x1EA1;n tr&#x1B0;&#x1EDB;c khi ch&#x1EA1;y l&#x1EC7;nh. C&#xF3; <code>// turbo</code> &#x2192; agent t&#x1EF1; &#x111;&#x1ED9;ng th&#x1EF1;c thi. Khuy&#x1EBF;n ngh&#x1ECB;: b&#x1EAF;t &#x111;&#x1EA7;u kh&#xF4;ng c&#xF3; <code>turbo</code> cho t&#x1EA5;t c&#x1EA3; b&#x1B0;&#x1EDB;c quan tr&#x1ECD;ng cho &#x111;&#x1EBF;n khi b&#x1EA1;n tin t&#x1B0;&#x1EDF;ng workflow.</p><h3 id="rules-d%C3%B9ng-alwayson-th%E1%BA%ADt-%C3%ADt">Rules: d&#xF9;ng <code>always_on</code> th&#x1EAD;t &#xED;t</h3><p><code>always_on</code> inject rule v&#xE0;o <em>m&#x1ECD;i</em> request, k&#x1EC3; c&#x1EA3; khi kh&#xF4;ng li&#xEA;n quan &#x2014; t&#x1ED1;n token, t&#x103;ng latency. &#x1AF;u ti&#xEA;n <code>model_decision</code> v&#x1EDB;i description r&#xF5; r&#xE0;ng. Agent &#x111;&#x1EE7; th&#xF4;ng minh &#x111;&#x1EC3; t&#x1EF1; ch&#x1ECD;n &#x111;&#xFA;ng.</p><h3 id="skills-l%C3%A0-living-documents">Skills l&#xE0; &quot;living documents&quot;</h3><p>Khi skill kh&#xF4;ng ho&#x1EA1;t &#x111;&#x1ED9;ng &#x111;&#xFA;ng, &#x111;&#x1EEB;ng fix th&#x1EE7; c&#xF4;ng &#x2014; nh&#x1EDD; agent t&#xEC;m gi&#x1EA3;i ph&#xE1;p r&#x1ED3;i c&#x1EAD;p nh&#x1EAD;t <code>SKILL.md</code>. Skill s&#x1EBD; h&#x1ECD;c t&#x1EEB; l&#x1EA7;n s&#x1EED;a &#x111;&#xF3; v&#xE0; kh&#xF4;ng l&#x1EB7;p l&#x1EA1;i sai l&#x1EA7;m t&#x1B0;&#x1A1;ng t&#x1EF1;.</p><hr><h2 id="t%C3%B3m-l%E1%BA%A1i">T&#xF3;m l&#x1EA1;i</h2><!--kg-card-begin: html--><table>
<thead>
<tr>
<th>Ch&#x1ECD;n</th>
<th>Khi n&#xE0;o</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>MCP</strong></td>
<td>C&#x1EA7;n agent th&#x1EF1;c s&#x1EF1; <em>l&#xE0;m</em> &#x111;i&#x1EC1;u g&#xEC; &#x111;&#xF3; &#x2014; build app, query DB, g&#x1ECD;i API</td>
</tr>
<tr>
<td><strong>Rules</strong></td>
<td>C&#xF3; quy t&#x1EAF;c c&#x1EA7;n lu&#xF4;n tu&#xE2;n th&#x1EE7; &#x2014; code style, ki&#x1EBF;n tr&#xFA;c b&#x1EAF;t bu&#x1ED9;c</td>
</tr>
<tr>
<td><strong>Skills</strong></td>
<td>C&#xF3; ki&#x1EBF;n th&#x1EE9;c chuy&#xEA;n s&#xE2;u c&#x1EA7;n apply theo ng&#x1EEF; c&#x1EA3;nh &#x2014; MVVM, SwiftData, accessibility</td>
</tr>
<tr>
<td><strong>Workflows</strong></td>
<td>C&#xF3; quy tr&#xEC;nh l&#x1EB7;p l&#x1EA1;i v&#x1EDB;i th&#x1EE9; t&#x1EF1; c&#x1ED1; &#x111;&#x1ECB;nh &#x2014; CI pipeline, feature scaffold, release</td>
</tr>
</tbody>
</table><!--kg-card-end: html--><pre><code>MCP         &#x2192; Tool ngo&#xE0;i: XcodeBuildMCP, Apple Docs MCP
Rules       &#x2192; &quot;Lu&#xF4;n d&#xF9;ng @Observable, async/await, guard let&quot;
Skills      &#x2192; mvvm-swiftui/ (load khi h&#x1ECF;i v&#x1EC1; ViewModel/state)
Workflows   &#x2192; /scaffold, /review, /ci, /ship-feature
</code></pre>]]></content:encoded></item><item><title><![CDATA[How I Spent Two Days Fighting a Workflow Engine — and What I Actually Learned]]></title><description><![CDATA[A debugging post-mortem on OpenClaw Lobster, llm-task, and the real cost of trusting AI-generated diagnoses.]]></description><link>https://makexyz.fun/how-i-spent-two-days-fighting-a-workflow-engine-and-what-i-actually-learned/</link><guid isPermaLink="false">69cae7206aaeabec02e09b3c</guid><category><![CDATA[AI]]></category><category><![CDATA[OpenClaw]]></category><category><![CDATA[Lobster]]></category><category><![CDATA[Tips & Tricks]]></category><dc:creator><![CDATA[Tony Phạm]]></dc:creator><pubDate>Mon, 30 Mar 2026 21:12:57 GMT</pubDate><content:encoded><![CDATA[<p><em>A debugging post-mortem on OpenClaw Lobster, llm-task, and the real cost of trusting AI-generated diagnoses.</em></p><hr><p>I&apos;m building a curriculum generation system for a PBL-based Python course. The idea is straightforward: a multi-phase workflow that calls an LLM at each step to produce requirements, constraints, research notes, lesson materials &#x2014; all written to disk as Markdown files, ready for review.</p><p>The orchestration layer is <a href="https://docs.openclaw.ai/tools/lobster">Lobster</a>, a workflow shell built into OpenClaw. The LLM step is handled by <code>llm-task</code>, an optional plugin that runs a JSON-only, stateless model call and returns structured output validated against a JSON Schema.</p><p>On paper, this is exactly what these tools were designed for. In practice, it took 12 test scenarios, several misdiagnoses (some by me, some by the AI agent helping me), and a lot of <code>lobster run ... 2&gt;&amp;1</code> before I understood what was actually happening.</p><p>This is the full story.</p><hr><h2 id="the-setup">The Setup</h2><p>My workflow looked roughly like this:</p><pre><code>build_payload.py &#x2192; Lobster &#x2192; openclaw.invoke &#x2192; llm-task &#x2192; save to disk
</code></pre><p>The Python script constructs a payload for each phase (prompt, model, schema, temperature), passes it to Lobster, which calls <code>openclaw.invoke --tool llm-task</code> with the payload as <code>--args-json</code>, and the output gets extracted and written to a file.</p><p>Simple. Clean. Deterministic.</p><p>The first test &#x2014; a hardcoded <code>&quot;say hi&quot;</code> prompt with a static <code>--args-json</code> &#x2014; worked immediately:</p><pre><code class="language-yaml">steps:
  - id: test_invoke
    pipeline: openclaw.invoke --tool llm-task --action json --args-json &apos;{&quot;prompt&quot;:&quot;say hi&quot;,&quot;model&quot;:&quot;gemini-2.5-flash&quot;}&apos;
</code></pre><p>Exit code 0. Output:</p><pre><code class="language-json">[{
  &quot;content&quot;: [{&quot;type&quot;: &quot;text&quot;, &quot;text&quot;: &quot;{\&quot;status\&quot;: \&quot;ok\&quot;}&quot;}],
  &quot;details&quot;: { &quot;json&quot;: {&quot;status&quot;: &quot;ok&quot;}, &quot;provider&quot;: &quot;google&quot;, &quot;model&quot;: &quot;gemini-2.5-flash&quot; }
}]
</code></pre><p>Great. Now I just need to make the payload dynamic.</p><hr><h2 id="the-core-problem-that-took-two-days-to-name-correctly">The Core Problem (That Took Two Days to Name Correctly)</h2><p>Here is the thing about Lobster: <strong>it does not interpolate variables inside a <code>pipeline:</code> string&apos;s argument values.</strong></p><p>When you write:</p><pre><code class="language-yaml">- id: invoke
  pipeline: openclaw.invoke --tool llm-task --action json --args-json &apos;$prepare.stdout&apos;
</code></pre><p>Lobster does not resolve <code>$prepare.stdout</code> into the actual content of that step&apos;s stdout. It passes the literal string <code>$prepare.stdout</code> to <code>openclaw.invoke</code>. The tool receives <code>&quot;$prepare.stdout&quot;</code> as the JSON payload &#x2014; which is not valid JSON &#x2014; and returns a 500.</p><p>This seems obvious in hindsight. But when you&apos;re staring at a <code>tool execution failed</code> error with no further detail, and the static version works perfectly, you start looking in every other direction first.</p><hr><h2 id="misdiagnosis-1-the-allowlist">Misdiagnosis #1: The Allowlist</h2><p>The first theory &#x2014; partly because an early error log mentioned it &#x2014; was that <code>llm-task</code> was blocked by a platform allowlist on macOS (&quot;darwin&quot;):</p><pre><code>llm-task.json is not in the allowlist for platform &quot;darwin&quot;
</code></pre><p>So I checked the config. Everything was already correct:</p><pre><code class="language-json">{
  &quot;plugins&quot;: {
    &quot;entries&quot;: {
      &quot;llm-task&quot;: { &quot;enabled&quot;: true }
    }
  },
  &quot;tools&quot;: {
    &quot;alsoAllow&quot;: [&quot;llm-task&quot;]
  }
}
</code></pre><p>The log entry was stale &#x2014; from before the config was set up properly. The allowlist was never the problem. But it ate an hour.</p><p><strong>Lesson:</strong> Don&apos;t treat old log lines as current diagnostics. Reproduce the error first, then read the logs.</p><hr><h2 id="misdiagnosis-2-payload-size">Misdiagnosis #2: Payload Size</h2><p>Next theory: the Gateway was crashing because the Vietnamese prompts were too long.</p><p>Evidence cited: short prompts like <code>&quot;say hi&quot;</code> passed, while longer curriculum prompts failed.</p><p>This led to the suggestion of trimming prompts, splitting tasks, and eventually building <code>direct_gemini.py</code> &#x2014; a script that called the Gemini API directly, bypassing Lobster and llm-task entirely, as a &quot;bridge&quot; workaround.</p><pre><code class="language-python"># direct_gemini.py
url = f&quot;https://generativelanguage.googleapis.com/v1beta/models/{model}:generateContent?key={api_key}&quot;
</code></pre><p>The problem with this approach: it exposed the API key in process arguments (<code>ps aux</code> readable), dropped JSON Schema validation, and disconnected from OpenClaw&apos;s auth profile system. It worked, but it was the wrong fix for the wrong problem.</p><p>The real reason short prompts passed and long ones failed had nothing to do with payload size. The hardcoded short test used a literal <code>--args-json &apos;{...}&apos;</code>. The longer tests were trying to interpolate a variable into that string. The variable contained newlines. Newlines broke JSON parsing. It was a quoting and interpolation problem all along.</p><p><strong>Lesson:</strong> When a workaround &quot;works,&quot; resist the urge to ship it. Ask whether it&apos;s fixing the actual failure mode or just routing around it.</p><hr><h2 id="misdiagnosis-3-theeach-pattern">Misdiagnosis #3: The <code>--each</code> Pattern</h2><p>After reading the docs more carefully, I found a pattern that looked promising:</p><pre><code>gog.gmail.search --query &apos;...&apos; | openclaw.invoke --tool message --action send --each --item-key message
</code></pre><p><code>--each</code> reads a JSON array from stdin and calls the tool once per item, merging each item&apos;s fields into the tool&apos;s args. So if my Python script output <code>[{&quot;task&quot;: {...payload...}}]</code>, then <code>--each --item-key task</code> would extract the payload and pass it as args &#x2014; no <code>--args-json</code> needed, no interpolation issue.</p><p>I rewrote <code>build_payload.py</code> to output <code>[{&quot;task&quot;: payload}]</code>, updated the workflow, ran it. Still 500.</p><p>Two rounds of debugging later: <code>--each</code> with <code>llm-task</code> is not stable in Lobster. The mechanism works for some tools, but for <code>llm-task</code> in this context it was failing at the argument extraction layer. This was confirmed in the final test matrix.</p><p><strong>Lesson:</strong> Docs examples are illustrative, not guaranteed. Test patterns in isolation before building on them.</p><hr><h2 id="the-test-matrix">The Test Matrix</h2><p>At this point, instead of theorizing, I built a systematic test suite. Twelve <code>.lobster</code> files, each testing one specific mechanism:</p><!--kg-card-begin: html--><table>
<thead>
<tr>
<th>Scenario</th>
<th>Result</th>
<th>Finding</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>verify_json_pipe.lobster</code></td>
<td>&#x2705; Pass</td>
<td><code>$step.json</code> is real and works</td>
</tr>
<tr>
<td><code>verify_echo.lobster</code></td>
<td>&#x2705; Pass</td>
<td>Lobster preserves <code>\n</code> literally when resolving vars &#x2014; breaks JSON</td>
</tr>
<tr>
<td><code>verify_vars</code> / <code>verify_final</code> / <code>verify_global</code></td>
<td>&#x274C; Fail</td>
<td>Lobster does NOT interpolate vars inside <code>pipeline: ...</code> strings</td>
</tr>
<tr>
<td><code>verify_each</code> / <code>verify_stdin</code> / <code>verify_native</code></td>
<td>&#x274C; Fail</td>
<td><code>openclaw.invoke --each</code> is unreliable for <code>llm-task</code> in Lobster</td>
</tr>
<tr>
<td><code>verify_shell.lobster</code></td>
<td>&#x274C; Fail</td>
<td>Classic shell quote-nesting when passing JSON via variable</td>
</tr>
</tbody>
</table><!--kg-card-end: html--><p>Two findings from this matrix changed everything:</p><p><strong>Finding 1 &#x2014; <code>$step.json</code> is real.</strong> After a step runs <code>openclaw.invoke --action json</code>, Lobster parses the output and makes the result available as <code>$step_id.json</code> &#x2014; a pre-parsed object, not a raw string. This means downstream steps can receive a clean JSON object via <code>stdin</code>, with no manual parsing.</p><p><strong>Finding 2 &#x2014; Lobster preserves <code>\n</code> literally.</strong> When a variable like <code>$prepare.stdout</code> is interpolated into any context, newline characters are kept as-is. If the stdout content gets embedded in a JSON string, those literal newlines make the JSON invalid. This is why piping Python output directly into a Lobster pipeline string always broke.</p><hr><h2 id="the-architecture-that-actually-works">The Architecture That Actually Works</h2><p>Given these constraints, the correct architecture is:</p><pre><code>Python (build payload + call llm-task via HTTP or subprocess)
  &#x2193; stdout = JSON string
Lobster command step (just runs Python, no JSON touch)
  &#x2193; $step.json (Lobster parses stdout)
Python file_manager.py (receives parsed object, extracts field, saves)
</code></pre><p>The key insight: <strong>Python handles all JSON construction and tool invocation. Lobster handles only sequencing and file piping.</strong></p><p>The workflow becomes clean and dumb:</p><pre><code class="language-yaml">steps:
  - id: ph1_requirements
    command: python3 &quot;${skill_dir}/tools/llm_invoker.py&quot; --phase ph1_requirements

  - id: save_requirements
    after: ph1_requirements
    stdin: $ph1_requirements.json
    command: python3 &quot;${skill_dir}/tools/file_manager.py&quot; save
      --path &quot;${root}/00_meta/requirements.md&quot;
      --extract-field content

  - id: ph1_constraints
    after: save_requirements
    command: python3 &quot;${skill_dir}/tools/llm_invoker.py&quot; --phase ph1_constraints

  # ...and so on
</code></pre><p><code>llm_invoker.py</code> calls the OpenClaw Gateway directly via HTTP, constructs the full payload in Python (no escaping issues, no encoding issues, Unicode-safe by default), and prints the response JSON to stdout. Lobster parses it into <code>$step.json</code>. <code>file_manager.py</code> receives a clean Python dict.</p><p>No transient <code>.lobster</code> files. No <code>--args-json</code> with dynamic content. No <code>--each</code>. No shell quoting gymnastics.</p><hr><h2 id="what-the-ai-agent-got-wrong">What the AI Agent Got Wrong</h2><p>I was using an AI agent throughout this process to help debug. It was useful for generating test variants quickly, but it misdiagnosed the root cause at least three times:</p><ol><li><strong>Blamed the allowlist</strong> when the config was already correct.</li><li><strong>Blamed payload size</strong> when the issue was interpolation.</li><li><strong>Endorsed <code>direct_gemini.py</code></strong> as a valid long-term solution, including documenting it in a &quot;Best Practices&quot; file &#x2014; despite it having a security flaw (API key exposed in process args) and losing schema validation.</li></ol><p>The agent also produced a &quot;Best Practices&quot; document that contained a bug in the headline example:</p><pre><code class="language-yaml"># From the agent&apos;s &quot;verified&quot; best practices doc:
pipeline: |
  openclaw.invoke --tool llm-task --action run --args-json &apos;$prepare.stdout&apos;
</code></pre><p><code>&apos;$prepare.stdout&apos;</code> in single quotes is a literal string. This is exactly the pattern that fails. The document marked it as verified.</p><p>The agent was confident, articulate, and wrong. Each misdiagnosis came with a coherent explanation that sounded plausible &#x2014; and that&apos;s what makes this kind of failure expensive. A vague error is easy to distrust. A confident, detailed explanation is much harder to push back on, especially when you&apos;re deep in a debugging session.</p><p><strong>The only thing that resolved the ambiguity was running actual tests and building an explicit result matrix.</strong></p><hr><h2 id="rules-for-working-with-lobster-llm-task">Rules for Working with Lobster + llm-task</h2><p>Based on everything above, here&apos;s what&apos;s actually verified:</p><p><strong>Do:</strong></p><ul><li>Use <code>$step.json</code> to receive <code>llm-task</code> output in downstream steps &#x2014; it&apos;s real, it&apos;s clean, it works.</li><li>Handle all JSON construction in Python. No exceptions.</li><li>Call the OpenClaw Gateway directly from Python (HTTP POST) rather than trying to pass dynamic payloads through Lobster&apos;s pipeline layer.</li><li>Use <code>command:</code> steps for Python scripts. Keep <code>pipeline:</code> steps for static, hardcoded <code>openclaw.invoke</code> calls only.</li><li>Build a test matrix when debugging. One scenario per file, one variable changed at a time.</li></ul><p><strong>Don&apos;t:</strong></p><ul><li>Try to interpolate <code>$step.stdout</code> into a <code>pipeline:</code> argument string. It will not work.</li><li>Use <code>--each</code> with <code>llm-task</code> in Lobster. Unstable.</li><li>Trust &quot;verified&quot; documentation produced by an AI agent unless you ran the test yourself.</li><li>Accept a workaround that bypasses the system&apos;s auth and validation layers, even if it unblocks you in the moment.</li></ul><hr><h2 id="closing-thought">Closing Thought</h2><p>The irony of this whole experience is that the final architecture is simpler than the original design. Python does what Python is good at. Lobster does what Lobster is good at. The two don&apos;t try to hand off dynamic JSON to each other through shell string interpolation.</p><p>The path to that simplicity, though, ran through twelve failing test files, three misdiagnoses, one unnecessary security hole, and a &quot;Best Practices&quot; document with a bug in the first example.</p><p>If you&apos;re building deterministic AI pipelines on top of a workflow engine you don&apos;t fully understand yet: <strong>test the primitives first, build the matrix before you build the system, and be skeptical of any diagnosis &#x2014; including your own &#x2014; that you haven&apos;t reproduced with a minimal test case.</strong></p><hr><p><em>Built with OpenClaw Lobster + Gemini 2.5 Flash. Tests run on macOS (darwin), Gateway v2026.2.x.</em></p>]]></content:encoded></item><item><title><![CDATA[Lobster & OpenProse — Bộ Đôi Kiểm Soát Quy Trình Trong OpenClaw]]></title><description><![CDATA[Dành cho người dùng OpenClaw đang xây dựng các quy trình tác nhân phức tạp và muốn hiểu đúng vai trò của từng công cụ trước khi thiết kế hệ thống.]]></description><link>https://makexyz.fun/lobster-openprose-bo-doi-kiem-soat-quy-trinh-trong-openclaw/</link><guid isPermaLink="false">69c892582db75f31a212e38d</guid><category><![CDATA[AI]]></category><dc:creator><![CDATA[Tony Phạm]]></dc:creator><pubDate>Sun, 29 Mar 2026 02:46:39 GMT</pubDate><content:encoded><![CDATA[<blockquote><strong>D&#xE0;nh cho ai:</strong> Ng&#x1B0;&#x1EDD;i d&#xF9;ng OpenClaw &#x111;ang x&#xE2;y d&#x1EF1;ng c&#xE1;c quy tr&#xEC;nh t&#xE1;c nh&#xE2;n ph&#x1EE9;c t&#x1EA1;p v&#xE0; mu&#x1ED1;n hi&#x1EC3;u &#x111;&#xFA;ng vai tr&#xF2; c&#x1EE7;a t&#x1EEB;ng c&#xF4;ng c&#x1EE5; tr&#x1B0;&#x1EDB;c khi thi&#x1EBF;t k&#x1EBF; h&#x1EC7; th&#x1ED1;ng.</blockquote><hr><h2 id="m%E1%BB%A5c-l%E1%BB%A5c">M&#x1EE5;c l&#x1EE5;c</h2><ol><li><a href="https://claude.ai/chat/3135436b-3507-40c0-8c6b-2124cd5a576d#1-v%E1%BA%A5n-%C4%91%E1%BB%81-m%C3%A0-c%E1%BA%A3-hai-c%C3%B9ng-gi%E1%BA%A3i-quy%E1%BA%BFt">V&#x1EA5;n &#x111;&#x1EC1; m&#xE0; c&#x1EA3; hai c&#xF9;ng gi&#x1EA3;i quy&#x1EBF;t</a></li><li><a href="https://claude.ai/chat/3135436b-3507-40c0-8c6b-2124cd5a576d#2-lobster--v%E1%BB%8F-ch%E1%BA%A1y-quy-tr%C3%ACnh-t%E1%BA%A5t-%C4%91%E1%BB%8Bnh">Lobster &#x2014; V&#x1ECF; Ch&#x1EA1;y Quy Tr&#xEC;nh T&#x1EA5;t &#x110;&#x1ECB;nh</a></li><li><a href="https://claude.ai/chat/3135436b-3507-40c0-8c6b-2124cd5a576d#3-openprose--ng%C3%B4n-ng%E1%BB%AF-%C4%91i%E1%BB%81u-ph%E1%BB%91i-phi%C3%AAn-ai">OpenProse &#x2014; Ng&#xF4;n Ng&#x1EEF; &#x110;i&#x1EC1;u Ph&#x1ED1;i Phi&#xEA;n AI</a></li><li><a href="https://claude.ai/chat/3135436b-3507-40c0-8c6b-2124cd5a576d#4-sai-l%E1%BA%A7m-ph%E1%BB%95-bi%E1%BA%BFn-d%C3%B9ng-lobster-m%E1%BB%99t-m%C3%ACnh-cho-t%E1%BA%A5t-c%E1%BA%A3">Sai L&#x1EA7;m Ph&#x1ED5; Bi&#x1EBF;n: D&#xF9;ng Lobster M&#x1ED9;t M&#xEC;nh Cho T&#x1EA5;t C&#x1EA3;</a></li><li><a href="https://claude.ai/chat/3135436b-3507-40c0-8c6b-2124cd5a576d#5-ph%C3%A2n-chia-vai-tr%C3%B2-%C4%91%C3%BAng">Ph&#xE2;n Chia Vai Tr&#xF2; &#x110;&#xFA;ng</a></li><li><a href="https://claude.ai/chat/3135436b-3507-40c0-8c6b-2124cd5a576d#6-k%E1%BA%BFt-h%E1%BB%A3p-openprose--lobster-c%C3%A1ch-l%C3%A0m-chu%E1%BA%A9n">K&#x1EBF;t H&#x1EE3;p OpenProse + Lobster: C&#xE1;ch L&#xE0;m Chu&#x1EA9;n</a></li><li><a href="https://claude.ai/chat/3135436b-3507-40c0-8c6b-2124cd5a576d#7-k%E1%BA%BFt-lu%E1%BA%ADn">K&#x1EBF;t Lu&#x1EAD;n</a></li></ol><hr><h2 id="1-v%E1%BA%A5n-%C4%91%E1%BB%81-m%C3%A0-c%E1%BA%A3-hai-c%C3%B9ng-gi%E1%BA%A3i-quy%E1%BA%BFt">1. V&#x1EA5;n &#x111;&#x1EC1; m&#xE0; c&#x1EA3; hai c&#xF9;ng gi&#x1EA3;i quy&#x1EBF;t</h2><p>Khi y&#xEA;u c&#x1EA7;u m&#x1ED9;t t&#xE1;c nh&#xE2;n AI th&#x1EF1;c hi&#x1EC7;n m&#x1ED9;t quy tr&#xEC;nh nhi&#x1EC1;u b&#x1B0;&#x1EDB;c &#x2014; nghi&#xEA;n c&#x1EE9;u, t&#x1ED5;ng h&#x1EE3;p, g&#x1EED;i email, c&#x1EAD;p nh&#x1EAD;t t&#x1EC7;p &#x2014; &#x111;i&#x1EC1;u th&#x1B0;&#x1EDD;ng x&#x1EA3;y ra l&#xE0;:</p><ul><li>T&#xE1;c nh&#xE2;n ph&#x1EA3;i <strong>l&#xEA;n k&#x1EBF; ho&#x1EA1;ch l&#x1EA1;i t&#x1EEB;ng b&#x1B0;&#x1EDB;c</strong> t&#x1EEB; &#x111;&#x1EA7;u, ti&#xEA;u t&#x1ED1;n token l&#xE3;ng ph&#xED;.</li><li>T&#xE1;c nh&#xE2;n t&#x1EF1; quy&#x1EBF;t &#x111;&#x1ECB;nh th&#x1EF1;c hi&#x1EC7;n c&#xE1;c h&#xE0;nh &#x111;&#x1ED9;ng c&#xF3; <strong>t&#xE1;c d&#x1EE5;ng ph&#x1EE5;</strong> (g&#x1EED;i tin nh&#x1EAF;n, ghi t&#x1EC7;p, g&#x1ECD;i API ngo&#xE0;i) m&#xE0; kh&#xF4;ng c&#xF3; &#x111;i&#x1EC3;m d&#x1EEB;ng &#x111;&#x1EC3; ki&#x1EC3;m so&#xE1;t.</li><li>Khi quy tr&#xEC;nh b&#x1ECB; gi&#xE1;n &#x111;o&#x1EA1;n gi&#x1EEF;a ch&#x1EEB;ng, kh&#xF4;ng c&#xF3; c&#xE1;ch n&#xE0;o ti&#x1EBF;p t&#x1EE5;c t&#x1EEB; &#x111;&#xFA;ng &#x111;i&#x1EC3;m &#x111;&#xE3; d&#x1EEB;ng.</li><li>Trong c&#xE1;c quy tr&#xEC;nh &#x111;a t&#xE1;c nh&#xE2;n ph&#x1EE9;c t&#x1EA1;p, ng&#x1EEF; c&#x1EA3;nh c&#x1EE7;a phi&#xEA;n ch&#xED;nh b&#x1ECB; ph&#xEC;nh to qu&#xE1; m&#x1EE9;c.</li></ul><p>OpenClaw gi&#x1EA3;i quy&#x1EBF;t nh&#x1EEF;ng v&#x1EA5;n &#x111;&#x1EC1; n&#xE0;y b&#x1EB1;ng hai plugin b&#x1ED5; sung cho nhau: <strong>Lobster</strong> v&#xE0; <strong>OpenProse</strong>. Hai c&#xF4;ng c&#x1EE5; n&#xE0;y kh&#xF4;ng c&#x1EA1;nh tranh &#x2014; ch&#xFA;ng ho&#x1EA1;t &#x111;&#x1ED9;ng &#x1EDF; hai t&#x1EA7;ng kh&#xE1;c nhau v&#xE0; ph&#x1EE5;c v&#x1EE5; hai nhu c&#x1EA7;u kh&#xE1;c nhau.</p><p>Hi&#x1EC3;u r&#xF5; ranh gi&#x1EDB;i &#x111;&#xF3; l&#xE0; ch&#xEC;a kh&#xF3;a &#x111;&#x1EC3; thi&#x1EBF;t k&#x1EBF; h&#x1EC7; th&#x1ED1;ng &#x111;&#xFA;ng.</p><hr><h2 id="2-lobster-%E2%80%94-v%E1%BB%8F-ch%E1%BA%A1y-quy-tr%C3%ACnh-t%E1%BA%A5t-%C4%91%E1%BB%8Bnh">2. Lobster &#x2014; V&#x1ECF; Ch&#x1EA1;y Quy Tr&#xEC;nh T&#x1EA5;t &#x110;&#x1ECB;nh</h2><h3 id="21-lobster-l%C3%A0-g%C3%AC">2.1 Lobster l&#xE0; g&#xEC;?</h3><p>Lobster l&#xE0; m&#x1ED9;t <strong>v&#x1ECF; ch&#x1EA1;y quy tr&#xEC;nh</strong> (workflow shell) &#x2014; m&#x1ED9;t m&#xF4;i tr&#x1B0;&#x1EDD;ng th&#x1EF1;c thi c&#xF3; ki&#x1EC3;u d&#x1EEF; li&#x1EC7;u, cho ph&#xE9;p OpenClaw th&#x1EF1;c thi chu&#x1ED7;i l&#x1EC7;nh shell/CLI theo th&#x1EE9; t&#x1EF1; x&#xE1;c &#x111;&#x1ECB;nh, truy&#x1EC1;n d&#x1EEF; li&#x1EC7;u JSON gi&#x1EEF;a c&#xE1;c b&#x1B0;&#x1EDB;c, v&#xE0; d&#x1EEB;ng l&#x1EA1;i ch&#x1EDD; ng&#x1B0;&#x1EDD;i d&#xF9;ng ph&#xEA; duy&#x1EC7;t tr&#x1B0;&#x1EDB;c khi th&#x1EF1;c hi&#x1EC7;n c&#xE1;c h&#xE0;nh &#x111;&#x1ED9;ng c&#xF3; t&#xE1;c d&#x1EE5;ng ph&#x1EE5;.</p><p>C&#xF3; th&#x1EC3; v&#xED; von nh&#x1B0; sau: <strong>Lobster &#x111;&#x1ED1;i v&#x1EDB;i OpenClaw gi&#x1ED1;ng nh&#x1B0; GitHub Actions &#x111;&#x1ED1;i v&#x1EDB;i GitHub</strong> &#x2014; m&#x1ED9;t b&#x1EA3;n khai b&#xE1;o quy tr&#xEC;nh ch&#x1EA1;y b&#xEA;n trong n&#x1EC1;n t&#x1EA3;ng.</p><p>&#x110;&#x1EB7;c &#x111;i&#x1EC3;m c&#x1ED1;t l&#xF5;i c&#x1EE7;a Lobster g&#x1ED3;m ba &#x111;i&#x1EC3;m:</p><p><strong>M&#x1ED9;t l&#x1EA7;n g&#x1ECD;i thay v&#xEC; nhi&#x1EC1;u l&#x1EA7;n.</strong> Thay v&#xEC; t&#xE1;c nh&#xE2;n ph&#x1EA3;i l&#x1EA7;n l&#x1B0;&#x1EE3;t g&#x1ECD;i t&#x1EEB;ng c&#xF4;ng c&#x1EE5;, suy ngh&#x129;, r&#x1ED3;i g&#x1ECD;i c&#xF4;ng c&#x1EE5; ti&#x1EBF;p theo &#x2014; Lobster g&#x1ED9;p to&#xE0;n b&#x1ED9; chu&#x1ED7;i &#x111;&#xF3; v&#xE0;o m&#x1ED9;t l&#x1EDD;i g&#x1ECD;i duy nh&#x1EA5;t. T&#xE1;c nh&#xE2;n kh&#x1EDF;i &#x111;&#x1ED9;ng Lobster, Lobster ch&#x1EA1;y chu&#x1ED7;i l&#x1EC7;nh, t&#xE1;c nh&#xE2;n nh&#x1EAD;n k&#x1EBF;t qu&#x1EA3;.</p><p><strong>C&#x1ED5;ng ph&#xEA; duy&#x1EC7;t t&#xED;ch h&#x1EE3;p s&#x1EB5;n.</strong> B&#x1EA5;t k&#x1EF3; b&#x1B0;&#x1EDB;c n&#xE0;o c&#xF3; kh&#x1EA3; n&#x103;ng g&#xE2;y t&#xE1;c d&#x1EE5;ng ph&#x1EE5; (g&#x1EED;i tin nh&#x1EAF;n, thay &#x111;&#x1ED5;i d&#x1EEF; li&#x1EC7;u, g&#x1ECD;i API ngo&#xE0;i) &#x111;&#x1EC1;u c&#xF3; th&#x1EC3; &#x111;&#x1EB7;t sau m&#x1ED9;t c&#x1ED5;ng <code>approval: required</code>. Quy tr&#xEC;nh t&#x1EF1; &#x111;&#x1ED9;ng d&#x1EEB;ng l&#x1EA1;i, tr&#x1EA3; v&#x1EC1; <code>resumeToken</code>, v&#xE0; ch&#x1EDD; ng&#x1B0;&#x1EDD;i d&#xF9;ng quy&#x1EBF;t &#x111;&#x1ECB;nh.</p><p><strong>C&#xF3; th&#x1EC3; ti&#x1EBF;p t&#x1EE5;c sau khi b&#x1ECB; gi&#xE1;n &#x111;o&#x1EA1;n.</strong> Quy tr&#xEC;nh &#x111;ang ch&#x1EDD; ph&#xEA; duy&#x1EC7;t kh&#xF4;ng m&#x1EA5;t tr&#x1EA1;ng th&#xE1;i. Khi ng&#x1B0;&#x1EDD;i d&#xF9;ng ph&#xEA; duy&#x1EC7;t, l&#x1EC7;nh ti&#x1EBF;p t&#x1EE5;c k&#xE8;m token s&#x1EBD; ch&#x1EA1;y ch&#xED;nh x&#xE1;c t&#x1EEB; b&#x1B0;&#x1EDB;c &#x111;&#xF3; &#x2014; kh&#xF4;ng ch&#x1EA1;y l&#x1EA1;i ph&#x1EA7;n &#x111;&#xE3; ho&#xE0;n th&#xE0;nh.</p><h3 id="22-t%E1%BA%A1i-sao-c%E1%BA%A7n-m%E1%BB%99t-ng%C3%B4n-ng%E1%BB%AF-%C4%91%E1%BA%B7c-th%C3%B9-ri%C3%AAng">2.2 T&#x1EA1;i sao c&#x1EA7;n m&#x1ED9;t ng&#xF4;n ng&#x1EEF; &#x111;&#x1EB7;c th&#xF9; ri&#xEA;ng?</h3><p>C&#xE2;u h&#x1ECF;i h&#x1EE3;p l&#xFD;: t&#x1EA1;i sao kh&#xF4;ng vi&#x1EBF;t script Python hay Bash th&#xF4;ng th&#x1B0;&#x1EDD;ng?</p><p>C&#xE2;u tr&#x1EA3; l&#x1EDD;i n&#x1EB1;m &#x1EDF; hai kh&#xED;a c&#x1EA1;nh: <strong>kh&#x1EA3; n&#x103;ng ki&#x1EC3;m tra</strong> v&#xE0; <strong>s&#x1EF1; an to&#xE0;n &#x111;&#x1B0;&#x1EE3;c thi&#x1EBF;t k&#x1EBF; s&#x1EB5;n</strong>.</p><p>Trong Lobster, chu&#x1ED7;i l&#x1EC7;nh l&#xE0; <em>d&#x1EEF; li&#x1EC7;u</em>, kh&#xF4;ng ph&#x1EA3;i m&#xE3; l&#x1EC7;nh. M&#x1ED7;i b&#x1B0;&#x1EDB;c l&#xE0; m&#x1ED9;t &#x111;&#x1ED1;i t&#x1B0;&#x1EE3;ng YAML c&#xF3; th&#x1EC3; ghi l&#x1EA1;i, so s&#xE1;nh s&#x1EF1; kh&#xE1;c bi&#x1EC7;t, v&#xE0; ch&#x1EA1;y l&#x1EA1;i. Kh&#xF4;ng c&#xF3; tr&#x1EA1;ng th&#xE1;i &#x1EA9;n, kh&#xF4;ng c&#xF3; t&#xE1;c d&#x1EE5;ng ph&#x1EE5; che gi&#x1EA5;u. Khi m&#x1ED9;t b&#x1B0;&#x1EDB;c th&#x1EA5;t b&#x1EA1;i, b&#x1EA1;n bi&#x1EBF;t ch&#xED;nh x&#xE1;c b&#x1B0;&#x1EDB;c n&#xE0;o, v&#xEC; sao, v&#xE0; &#x111;&#x1EA7;u ra c&#x1EE7;a c&#xE1;c b&#x1B0;&#x1EDB;c tr&#x1B0;&#x1EDB;c l&#xE0; g&#xEC;.</p><p>H&#x1A1;n n&#x1EEF;a, b&#x1EC1; m&#x1EB7;t th&#x1EF1;c thi c&#x1EE7;a Lobster b&#x1ECB; gi&#x1EDB;i h&#x1EA1;n c&#xF3; ch&#x1EE7; &#xFD;: gi&#x1EDB;i h&#x1EA1;n th&#x1EDD;i gian, gi&#x1EDB;i h&#x1EA1;n k&#xED;ch th&#x1B0;&#x1EDB;c &#x111;&#x1EA7;u ra (<code>maxStdoutBytes</code>), nh&#x1EAD;n bi&#x1EBF;t m&#xF4;i tr&#x1B0;&#x1EDD;ng c&#xF4; l&#x1EAD;p (sandbox). &#x110;&#xE2;y l&#xE0; &quot;b&#x1EC1; m&#x1EB7;t thu h&#x1EB9;p&quot; gi&#xFA;p h&#xE0;nh vi c&#x1EE7;a t&#xE1;c nh&#xE2;n c&#xF3; th&#x1EC3; d&#x1EF1; &#x111;o&#xE1;n &#x111;&#x1B0;&#x1EE3;c &#x2014; AI kh&#xF4;ng th&#x1EC3; &quot;s&#xE1;ng t&#x1EA1;o&quot; sai &#x1EDF; t&#x1EA7;ng &#x111;i&#x1EC1;u ph&#x1ED1;i th&#x1EF1;c thi.</p><h3 id="23-c%C3%BA-ph%C3%A1p-v%C3%A0-c%C3%A1ch-ho%E1%BA%A1t-%C4%91%E1%BB%99ng">2.3 C&#xFA; ph&#xE1;p v&#xE0; c&#xE1;ch ho&#x1EA1;t &#x111;&#x1ED9;ng</h3><p>Lobster ch&#x1EA1;y c&#xE1;c t&#x1EC7;p <code>.lobster</code> &#x2014; YAML/JSON v&#x1EDB;i c&#x1EA5;u tr&#xFA;c <code>name</code>, <code>args</code>, <code>steps</code>, <code>env</code>, <code>condition</code>, v&#xE0; <code>approval</code>.</p><p><strong>T&#x1EC7;p quy tr&#xEC;nh m&#x1EAB;u &#x2014; ph&#xE2;n lo&#x1EA1;i h&#x1ED9;p th&#x1B0;:</strong></p><pre><code class="language-yaml">name: inbox-triage
args:
  tag:
    default: &quot;family&quot;

steps:
  - id: collect
    command: inbox list --json

  - id: categorize
    command: inbox categorize --json
    stdin: $collect.stdout

  - id: approve
    command: inbox apply --approve
    stdin: $categorize.stdout
    approval: required

  - id: execute
    command: inbox apply --execute
    stdin: $categorize.stdout
    condition: $approve.approved
</code></pre><p>Nh&#xEC;n v&#xE0;o c&#x1EA5;u tr&#xFA;c n&#xE0;y, b&#x1EA1;n th&#x1EA5;y ngay tri&#x1EBF;t l&#xFD; thi&#x1EBF;t k&#x1EBF;: <strong>b&#x1B0;&#x1EDB;c <code>approve</code> n&#x1EB1;m tr&#x1B0;&#x1EDB;c <code>execute</code></strong>. Kh&#xF4;ng c&#xF3; c&#xE1;ch n&#xE0;o &#x111;&#x1EC3; <code>execute</code> ch&#x1EA1;y m&#xE0; kh&#xF4;ng qua c&#x1ED5;ng ph&#xEA; duy&#x1EC7;t. &#x110;&#xE2;y l&#xE0; s&#x1EF1; an to&#xE0;n &#x111;&#x1B0;&#x1EE3;c &#x111;&#x1B0;a v&#xE0;o c&#x1EA5;u tr&#xFA;c, kh&#xF4;ng ph&#x1EA3;i v&#xE0;o l&#x1EDD;i nh&#x1EAF;c (prompt).</p><p><strong>C&#xE1;ch OpenClaw g&#x1ECD;i Lobster:</strong></p><pre><code class="language-json">{
  &quot;action&quot;: &quot;run&quot;,
  &quot;pipeline&quot;: &quot;/path/to/inbox-triage.lobster&quot;,
  &quot;argsJson&quot;: &quot;{\&quot;tag\&quot;:\&quot;family\&quot;}&quot;,
  &quot;cwd&quot;: &quot;workspace&quot;,
  &quot;timeoutMs&quot;: 30000,
  &quot;maxStdoutBytes&quot;: 512000
}
</code></pre><p>OpenClaw kh&#x1EDF;i &#x111;&#x1ED9;ng Lobster CLI &#x1EDF; ch&#x1EBF; &#x111;&#x1ED9; c&#xF4;ng c&#x1EE5; v&#xE0; ph&#xE2;n t&#xED;ch phong b&#xEC; JSON t&#x1EEB; &#x111;&#x1EA7;u ra. N&#x1EBF;u quy tr&#xEC;nh d&#x1EEB;ng t&#x1EA1;i c&#x1ED5;ng ph&#xEA; duy&#x1EC7;t:</p><pre><code class="language-json">{
  &quot;ok&quot;: true,
  &quot;status&quot;: &quot;needs_approval&quot;,
  &quot;output&quot;: [{ &quot;summary&quot;: &quot;5 need replies, 2 need action&quot; }],
  &quot;requiresApproval&quot;: {
    &quot;type&quot;: &quot;approval_request&quot;,
    &quot;prompt&quot;: &quot;Send 2 draft replies?&quot;,
    &quot;items&quot;: [],
    &quot;resumeToken&quot;: &quot;eyJ...&quot;
  }
}
</code></pre><p>T&#xE1;c nh&#xE2;n nh&#x1EAD;n phong b&#xEC; n&#xE0;y, tr&#xEC;nh b&#xE0;y cho ng&#x1B0;&#x1EDD;i d&#xF9;ng, v&#xE0; ch&#x1EDD; quy&#x1EBF;t &#x111;&#x1ECB;nh. Khi ng&#x1B0;&#x1EDD;i d&#xF9;ng ph&#xEA; duy&#x1EC7;t:</p><pre><code class="language-json">{
  &quot;action&quot;: &quot;resume&quot;,
  &quot;token&quot;: &quot;eyJ...&quot;,
  &quot;approve&quot;: true
}
</code></pre><p>Quy tr&#xEC;nh ti&#x1EBF;p t&#x1EE5;c t&#x1EEB; &#x111;&#xFA;ng &#x111;i&#x1EC3;m &#x111;&#xF3;.</p><h3 id="24-nh%C3%BAng-b%C6%B0%E1%BB%9Bc-ai-v%C3%A0o-lobster-plugin-llm-task">2.4 Nh&#xFA;ng b&#x1B0;&#x1EDB;c AI v&#xE0;o Lobster: plugin <code>llm-task</code></h3><p>Lobster l&#xE0; v&#x1ECF; th&#x1EF1;c thi &#x2014; n&#xF3; kh&#xF4;ng t&#x1EF1; g&#x1ECD;i m&#xF4; h&#xEC;nh ng&#xF4;n ng&#x1EEF;. Nh&#x1B0;ng v&#x1EDB;i plugin <code>llm-task</code> &#x111;&#x1B0;&#x1EE3;c b&#x1EAD;t, b&#x1EA1;n c&#xF3; th&#x1EC3; nh&#xFA;ng m&#x1ED9;t b&#x1B0;&#x1EDB;c AI c&#xF3; c&#x1EA5;u tr&#xFA;c v&#xE0;o trong chu&#x1ED7;i l&#x1EC7;nh m&#xE0; kh&#xF4;ng ph&#xE1; v&#x1EE1; t&#xED;nh t&#x1EA5;t &#x111;&#x1ECB;nh c&#x1EE7;a ph&#x1EA7;n c&#xF2;n l&#x1EA1;i.</p><p><strong>B&#x1EAD;t llm-task:</strong></p><pre><code class="language-json">{
  &quot;plugins&quot;: {
    &quot;entries&quot;: {
      &quot;llm-task&quot;: { &quot;enabled&quot;: true }
    }
  },
  &quot;agents&quot;: {
    &quot;list&quot;: [
      {
        &quot;id&quot;: &quot;main&quot;,
        &quot;tools&quot;: { &quot;allow&quot;: [&quot;llm-task&quot;] }
      }
    ]
  }
}
</code></pre><p><strong>G&#x1ECD;i m&#xF4; h&#xEC;nh t&#x1EEB; trong b&#x1B0;&#x1EDB;c Lobster:</strong></p><pre><code class="language-yaml">- id: classify
  command: &gt;
    openclaw.invoke --tool llm-task --action json --args-json &apos;{
      &quot;prompt&quot;: &quot;Given the input email, return intent and draft reply as JSON.&quot;,
      &quot;input&quot;: { &quot;subject&quot;: &quot;Hello&quot;, &quot;body&quot;: &quot;Can you help?&quot; },
      &quot;schema&quot;: {},
      &quot;model&quot;: &quot;ollama/qwen3.5:14b&quot;,
      &quot;temperature&quot;: 0.4,
      &quot;maxTokens&quot;: 2000
    }&apos;
  stdin: $collect.stdout
</code></pre><p><code>llm-task</code> y&#xEA;u c&#x1EA7;u m&#xF4; h&#xEC;nh ch&#x1EC9; xu&#x1EA5;t JSON (kh&#xF4;ng c&#xF3; th&#xEA;m gi&#x1EA3;i th&#xED;ch hay &#x111;&#x1ECB;nh d&#x1EA1;ng markdown), ki&#x1EC3;m tra schema tr&#x1B0;&#x1EDB;c khi tr&#x1EA3; v&#x1EC1;. B&#x1B0;&#x1EDB;c AI n&#xE0;y l&#xE0; m&#x1ED9;t h&#x1ED9;p &#x111;en t&#x1EEB; g&#xF3;c nh&#xEC;n c&#x1EE7;a Lobster &#x2014; n&#xF3; ch&#x1EC9; nh&#x1EAD;n &#x111;&#x1EA7;u v&#xE0;o JSON v&#xE0; xu&#x1EA5;t &#x111;&#x1EA7;u ra JSON nh&#x1B0; m&#x1ECD;i b&#x1B0;&#x1EDB;c kh&#xE1;c.</p><h3 id="25-c%C3%A0i-%C4%91%E1%BA%B7t-v%C3%A0-c%E1%BA%A5u-h%C3%ACnh">2.5 C&#xE0;i &#x111;&#x1EB7;t v&#xE0; c&#x1EA5;u h&#xEC;nh</h3><p><strong>C&#xE0;i Lobster CLI:</strong></p><pre><code class="language-bash"># C&#xE0;i to&#xE0;n c&#x1EE5;c qua npm
npm install -g @clawdbot/lobster

# Ho&#x1EB7;c d&#xF9;ng node tr&#x1EF1;c ti&#x1EBF;p (&#x111;i&#x1EC1;u ch&#x1EC9;nh &#x111;&#x1B0;&#x1EDD;ng d&#x1EAB;n)
alias lobster=&quot;node /path/to/lobster/bin/lobster.js&quot;

# Ki&#x1EC3;m tra
lobster --version
</code></pre><p>Lobster ph&#x1EA3;i n&#x1EB1;m tr&#xEA;n <code>PATH</code> tr&#xEA;n c&#xF9;ng m&#xE1;y ch&#x1EE7; ch&#x1EA1;y OpenClaw Gateway.</p><p><strong>B&#x1EAD;t plugin trong <code>openclaw.json</code>:</strong></p><pre><code class="language-json5">{
  &quot;tools&quot;: {
    &quot;alsoAllow&quot;: [&quot;lobster&quot;]
    // D&#xF9;ng alsoAllow thay v&#xEC; allow &#x111;&#x1EC3; kh&#xF4;ng v&#xF4; t&#xEC;nh gi&#x1EDB;i h&#x1EA1;n c&#xE1;c c&#xF4;ng c&#x1EE5; c&#x1ED1;t l&#xF5;i
  }
}
</code></pre><blockquote><strong>L&#x1B0;u &#xFD; quan tr&#x1ECD;ng:</strong> Tr&#xE1;nh d&#xF9;ng <code>tools.allow: [&quot;lobster&quot;]</code> (danh s&#xE1;ch cho ph&#xE9;p thu&#x1EA7;n t&#xFA;y) tr&#x1EEB; khi b&#x1EA1;n ch&#x1EE7; &#xFD; ch&#x1EA1;y &#x1EDF; ch&#x1EBF; &#x111;&#x1ED9; h&#x1EA1;n ch&#x1EBF;. <code>alsoAllow</code> l&#xE0; b&#x1ED5; sung &#x2014; an to&#xE0;n h&#x1A1;n.</blockquote><p><strong>C&#xE1;c tham s&#x1ED1; khi ch&#x1EA1;y:</strong></p><!--kg-card-begin: html--><table>
<thead>
<tr>
<th>Tham s&#x1ED1;</th>
<th>M&#x1EB7;c &#x111;&#x1ECB;nh</th>
<th>&#xDD; ngh&#x129;a</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>cwd</code></td>
<td>workspace</td>
<td>Th&#x1B0; m&#x1EE5;c l&#xE0;m vi&#x1EC7;c (ph&#x1EA3;i n&#x1EB1;m trong th&#x1B0; m&#x1EE5;c l&#xE0;m vi&#x1EC7;c c&#x1EE7;a ti&#x1EBF;n tr&#xEC;nh)</td>
</tr>
<tr>
<td><code>timeoutMs</code></td>
<td>20000</td>
<td>K&#x1EBF;t th&#xFA;c ti&#x1EBF;n tr&#xEC;nh con n&#x1EBF;u v&#x1B0;&#x1EE3;t th&#x1EDD;i gian</td>
</tr>
<tr>
<td><code>maxStdoutBytes</code></td>
<td>512000</td>
<td>K&#x1EBF;t th&#xFA;c n&#x1EBF;u &#x111;&#x1EA7;u ra v&#x1B0;&#x1EE3;t k&#xED;ch th&#x1B0;&#x1EDB;c</td>
</tr>
<tr>
<td><code>argsJson</code></td>
<td>&#x2014;</td>
<td>Chu&#x1ED7;i JSON truy&#x1EC1;n v&#xE0;o <code>lobster run --args-json</code></td>
</tr>
<tr>
<td><code>lobsterPath</code></td>
<td><code>lobster</code> tr&#xEA;n PATH</td>
<td>&#x110;&#x1B0;&#x1EDD;ng d&#x1EAB;n tuy&#x1EC7;t &#x111;&#x1ED1;i n&#x1EBF;u c&#x1EA7;n ch&#x1EC9; &#x111;&#x1ECB;nh r&#xF5;</td>
</tr>
</tbody>
</table><!--kg-card-end: html--><p><strong>X&#x1EED; l&#xFD; l&#x1ED7;i th&#x1B0;&#x1EDD;ng g&#x1EB7;p:</strong></p><pre><code>lobster subprocess timed out
&#x2192; T&#x103;ng timeoutMs ho&#x1EB7;c chia chu&#x1ED7;i l&#x1EC7;nh th&#xE0;nh nhi&#x1EC1;u b&#x1B0;&#x1EDB;c nh&#x1ECF; h&#x1A1;n

lobster output exceeded maxStdoutBytes
&#x2192; T&#x103;ng maxStdoutBytes ho&#x1EB7;c gi&#x1EA3;m k&#xED;ch th&#x1B0;&#x1EDB;c &#x111;&#x1EA7;u ra c&#x1EE7;a t&#x1EEB;ng b&#x1B0;&#x1EDB;c

lobster returned invalid JSON
&#x2192; &#x110;&#x1EA3;m b&#x1EA3;o chu&#x1ED7;i l&#x1EC7;nh ch&#x1EA1;y &#x1EDF; ch&#x1EBF; &#x111;&#x1ED9; c&#xF4;ng c&#x1EE5; v&#xE0; ch&#x1EC9; in JSON ra &#x111;&#x1EA7;u ra

lobster failed (code N)
&#x2192; Ch&#x1EA1;y c&#xF9;ng chu&#x1ED7;i l&#x1EC7;nh trong terminal &#x111;&#x1EC3; xem chi ti&#x1EBF;t l&#x1ED7;i
</code></pre><h3 id="26-v%C3%AD-d%E1%BB%A5-th%E1%BB%B1c-t%E1%BA%BF-b%E1%BB%99-n%C3%A3o-th%E1%BB%A9-hai-v%E1%BB%9Bi-kho-l%C6%B0u-tr%E1%BB%AF-markdown">2.6 V&#xED; d&#x1EE5; th&#x1EF1;c t&#x1EBF;: &quot;B&#x1ED9; N&#xE3;o Th&#x1EE9; Hai&quot; v&#x1EDB;i kho l&#x1B0;u tr&#x1EEF; Markdown</h3><p>M&#x1ED9;t tr&#x1B0;&#x1EDD;ng h&#x1EE3;p s&#x1EED; d&#x1EE5;ng t&#x1EEB; c&#x1ED9;ng &#x111;&#x1ED3;ng OpenClaw: qu&#x1EA3;n l&#xFD; ba kho l&#x1B0;u tr&#x1EEF; Markdown (c&#xE1; nh&#xE2;n, &#x111;&#x1ED1;i t&#xE1;c, chia s&#x1EBB;) b&#x1EB1;ng m&#x1ED9;t c&#xF4;ng c&#x1EE5; d&#xF2;ng l&#x1EC7;nh t&#x1EF1; vi&#x1EBF;t k&#x1EBF;t h&#x1EE3;p v&#x1EDB;i Lobster.</p><p>C&#xF4;ng c&#x1EE5; n&#xE0;y xu&#x1EA5;t JSON cho th&#x1ED1;ng k&#xEA;, danh s&#xE1;ch h&#x1ED9;p th&#x1B0; &#x111;&#x1EBF;n, v&#xE0; qu&#xE9;t t&#x1EC7;p l&#x1ED7;i th&#x1EDD;i. Lobster n&#x1ED1;i c&#xE1;c l&#x1EC7;nh &#x111;&#xF3; th&#xE0;nh c&#xE1;c quy tr&#xEC;nh:</p><pre><code class="language-yaml">name: weekly-review
steps:
  - id: stats
    command: brain stats --json --vault personal

  - id: inbox
    command: brain inbox list --json --vault personal
    stdin: $stats.stdout

  - id: stale
    command: brain stale --json --days 14

  - id: review_gate
    command: brain inbox preview --json
    stdin: $inbox.stdout
    approval: required

  - id: consolidate
    command: brain memory consolidate --json
    stdin: $inbox.stdout
    condition: $review_gate.approved

  - id: sync_shared
    command: brain task sync --vault shared
    condition: $review_gate.approved
</code></pre><p>M&#x1ED7;i tu&#x1EA7;n, t&#xE1;c nh&#xE2;n kh&#x1EDF;i &#x111;&#x1ED9;ng <code>weekly-review</code>, ng&#x1B0;&#x1EDD;i d&#xF9;ng xem l&#x1EA1;i t&#xF3;m t&#x1EAF;t h&#x1ED9;p th&#x1B0; &#x111;&#x1EBF;n t&#x1EA1;i c&#x1ED5;ng ph&#xEA; duy&#x1EC7;t, ph&#xEA; duy&#x1EC7;t m&#x1ED9;t l&#x1EA7;n &#x2014; v&#xE0; to&#xE0;n b&#x1ED9; qu&#xE1; tr&#xEC;nh h&#x1EE3;p nh&#x1EA5;t + &#x111;&#x1ED3;ng b&#x1ED9; &#x111;&#x1B0;&#x1EE3;c th&#x1EF1;c thi theo th&#x1EE9; t&#x1EF1; x&#xE1;c &#x111;&#x1ECB;nh.</p><hr><h2 id="3-openprose-%E2%80%94-ng%C3%B4n-ng%E1%BB%AF-%C4%91i%E1%BB%81u-ph%E1%BB%91i-phi%C3%AAn-ai">3. OpenProse &#x2014; Ng&#xF4;n Ng&#x1EEF; &#x110;i&#x1EC1;u Ph&#x1ED1;i Phi&#xEA;n AI</h2><h3 id="31-openprose-l%C3%A0-g%C3%AC">3.1 OpenProse l&#xE0; g&#xEC;?</h3><p>OpenProse l&#xE0; m&#x1ED9;t <strong>ng&#xF4;n ng&#x1EEF; l&#x1EAD;p tr&#xEC;nh cho c&#xE1;c phi&#xEA;n AI</strong> &#x2014; m&#x1ED9;t &#x111;&#x1ECB;nh d&#x1EA1;ng quy tr&#xEC;nh &#x111;a n&#x1EC1;n t&#x1EA3;ng, &#x1B0;u ti&#xEA;n markdown, d&#xF9;ng &#x111;&#x1EC3; &#x111;i&#x1EC1;u ph&#x1ED1;i c&#xE1;c phi&#xEA;n AI c&#xF3; c&#x1EA5;u tr&#xFA;c, nhi&#x1EC1;u t&#xE1;c nh&#xE2;n, v&#x1EDB;i lu&#x1ED3;ng ki&#x1EC3;m so&#xE1;t t&#x1B0;&#x1EDD;ng minh.</p><p>Trong OpenClaw, n&#xF3; &#x111;&#x1B0;&#x1EE3;c t&#xED;ch h&#x1EE3;p d&#x1B0;&#x1EDB;i d&#x1EA1;ng plugin c&#xE0;i &#x111;&#x1EB7;t m&#x1ED9;t <strong>b&#x1ED9; k&#x1EF9; n&#x103;ng OpenProse</strong> v&#xE0; m&#x1ED9;t <strong>l&#x1EC7;nh g&#x1EA1;ch ch&#xE9;o <code>/prose</code></strong>. Trang ch&#xED;nh th&#x1EE9;c: <a href="https://www.prose.md/">prose.md</a>.</p><p>&#x110;&#x1EC3; hi&#x1EC3;u tri&#x1EBF;t l&#xFD; c&#x1EE7;a OpenProse, h&#xE3;y b&#x1EAF;t &#x111;&#x1EA7;u t&#x1EEB; nh&#x1EAD;n &#x111;&#x1ECB;nh n&#x1EC1;n t&#x1EA3;ng c&#x1EE7;a n&#xF3;:</p><blockquote><em>&quot;M&#xF4; h&#xEC;nh ng&#xF4;n ng&#x1EEF; l&#xE0; b&#x1ED9; m&#xF4; ph&#x1ECF;ng. Khi &#x111;&#x1B0;&#x1EE3;c cung c&#x1EA5;p m&#x1ED9;t m&#xF4; t&#x1EA3; h&#x1EC7; th&#x1ED1;ng &#x111;&#x1EE7; chi ti&#x1EBF;t, ch&#xFA;ng kh&#xF4;ng ch&#x1EC9; m&#xF4; t&#x1EA3; n&#xF3; &#x2014; ch&#xFA;ng m&#xF4; ph&#x1ECF;ng n&#xF3;. B&#x1EA3;n &#x111;&#x1EB7;c t&#x1EA3; OpenProse m&#xF4; t&#x1EA3; m&#x1ED9;t m&#xE1;y &#x1EA3;o v&#x1EDB;i &#x111;&#x1EE7; &#x111;&#x1ED9; ch&#xED;nh x&#xE1;c &#x111;&#x1EC3; b&#x1EA5;t k&#x1EF3; h&#x1EC7; th&#x1ED1;ng t&#x1B0;&#x1A1;ng th&#xED;ch Prose n&#xE0;o &#x111;&#x1ECD;c n&#xF3; &#x111;&#x1EC1;u tr&#x1EDF; th&#xE0;nh m&#xE1;y &#x1EA3;o &#x111;&#xF3;.&quot;</em></blockquote><p>N&#xF3;i c&#x1EE5; th&#x1EC3; h&#x1A1;n: OpenProse kh&#xF4;ng c&#x1EA7;n m&#x1ED9;t tr&#xEC;nh th&#xF4;ng d&#x1ECB;ch ri&#xEA;ng. Khi t&#xE1;c nh&#xE2;n &#x111;&#x1ECD;c t&#x1EC7;p &#x111;&#x1EB7;c t&#x1EA3; <code>prose.md</code>, n&#xF3; <em>tr&#x1EDF; th&#xE0;nh</em> m&#xE1;y &#x1EA3;o &#x111;&#xF3;. <strong>M&#xF4; ph&#x1ECF;ng v&#x1EDB;i &#x111;&#x1EE7; &#x111;&#x1ED9; ch&#xED;nh x&#xE1;c ch&#xED;nh l&#xE0; s&#x1EF1; hi&#x1EC7;n th&#x1EF1;c h&#xF3;a.</strong></p><p>&#x110;&#xE2;y l&#xE0; &#x111;i&#x1EC3;m kh&#xE1;c bi&#x1EC7;t c&#x1ED1;t l&#xF5;i so v&#x1EDB;i c&#xE1;c khung nh&#x1B0; LangChain, CrewAI hay AutoGen &#x2014; nh&#x1EEF;ng c&#xF4;ng c&#x1EE5; &#x111;&#xF3; <strong>&#x111;i&#x1EC1;u ph&#x1ED1;i t&#xE1;c nh&#xE2;n t&#x1EEB; b&#xEA;n ngo&#xE0;i</strong> b&#x1EB1;ng m&#xE3; l&#x1EC7;nh. OpenProse <strong>ch&#x1EA1;y b&#xEA;n trong phi&#xEA;n t&#xE1;c nh&#xE2;n</strong>. Kh&#xF4;ng c&#x1EA7;n ph&#x1EE5; thu&#x1ED9;c b&#xEA;n ngo&#xE0;i, c&#xF3; th&#x1EC3; s&#x1EED; d&#x1EE5;ng tr&#xEA;n m&#x1ECD;i h&#x1EC7; th&#x1ED1;ng t&#x1B0;&#x1A1;ng th&#xED;ch Prose.</p><h3 id="32-tri%E1%BA%BFt-l%C3%BD-t%E1%BA%A1i-sao-kh%C3%B4ng-ch%E1%BB%89-d%C3%B9ng-ti%E1%BA%BFng-t%E1%BB%B1-nhi%C3%AAn">3.2 Tri&#x1EBF;t l&#xFD;: T&#x1EA1;i sao kh&#xF4;ng ch&#x1EC9; d&#xF9;ng ti&#x1EBF;ng t&#x1EF1; nhi&#xEA;n?</h3><p>M&#x1ED9;t quy tr&#xEC;nh ph&#x1EE9;c t&#x1EA1;p c&#x1EA7;n <strong>c&#x1EA5;u tr&#xFA;c r&#xF5; r&#xE0;ng, kh&#xF4;ng m&#x1A1; h&#x1ED3;</strong> cho lu&#x1ED3;ng ki&#x1EC3;m so&#xE1;t. N&#x1EBF;u b&#x1EA1;n m&#xF4; t&#x1EA3; b&#x1EB1;ng ti&#x1EBF;ng Vi&#x1EC7;t hay ti&#x1EBF;ng Anh th&#xF4;ng th&#x1B0;&#x1EDD;ng: &quot;Nghi&#xEA;n c&#x1EE9;u song song, r&#x1ED3;i t&#x1ED5;ng h&#x1EE3;p&quot; &#x2014; t&#xE1;c nh&#xE2;n ph&#x1EA3;i <em>&#x111;o&#xE1;n</em> b&#x1EA1;n mu&#x1ED1;n tu&#x1EA7;n t&#x1EF1; hay song song, bao nhi&#xEA;u t&#xE1;c nh&#xE2;n, khi n&#xE0;o g&#x1ED9;p k&#x1EBF;t qu&#x1EA3;.</p><p>OpenProse gi&#x1EA3;i quy&#x1EBF;t &#x111;i&#x1EC1;u n&#xE0;y b&#x1EB1;ng <strong>ng&#x1EEF; ngh&#x129;a d&#x1EF1;a tr&#xEA;n h&#x1EE3;p &#x111;&#x1ED3;ng</strong>:</p><pre><code class="language-yaml">---
name: research-with-agents
kind: program
services: [researcher, writer]
---

requires:
  - topic: a research question to investigate

ensures:
  - report: an executive-ready summary of research findings

strategies:
  - when initial research is shallow: deepen with more targeted queries
  - when findings are too technical for executives: simplify language while preserving accuracy
</code></pre><p><code>requires:</code> v&#xE0; <code>ensures:</code> l&#xE0; c&#xE1;c h&#x1EE3;p &#x111;&#x1ED3;ng &#x2014; kh&#xF4;ng ph&#x1EA3;i m&#xF4; t&#x1EA3;, m&#xE0; l&#xE0; cam k&#x1EBF;t. M&#xF4;i tr&#x1B0;&#x1EDD;ng th&#x1EF1;c thi bi&#x1EBF;t ch&#xED;nh x&#xE1;c &#x111;&#x1EA7;u v&#xE0;o c&#x1EA7;n c&#xF3; v&#xE0; &#x111;&#x1EA7;u ra c&#x1EA7;n &#x111;&#x1EA3;m b&#x1EA3;o tr&#x1B0;&#x1EDB;c khi ch&#x1EA1;y.</p><h3 id="33-c%C3%A1ch-openprose-ho%E1%BA%A1t-%C4%91%E1%BB%99ng">3.3 C&#xE1;ch OpenProse ho&#x1EA1;t &#x111;&#x1ED9;ng</h3><p><strong>T&#x1EC7;p <code>.prose</code> &#x2014; v&#xED; d&#x1EE5; nghi&#xEA;n c&#x1EE9;u + t&#x1ED5;ng h&#x1EE3;p:</strong></p><pre><code class="language-yaml"># research-synthesis.prose
# Nghi&#xEA;n c&#x1EE9;u + t&#x1ED5;ng h&#x1EE3;p v&#x1EDB;i hai t&#xE1;c nh&#xE2;n ch&#x1EA1;y song song

input topic: &quot;What should we research?&quot;

agent researcher:
  model: sonnet
  prompt: &quot;You research thoroughly and cite sources.&quot;

agent writer:
  model: opus
  prompt: &quot;You write a concise summary.&quot;

parallel:
  findings = session: researcher
    prompt: &quot;Research {topic}.&quot;
  draft = session: writer
    prompt: &quot;Summarize {topic}.&quot;

session &quot;Merge the findings + draft into a final answer.&quot;
  context: { findings, draft }
</code></pre><p>Nh&#xEC;n v&#xE0;o kh&#x1ED1;i <code>parallel:</code> &#x2014; &#x111;&#xE2;y l&#xE0; &#x111;i&#x1EC1;u Lobster kh&#xF4;ng th&#x1EC3; l&#xE0;m. OpenProse h&#x1ED7; tr&#x1EE3; s&#x1EB5;n vi&#x1EC7;c ch&#x1EA1;y song song, truy&#x1EC1;n ng&#x1EEF; c&#x1EA3;nh t&#x1B0;&#x1EDD;ng minh gi&#x1EEF;a c&#xE1;c t&#xE1;c nh&#xE2;n, v&#xE0; g&#x1ED9;p k&#x1EBF;t qu&#x1EA3; v&#x1EC1; phi&#xEA;n ch&#xED;nh.</p><p><strong>Qu&#x1EA3;n l&#xFD; tr&#x1EA1;ng th&#xE1;i:</strong></p><p>OpenProse l&#x1B0;u tr&#x1EA1;ng th&#xE1;i trong th&#x1B0; m&#x1EE5;c <code>.prose/</code> trong kh&#xF4;ng gian l&#xE0;m vi&#x1EC7;c:</p><pre><code>.prose/
&#x251C;&#x2500;&#x2500; .env
&#x251C;&#x2500;&#x2500; runs/
&#x2502;   &#x2514;&#x2500;&#x2500; {YYYYMMDD}-{HHMMSS}-{random}/
&#x2502;       &#x251C;&#x2500;&#x2500; program.prose
&#x2502;       &#x251C;&#x2500;&#x2500; state.md
&#x2502;       &#x251C;&#x2500;&#x2500; bindings/
&#x2502;       &#x2514;&#x2500;&#x2500; agents/
&#x2514;&#x2500;&#x2500; agents/
</code></pre><p>Ba ch&#x1EBF; &#x111;&#x1ED9; l&#x1B0;u tr&#x1EA1;ng th&#xE1;i:</p><!--kg-card-begin: html--><table>
<thead>
<tr>
<th>Ch&#x1EBF; &#x111;&#x1ED9;</th>
<th>Khi n&#xE0;o d&#xF9;ng</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>filesystem</strong> (m&#x1EB7;c &#x111;&#x1ECB;nh)</td>
<td>H&#x1EA7;u h&#x1EBF;t c&#xE1;c tr&#x1B0;&#x1EDD;ng h&#x1EE3;p, c&#x1EA7;n ti&#x1EBF;p t&#x1EE5;c v&#xE0; l&#x1B0;u tr&#x1EEF; l&#xE2;u d&#xE0;i</td>
</tr>
<tr>
<td><strong>in-context</strong></td>
<td>C&#xE1;c ch&#x1B0;&#x1A1;ng tr&#xEC;nh nh&#x1ECF;, t&#x1EA1;m th&#x1EDD;i, kh&#xF4;ng c&#x1EA7;n l&#x1B0;u tr&#x1EEF;</td>
</tr>
<tr>
<td><strong>sqlite / postgres</strong></td>
<td>Quy tr&#xEC;nh s&#x1EA3;n xu&#x1EA5;t v&#x1EDB;i tr&#x1EA1;ng th&#xE1;i ph&#x1EE9;c t&#x1EA1;p</td>
</tr>
</tbody>
</table><!--kg-card-end: html--><h3 id="34-l%E1%BB%87nh-g%E1%BA%A1ch-ch%C3%A9o-prose-v%C3%A0-c%C3%A1c-l%E1%BB%87nh-con">3.4 L&#x1EC7;nh g&#x1EA1;ch ch&#xE9;o <code>/prose</code> v&#xE0; c&#xE1;c l&#x1EC7;nh con</h3><p>Khi plugin OpenProse &#x111;&#x1B0;&#x1EE3;c b&#x1EAD;t, OpenClaw &#x111;&#x103;ng k&#xFD; <code>/prose</code> l&#xE0; l&#x1EC7;nh g&#x1EA1;ch ch&#xE9;o c&#xF3; th&#x1EC3; g&#x1ECD;i tr&#x1EF1;c ti&#x1EBF;p t&#x1EEB; b&#x1EA5;t k&#x1EF3; k&#xEA;nh n&#xE0;o:</p><!--kg-card-begin: html--><table>
<thead>
<tr>
<th>L&#x1EC7;nh</th>
<th>T&#xE1;c d&#x1EE5;ng</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>/prose help</code></td>
<td>T&#x1EA3;i <code>help.md</code>, h&#x1B0;&#x1EDB;ng d&#x1EAB;n ng&#x1B0;&#x1EDD;i d&#xF9;ng</td>
</tr>
<tr>
<td><code>/prose run &lt;file.prose&gt;</code></td>
<td>T&#x1EA3;i m&#xE1;y &#x1EA3;o, th&#x1EF1;c thi ch&#x1B0;&#x1A1;ng tr&#xEC;nh c&#x1EE5;c b&#x1ED9;</td>
</tr>
<tr>
<td><code>/prose run handle/slug</code></td>
<td>T&#x1EA3;i t&#x1EEB; kho l&#x1B0;u tr&#x1EEF; tr&#x1EF1;c tuy&#x1EBF;n, r&#x1ED3;i th&#x1EF1;c thi</td>
</tr>
<tr>
<td><code>/prose run https://...</code></td>
<td>T&#x1EA3;i t&#x1EEB; URL tr&#x1EF1;c ti&#x1EBF;p, r&#x1ED3;i th&#x1EF1;c thi</td>
</tr>
<tr>
<td><code>/prose compile &lt;file.prose&gt;</code></td>
<td>Ki&#x1EC3;m tra ch&#x1B0;&#x1A1;ng tr&#xEC;nh (kh&#xF4;ng th&#x1EF1;c thi)</td>
</tr>
<tr>
<td><code>/prose examples</code></td>
<td>Hi&#x1EC3;n th&#x1ECB; ho&#x1EB7;c ch&#x1EA1;y c&#xE1;c v&#xED; d&#x1EE5; c&#xF3; s&#x1EB5;n</td>
</tr>
<tr>
<td><code>/prose update</code></td>
<td>Chuy&#x1EC3;n &#x111;&#x1ED5;i t&#x1EC7;p kh&#xF4;ng gian l&#xE0;m vi&#x1EC7;c c&#x169; sang &#x111;&#x1ECB;nh d&#x1EA1;ng hi&#x1EC7;n t&#x1EA1;i</td>
</tr>
</tbody>
</table><!--kg-card-end: html--><p><strong>Ch&#x1EA1;y t&#x1EEB; kho l&#x1B0;u tr&#x1EEF; tr&#x1EF1;c tuy&#x1EBF;n:</strong></p><pre><code class="language-bash"># T&#xEA;n t&#x1EAF;t t&#x1EEB; kho &#x2014; ph&#xE2;n gi&#x1EA3;i qua p.prose.md
/prose run irl-danb/habit-miner

# URL tr&#x1EF1;c ti&#x1EBF;p
/prose run https://raw.githubusercontent.com/openprose/prose/main/examples/48-habit-miner.prose

# B&#xED; danh trong ch&#x1B0;&#x1A1;ng tr&#xEC;nh
use &quot;alice/research&quot; as research
use &quot;@alice/code-review&quot; as reviewer  # @ &#x111;&#x1B0;&#x1EE3;c lo&#x1EA1;i b&#x1ECF; t&#x1EF1; &#x111;&#x1ED9;ng
</code></pre><h3 id="35-c%C3%A0i-%C4%91%E1%BA%B7t-v%C3%A0-c%E1%BA%A5u-h%C3%ACnh">3.5 C&#xE0;i &#x111;&#x1EB7;t v&#xE0; c&#x1EA5;u h&#xEC;nh</h3><p><strong>B&#x1EAD;t plugin trong <code>openclaw.json</code>:</strong></p><pre><code class="language-json">{
  &quot;plugins&quot;: {
    &quot;entries&quot;: {
      &quot;open-prose&quot;: { &quot;enabled&quot;: true }
    }
  }
}
</code></pre><p>Kh&#x1EDF;i &#x111;&#x1ED9;ng l&#x1EA1;i Gateway sau khi b&#x1EAD;t. V&#x1EDB;i phi&#xEA;n b&#x1EA3;n th&#x1EED; nghi&#x1EC7;m c&#x1EE5;c b&#x1ED9;:</p><pre><code class="language-bash">openclaw plugins install ./extensions/open-prose
</code></pre><p><strong>C&#x1EA5;u h&#xEC;nh ch&#x1EBF; &#x111;&#x1ED9; l&#x1B0;u tr&#x1EA1;ng th&#xE1;i (t&#xF9;y ch&#x1ECD;n):</strong></p><pre><code class="language-bash"># Filesystem (m&#x1EB7;c &#x111;&#x1ECB;nh) &#x2014; kh&#xF4;ng c&#x1EA7;n c&#x1EA5;u h&#xEC;nh th&#xEA;m

# SQLite
OPENPROSE_STATE=sqlite

# PostgreSQL (d&#xF9;ng th&#xF4;ng tin x&#xE1;c th&#x1EF1;c quy&#x1EC1;n h&#x1EA1;n t&#x1ED1;i thi&#x1EC3;u)
OPENPROSE_POSTGRES_URL=postgres://user:pass@host/db
</code></pre><blockquote><strong>L&#x1B0;u &#xFD; b&#x1EA3;o m&#x1EAD;t PostgreSQL:</strong> Th&#xF4;ng tin x&#xE1;c th&#x1EF1;c &#x111;&#x1B0;&#x1EE3;c truy&#x1EC1;n v&#xE0;o c&#xE1;c phi&#xEA;n t&#xE1;c nh&#xE2;n con v&#xE0; s&#x1EBD; hi&#x1EC3;n th&#x1ECB; trong ng&#x1EEF; c&#x1EA3;nh t&#xE1;c nh&#xE2;n v&#xE0; nh&#x1EAD;t k&#xFD;. H&#xE3;y d&#xF9;ng c&#x1A1; s&#x1EDF; d&#x1EEF; li&#x1EC7;u ri&#xEA;ng v&#x1EDB;i quy&#x1EC1;n h&#x1EA1;n t&#x1ED1;i thi&#x1EC3;u.</blockquote><p><strong>M&#x1ED9;t k&#x1EF9; n&#x103;ng duy nh&#x1EA5;t, kh&#xF4;ng ph&#x1EA3;i nhi&#x1EC1;u:</strong></p><p>C&#xF3; m&#x1ED9;t &#x111;i&#x1EC3;m d&#x1EC5; nh&#x1EA7;m: OpenProse ch&#x1EC9; c&#xF3; <strong>m&#x1ED9;t k&#x1EF9; n&#x103;ng duy nh&#x1EA5;t</strong> l&#xE0; <code>open-prose</code>. Kh&#xF4;ng c&#xF3; <code>prose-run</code>, <code>prose-compile</code>, hay <code>prose-boot</code> t&#xE1;ch bi&#x1EC7;t. M&#x1ECD;i l&#x1EC7;nh &#x111;&#x1EC1;u &#x111;i qua k&#x1EF9; n&#x103;ng n&#xE0;y.</p><pre><code>Kh&#xF4;ng &#x111;&#xFA;ng: npx playbooks add skill openclaw/skills --skill prose-run
&#x110;&#xFA;ng:       npx playbooks add skill openclaw/skills --skill prose
</code></pre><p><strong>B&#x1EA3;o m&#x1EAD;t &#x2014; xem x&#xE9;t tr&#x1B0;&#x1EDB;c khi ch&#x1EA1;y:</strong></p><p>OpenProse th&#x1EF1;c thi c&#xE1;c ch&#x1B0;&#x1A1;ng tr&#xEC;nh v&#x1EDB;i quy&#x1EC1;n truy c&#x1EAD;p &#x111;&#x1EA7;y &#x111;&#x1EE7; v&#xE0;o kh&#xF4;ng gian l&#xE0;m vi&#x1EC7;c v&#xE0; c&#xE1;c c&#xF4;ng c&#x1EE5; c&#x1EE7;a t&#xE1;c nh&#xE2;n. Lu&#xF4;n xem x&#xE9;t t&#x1EC7;p <code>.prose</code> tr&#x1B0;&#x1EDB;c khi ch&#x1EA1;y, &#x111;&#x1EB7;c bi&#x1EC7;t v&#x1EDB;i c&#xE1;c ch&#x1B0;&#x1A1;ng tr&#xEC;nh t&#x1EEB; xa t&#x1EEB; kho l&#x1B0;u tr&#x1EEF; ho&#x1EB7;c URL. D&#xF9;ng danh s&#xE1;ch cho ph&#xE9;p c&#xF4;ng c&#x1EE5; trong c&#x1EA5;u h&#xEC;nh &#x111;&#x1EC3; h&#x1EA1;n ch&#x1EBF; nh&#x1EEF;ng g&#xEC; t&#xE1;c nh&#xE2;n con c&#xF3; th&#x1EC3; l&#xE0;m.</p><h3 id="36-y%C3%AAu-c%E1%BA%A7u-h%E1%BB%87-th%E1%BB%91ng-t%C6%B0%C6%A1ng-th%C3%ADch-prose">3.6 Y&#xEA;u c&#x1EA7;u: H&#x1EC7; th&#x1ED1;ng t&#x1B0;&#x1A1;ng th&#xED;ch Prose</h3><p>OpenProse kh&#xF4;ng ch&#x1EA1;y tr&#xEA;n m&#x1ECD;i m&#xF4; h&#xEC;nh. N&#xF3; y&#xEA;u c&#x1EA7;u m&#x1ED9;t <strong>h&#x1EC7; th&#x1ED1;ng t&#x1B0;&#x1A1;ng th&#xED;ch Prose</strong> &#x2014; t&#x1ED5; h&#x1EE3;p m&#xF4; h&#xEC;nh v&#xE0; m&#xF4;i tr&#x1B0;&#x1EDD;ng &#x111;&#x1EE7; m&#x1EA1;nh &#x111;&#x1EC3; m&#xF4; ph&#x1ECF;ng m&#xE1;y &#x1EA3;o khi &#x111;&#x1ECD;c &#x111;&#x1EB7;c t&#x1EA3;. Hi&#x1EC7;n t&#x1EA1;i &#x111;&#x1B0;&#x1EE3;c h&#x1ED7; tr&#x1EE3; ch&#xED;nh th&#x1EE9;c: Claude Code + Opus, OpenCode + Opus, Amp + Opus.</p><p>V&#x1EDB;i OpenClaw k&#x1EBF;t h&#x1EE3;p m&#xF4; h&#xEC;nh c&#x1EE5;c b&#x1ED9; (nh&#x1B0; Qwen3.5), kh&#x1EA3; n&#x103;ng t&#x1B0;&#x1A1;ng th&#xED;ch ph&#x1EE5; thu&#x1ED9;c v&#xE0;o vi&#x1EC7;c m&#xF4; h&#xEC;nh c&#xF3; &#x111;&#x1EE7; n&#x103;ng l&#x1EF1;c m&#xF4; ph&#x1ECF;ng hay kh&#xF4;ng &#x2014; &#x111;&#xE2;y l&#xE0; &#x111;i&#x1EC3;m c&#x1EA7;n ki&#x1EC3;m tra th&#x1EF1;c t&#x1EBF;.</p><hr><h2 id="4-sai-l%E1%BA%A7m-ph%E1%BB%95-bi%E1%BA%BFn-d%C3%B9ng-lobster-m%E1%BB%99t-m%C3%ACnh-cho-t%E1%BA%A5t-c%E1%BA%A3">4. Sai L&#x1EA7;m Ph&#x1ED5; Bi&#x1EBF;n: D&#xF9;ng Lobster M&#x1ED9;t M&#xEC;nh Cho T&#x1EA5;t C&#x1EA3;</h2><p>Hi&#x1EC3;u l&#xFD; thuy&#x1EBF;t l&#xE0; m&#x1ED9;t chuy&#x1EC7;n. Nh&#x1B0;ng c&#xE1;ch hi&#x1EC3;u s&#xE2;u nh&#x1EA5;t l&#xE0; xem m&#x1ED9;t h&#x1EC7; th&#x1ED1;ng <em>th&#x1EF1;c t&#x1EBF;</em> &#x111;ang d&#xF9;ng sai c&#xF4;ng c&#x1EE5;, v&#xE0; ph&#xE2;n t&#xED;ch t&#x1EA1;i sao.</p><p>D&#x1B0;&#x1EDB;i &#x111;&#xE2;y l&#xE0; ki&#x1EBF;n tr&#xFA;c c&#x1EE7;a m&#x1ED9;t quy tr&#xEC;nh x&#xE2;y d&#x1EF1;ng ch&#x1B0;&#x1A1;ng tr&#xEC;nh h&#x1ECD;c &#x111;ang d&#xF9;ng Lobster &#x111;&#x1EC3; &#x111;i&#x1EC1;u ph&#x1ED1;i <em>to&#xE0;n b&#x1ED9;</em> &#x2014; bao g&#x1ED3;m c&#x1EA3; ph&#x1EA7;n &#x111;i&#x1EC1;u ph&#x1ED1;i c&#xE1;c phi&#xEA;n AI:</p><pre><code class="language-yaml"># curriculum_master.lobster

- id: ph1_prep
  command: &gt;
    python tools/prepare_prompt.py
    --skill skills/phase-1/skill-interview
    --context projects/curriculum/00_meta/requirements.md

- id: ph1_interview
  command: &gt;
    openclaw.invoke --tool llm-task --action json --args-json &apos;{
      &quot;prompt&quot;: &quot;Ch&#x1EA1;y skill interview. Output JSON.&quot;,
      &quot;model&quot;: &quot;ollama/qwen3.5:14b&quot;,
      &quot;temperature&quot;: 0.6,
      &quot;maxTokens&quot;: 2000
    }&apos;
  stdin: $ph1_prep.stdout

- id: ph1_save
  command: python tools/file_manager.py save --path &quot;projects/curriculum/00_meta/requirements.md&quot;
  stdin: $ph1_interview.stdout
</code></pre><p>V&#xE0; m&#x1ED9;t &#x111;o&#x1EA1;n t&#x1EEB; c&#xF9;ng t&#xE0;i li&#x1EC7;u thi&#x1EBF;t k&#x1EBF;:</p><blockquote><em>&quot;Giai &#x111;o&#x1EA1;n 6&#x2013;7 &#x111;&#x1B0;&#x1EE3;c x&#x1EED; l&#xFD; b&#x1EB1;ng script Python ri&#xEA;ng v&#xEC; Lobster kh&#xF4;ng c&#xF3; v&#xF2;ng l&#x1EB7;p for t&#xED;ch h&#x1EE3;p s&#x1EB5;n.&quot;</em></blockquote><p>Hai &#x111;o&#x1EA1;n n&#xE0;y ch&#x1EE9;a <strong>ba d&#x1EA5;u hi&#x1EC7;u</strong> c&#x1EE7;a m&#x1ED9;t h&#x1EC7; th&#x1ED1;ng &#x111;ang d&#xF9;ng sai t&#x1EA7;ng.</p><hr><h3 id="d%E1%BA%A5u-hi%E1%BB%87u-1-preparepromptpy-kh%C3%B4ng-n%C3%AAn-t%E1%BB%93n-t%E1%BA%A1i">D&#x1EA5;u hi&#x1EC7;u 1: <code>prepare_prompt.py</code> kh&#xF4;ng n&#xEA;n t&#x1ED3;n t&#x1EA1;i</h3><p>C&#xF4;ng c&#x1EE5; <code>prepare_prompt.py</code> l&#xE0;m m&#x1ED9;t vi&#x1EC7;c duy nh&#x1EA5;t: &#x111;&#x1ECD;c <code>SKILL.md</code> t&#x1EEB; th&#x1B0; m&#x1EE5;c k&#x1EF9; n&#x103;ng, g&#x1ED9;p c&#xE1;c t&#x1EC7;p tham chi&#x1EBF;u, &#x111;i&#x1EC1;n bi&#x1EBF;n, r&#x1ED3;i t&#x1EA1;o m&#x1ED9;t chu&#x1ED7;i v&#x103;n b&#x1EA3;n l&#xE0;m &#x111;&#x1EA7;u v&#xE0;o cho <code>llm-task</code>.</p><p>L&#xFD; do n&#xF3; ph&#x1EA3;i t&#x1ED3;n t&#x1EA1;i: <strong>Lobster kh&#xF4;ng bi&#x1EBF;t c&#xE1;ch n&#xF3;i chuy&#x1EC7;n v&#x1EDB;i ng&#x1EEF; c&#x1EA3;nh AI</strong>. N&#xF3; l&#xE0; v&#x1ECF; th&#x1EF1;c thi &#x2014; n&#xF3; ch&#x1EC9; bi&#x1EBF;t &#x111;&#x1EA7;u v&#xE0;o/&#x111;&#x1EA7;u ra. &#x110;&#x1EC3; &#x111;&#x1B0;a k&#x1EF9; n&#x103;ng v&#xE0; ng&#x1EEF; c&#x1EA3;nh v&#xE0;o l&#x1EDD;i g&#x1ECD;i m&#xF4; h&#xEC;nh, b&#x1EA1;n ph&#x1EA3;i t&#x1EF1; x&#xE2;y d&#x1EF1;ng c&#x1EA7;u n&#x1ED1;i th&#x1EE7; c&#xF4;ng.</p><p>OpenProse lo&#x1EA1;i b&#x1ECF; ho&#xE0;n to&#xE0;n s&#x1EF1; c&#x1EA7;n thi&#x1EBF;t c&#x1EE7;a c&#x1EA7;u n&#x1ED1;i n&#xE0;y. Trong m&#x1ED9;t ch&#x1B0;&#x1A1;ng tr&#xEC;nh OpenProse, t&#xE1;c nh&#xE2;n <em>l&#xE0;</em> phi&#xEA;n AI &#x2014; n&#xF3; &#x111;&#x1ECD;c t&#x1EC7;p k&#x1EF9; n&#x103;ng, hi&#x1EC3;u ng&#x1EEF; c&#x1EA3;nh, v&#xE0; &#x111;&#x1B0;a th&#xF4;ng tin v&#xE0;o l&#x1EDD;i nh&#x1EAF;c m&#x1ED9;t c&#xE1;ch t&#x1EF1; nhi&#xEA;n, kh&#xF4;ng c&#x1EA7;n l&#x1EDB;p bao b&#x1ECD;c.</p><pre><code>Ki&#x1EBF;n tr&#xFA;c c&#xF3; v&#x1EA5;n &#x111;&#x1EC1;:
  Lobster (v&#x1ECF; th&#x1EF1;c thi)
      &#x2192; prepare_prompt.py (c&#x1EA7;u n&#x1ED1;i th&#x1EE7; c&#xF4;ng)
      &#x2192; llm-task (l&#x1EDD;i g&#x1ECD;i m&#xF4; h&#xEC;nh)
      &#x2192; file_manager.py (l&#x1B0;u k&#x1EBF;t qu&#x1EA3;)

Ki&#x1EBF;n tr&#xFA;c &#x111;&#xFA;ng:
  Phi&#xEA;n OpenProse (hi&#x1EC3;u AI)
      &#x2192; &#x111;&#x1ECD;c t&#x1EC7;p k&#x1EF9; n&#x103;ng tr&#x1EF1;c ti&#x1EBF;p
      &#x2192; l&#xFD; lu&#x1EAD;n v&#x1EC1; ng&#x1EEF; c&#x1EA3;nh
      &#x2192; [g&#x1ECD;i Lobster khi c&#x1EA7;n th&#x1EF1;c thi t&#x1EA5;t &#x111;&#x1ECB;nh + ph&#xEA; duy&#x1EC7;t]
</code></pre><hr><h3 id="d%E1%BA%A5u-hi%E1%BB%87u-2-ki%E1%BA%BFn-tr%C3%BAc-t%C3%A1c-nh%C3%A2n-con-ph%E1%BA%A3i-t%E1%BB%B1-x%C3%A2y-t%E1%BB%AB-%C4%91%E1%BA%A7u">D&#x1EA5;u hi&#x1EC7;u 2: Ki&#x1EBF;n tr&#xFA;c t&#xE1;c nh&#xE2;n con ph&#x1EA3;i t&#x1EF1; x&#xE2;y t&#x1EEB; &#x111;&#x1EA7;u</h3><p>C&#xF9;ng t&#xE0;i li&#x1EC7;u thi&#x1EBF;t k&#x1EBF; m&#xF4; t&#x1EA3; to&#xE0;n b&#x1ED9; ki&#x1EBF;n tr&#xFA;c ba t&#x1EA7;ng ph&#x1EA3;i t&#x1EF1; x&#xE2;y d&#x1EF1;ng th&#x1EE7; c&#xF4;ng:</p><pre><code>T&#xE1;c nh&#xE2;n ch&#xED;nh (t&#x1EA7;ng 0)
  &#x2192; sessions_spawn &#x2192; &#x110;i&#x1EC1;u ph&#x1ED1;i giai &#x111;o&#x1EA1;n 8 (t&#x1EA7;ng 1)
                       &#x2192; sessions_spawn &#x2192; C&#xE1;c nh&#xE2;n vi&#xEA;n b&#xE0;i h&#x1ECD;c (t&#x1EA7;ng 2)
</code></pre><p>Bao g&#x1ED3;m: t&#x1EF1; vi&#x1EBF;t logic &#x111;&#x1B0;a g&#xF3;i nhi&#x1EC7;m v&#x1EE5; v&#xE0;o <code>AGENTS.md</code> tr&#x1B0;&#x1EDB;c khi t&#x1EA1;o nh&#xE2;n vi&#xEA;n, t&#x1EF1; x&#x1EED; l&#xFD; m&#x1EAB;u th&#xF4;ng b&#xE1;o, t&#x1EF1; qu&#x1EA3;n l&#xFD; tr&#x1EA1;ng th&#xE1;i gi&#x1EEF;a c&#xE1;c t&#x1EA7;ng.</p><p>&#x110;&#xE2;y ch&#xED;nh x&#xE1;c l&#xE0; nh&#x1EEF;ng g&#xEC; OpenProse &#x111;&#x1B0;&#x1EE3;c thi&#x1EBF;t k&#x1EBF; &#x111;&#x1EC3; l&#xE0;m &#x2014; <strong>c&#xF3; s&#x1EB5;n ngay t&#x1EEB; &#x111;&#x1EA7;u</strong>:</p><pre><code class="language-yaml"># Thay th&#x1EBF; to&#xE0;n b&#x1ED9; ki&#x1EBF;n tr&#xFA;c ba t&#x1EA7;ng tr&#xEA;n b&#x1EB1;ng:

parallel:
  for lesson in lessons:
    result_{lesson.id} = session: lesson_worker
      prompt: &quot;Execute lesson materials for {lesson.title} using skill {lesson.skill}.&quot;
      context: { lesson, constraints, unit_framework }
</code></pre><p>Kh&#xF4;ng c&#x1EA7;n &#x111;&#x1B0;a ng&#x1EEF; c&#x1EA3;nh th&#x1EE7; c&#xF4;ng, kh&#xF4;ng c&#x1EA7;n t&#x1EF1; x&#xE2;y m&#x1EAB;u th&#xF4;ng b&#xE1;o, kh&#xF4;ng c&#x1EA7;n qu&#x1EA3;n l&#xFD; <code>AGENTS.md</code> gi&#x1EEF;a c&#xE1;c l&#x1EA7;n t&#x1EA1;o t&#xE1;c nh&#xE2;n.</p><hr><h3 id="d%E1%BA%A5u-hi%E1%BB%87u-3-lobster-kh%C3%B4ng-c%C3%B3-v%C3%B2ng-l%E1%BA%B7p-for-%E2%80%94-%C4%91ang-%E1%BB%9F-sai-t%E1%BA%A7ng">D&#x1EA5;u hi&#x1EC7;u 3: &quot;Lobster kh&#xF4;ng c&#xF3; v&#xF2;ng l&#x1EB7;p for&quot; &#x2014; &#x111;ang &#x1EDF; sai t&#x1EA7;ng</h3><p>Khi b&#x1EA1;n c&#x1EA7;n v&#xF2;ng l&#x1EB7;p, khi b&#x1EA1;n c&#x1EA7;n logic &#x111;i&#x1EC1;u ki&#x1EC7;n ph&#x1EE9;c t&#x1EA1;p, khi b&#x1EA1;n c&#x1EA7;n &#x111;i&#x1EC1;u ph&#x1ED1;i nhi&#x1EC1;u phi&#xEA;n AI &#x2014; &#x111;&#xF3; l&#xE0; l&#xFA;c b&#x1EA1;n &#x111;&#xE3; v&#x1B0;&#x1EE3;t ra ngo&#xE0;i ph&#x1EA1;m vi c&#x1EE7;a Lobster.</p><p>Lobster l&#xE0; <strong>v&#x1ECF; th&#x1EF1;c thi quy tr&#xEC;nh</strong>, kh&#xF4;ng ph&#x1EA3;i ng&#xF4;n ng&#x1EEF; &#x111;i&#x1EC1;u ph&#x1ED1;i. Gi&#x1ED1;ng nh&#x1B0; b&#x1EA1;n kh&#xF4;ng n&#xEA;n d&#xF9;ng script Bash &#x111;&#x1EC3; qu&#x1EA3;n l&#xFD; m&#xE1;y tr&#x1EA1;ng th&#xE1;i ph&#x1EE9;c t&#x1EA1;p c&#x1EE7;a m&#x1ED9;t &#x1EE9;ng d&#x1EE5;ng &#x2014; Bash l&#xE0; c&#xF4;ng c&#x1EE5; sai cho b&#xE0;i to&#xE1;n &#x111;&#xF3;.</p><p>T&#x1ED5;ng k&#x1EBF;t c&#xE1;c d&#x1EA5;u hi&#x1EC7;u:</p><!--kg-card-begin: html--><table>
<thead>
<tr>
<th>D&#x1EA5;u hi&#x1EC7;u</th>
<th>Nguy&#xEA;n nh&#xE2;n g&#x1ED1;c r&#x1EC5;</th>
<th>Gi&#x1EA3;i ph&#xE1;p</th>
</tr>
</thead>
<tbody>
<tr>
<td>Ph&#x1EA3;i t&#x1EF1; vi&#x1EBF;t <code>prepare_prompt.py</code></td>
<td>Lobster kh&#xF4;ng hi&#x1EC3;u ng&#x1EEF; c&#x1EA3;nh AI</td>
<td>&#x110;&#x1EC3; OpenProse x&#x1EED; l&#xFD; ng&#x1EEF; c&#x1EA3;nh AI</td>
</tr>
<tr>
<td>Ph&#x1EA3;i t&#x1EF1; x&#xE2;y t&#xE1;c nh&#xE2;n con ba t&#x1EA7;ng</td>
<td>Lobster kh&#xF4;ng c&#xF3; &#x111;i&#x1EC1;u ph&#x1ED1;i</td>
<td>D&#xF9;ng &#x111;a t&#xE1;c nh&#xE2;n t&#xED;ch h&#x1EE3;p s&#x1EB5;n c&#x1EE7;a OpenProse</td>
</tr>
<tr>
<td>Ph&#x1EA3;i d&#xF9;ng Python v&#xEC; &quot;Lobster thi&#x1EBF;u v&#xF2;ng l&#x1EB7;p&quot;</td>
<td>&#x110;ang &#x1EDF; sai t&#x1EA7;ng</td>
<td>OpenProse c&#xF3; lu&#x1ED3;ng ki&#x1EC3;m so&#xE1;t t&#xED;ch h&#x1EE3;p s&#x1EB5;n</td>
</tr>
<tr>
<td>Ng&#x1EEF; c&#x1EA3;nh phi&#xEA;n ch&#xED;nh b&#x1ECB; ph&#xEC;nh to &#x1EDF; giai &#x111;o&#x1EA1;n 8</td>
<td>Kh&#xF4;ng c&#xF3; c&#xF4; l&#x1EAD;p ng&#x1EEF; c&#x1EA3;nh</td>
<td>T&#xE1;c nh&#xE2;n con OpenProse c&#xF3; phi&#xEA;n ri&#xEA;ng</td>
</tr>
</tbody>
</table><!--kg-card-end: html--><hr><h2 id="5-ph%C3%A2n-chia-vai-tr%C3%B2-%C4%91%C3%BAng">5. Ph&#xE2;n Chia Vai Tr&#xF2; &#x110;&#xFA;ng</h2><p>Sau khi hi&#x1EC3;u c&#xE1;c sai l&#x1EA7;m ph&#x1ED5; bi&#x1EBF;n, c&#xE2;u h&#x1ECF;i tr&#x1EDF; th&#xE0;nh: <strong>ai l&#xE0;m g&#xEC;?</strong></p><pre><code>&#x250C;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2510;
&#x2502;  OPENPROSE &#x2014; T&#x1EA7;ng &#x110;i&#x1EC1;u Ph&#x1ED1;i                                 &#x2502;
&#x2502;                                                             &#x2502;
&#x2502;  &#x2022; &#x110;&#x1ECB;nh ngh&#x129;a quy tr&#xEC;nh, lu&#x1ED3;ng ki&#x1EC3;m so&#xE1;t, &#x111;a t&#xE1;c nh&#xE2;n      &#x2502;
&#x2502;  &#x2022; &#x110;&#x1ECD;c k&#x1EF9; n&#x103;ng, l&#xFD; lu&#x1EAD;n v&#x1EC1; ng&#x1EEF; c&#x1EA3;nh, x&#xE2;y d&#x1EF1;ng phi&#xEA;n AI     &#x2502;
&#x2502;  &#x2022; Th&#x1EF1;c thi song song, c&#xF4; l&#x1EAD;p ng&#x1EEF; c&#x1EA3;nh                     &#x2502;
&#x2502;  &#x2022; Qu&#x1EA3;n l&#xFD; tr&#x1EA1;ng th&#xE1;i qua c&#xE1;c phi&#xEA;n                        &#x2502;
&#x2502;  &#x2022; G&#x1ECD;i Lobster nh&#x1B0; m&#x1ED9;t c&#xF4;ng c&#x1EE5; b&#xEA;n d&#x1B0;&#x1EDB;i                     &#x2502;
&#x2514;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x252C;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2518;
                       &#x2502; g&#x1ECD;i khi c&#x1EA7;n
&#x250C;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x25BC;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2510;
&#x2502;  LOBSTER &#x2014; T&#x1EA7;ng Th&#x1EF1;c Thi                                    &#x2502;
&#x2502;                                                             &#x2502;
&#x2502;  &#x2022; Ch&#x1EA1;y chu&#x1ED7;i l&#x1EC7;nh shell/CLI theo th&#x1EE9; t&#x1EF1; x&#xE1;c &#x111;&#x1ECB;nh          &#x2502;
&#x2502;  &#x2022; C&#x1ED5;ng ph&#xEA; duy&#x1EC7;t tr&#x1B0;&#x1EDB;c c&#xE1;c t&#xE1;c d&#x1EE5;ng ph&#x1EE5;                   &#x2502;
&#x2502;  &#x2022; Truy&#x1EC1;n JSON gi&#x1EEF;a c&#xE1;c b&#x1B0;&#x1EDB;c                               &#x2502;
&#x2502;  &#x2022; Ti&#x1EBF;p t&#x1EE5;c v&#x1EDB;i token sau khi &#x111;&#x1B0;&#x1EE3;c ph&#xEA; duy&#x1EC7;t               &#x2502;
&#x2502;  &#x2022; Ki&#x1EC3;m tra schema, l&#x1B0;u t&#x1EC7;p, so s&#xE1;nh s&#x1EF1; kh&#xE1;c bi&#x1EC7;t         &#x2502;
&#x2514;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2518;
</code></pre><p><strong>B&#x1EA3;ng ph&#xE2;n chia theo lo&#x1EA1;i c&#xF4;ng vi&#x1EC7;c:</strong></p><!--kg-card-begin: html--><table>
<thead>
<tr>
<th>Lo&#x1EA1;i c&#xF4;ng vi&#x1EC7;c</th>
<th>C&#xF4;ng c&#x1EE5; &#x111;&#xFA;ng</th>
<th>L&#xFD; do</th>
</tr>
</thead>
<tbody>
<tr>
<td>&#x110;&#x1ECB;nh ngh&#x129;a quy tr&#xEC;nh nhi&#x1EC1;u b&#x1B0;&#x1EDB;c, &#x111;i&#x1EC1;u ph&#x1ED1;i AI</td>
<td><strong>OpenProse</strong></td>
<td>Hi&#x1EC3;u ng&#x1EEF; c&#x1EA3;nh v&#xE0; m&#x1EE5;c &#x111;&#xED;ch</td>
</tr>
<tr>
<td>&#x110;&#x1ECD;c t&#x1EC7;p k&#x1EF9; n&#x103;ng, l&#xFD; lu&#x1EAD;n v&#x1EC1; y&#xEA;u c&#x1EA7;u</td>
<td><strong>OpenProse</strong></td>
<td>&#x110;&#xE2;y l&#xE0; c&#xF4;ng vi&#x1EC7;c c&#x1EE7;a phi&#xEA;n AI</td>
</tr>
<tr>
<td>T&#x1EA1;o v&#xE0; &#x111;i&#x1EC1;u ph&#x1ED1;i nhi&#x1EC1;u t&#xE1;c nh&#xE2;n AI</td>
<td><strong>OpenProse</strong></td>
<td>&#x110;a t&#xE1;c nh&#xE2;n v&#xE0; ch&#x1EA1;y song song t&#xED;ch h&#x1EE3;p s&#x1EB5;n</td>
</tr>
<tr>
<td>V&#xF2;ng l&#x1EB7;p qua danh s&#xE1;ch (b&#xE0;i h&#x1ECD;c, m&#x1EE5;c)</td>
<td><strong>OpenProse</strong></td>
<td>Lu&#x1ED3;ng ki&#x1EC3;m so&#xE1;t t&#xED;ch h&#x1EE3;p s&#x1EB5;n</td>
</tr>
<tr>
<td>Qu&#x1EA3;n l&#xFD; tr&#x1EA1;ng th&#xE1;i gi&#x1EEF;a c&#xE1;c phi&#xEA;n</td>
<td><strong>OpenProse</strong></td>
<td>H&#x1EC7; th&#x1ED1;ng l&#x1B0;u tr&#x1EEF; tr&#x1EA1;ng th&#xE1;i t&#xED;ch h&#x1EE3;p s&#x1EB5;n</td>
</tr>
<tr>
<td>C&#x1ED5;ng ph&#xEA; duy&#x1EC7;t tr&#x1B0;&#x1EDB;c t&#xE1;c d&#x1EE5;ng ph&#x1EE5;</td>
<td><strong>Lobster</strong></td>
<td>&#x110;&#xE2;y l&#xE0; s&#x1EDF; tr&#x1B0;&#x1EDD;ng &#x2014; t&#x1EA5;t &#x111;&#x1ECB;nh, minh b&#x1EA1;ch</td>
</tr>
<tr>
<td>Ki&#x1EC3;m tra schema + l&#x1B0;u k&#x1EBF;t qu&#x1EA3;</td>
<td><strong>Lobster</strong></td>
<td>C&#xF4;ng c&#x1EE5; thu&#x1EA7;n t&#xFA;y, kh&#xF4;ng c&#x1EA7;n l&#xFD; lu&#x1EAD;n AI</td>
</tr>
<tr>
<td>So s&#xE1;nh t&#x1EC7;p, sao l&#x1B0;u phi&#xEA;n b&#x1EA3;n</td>
<td><strong>Lobster</strong></td>
<td>Thao t&#xE1;c &#x1EDF; t&#x1EA7;ng v&#x1ECF;</td>
</tr>
<tr>
<td>Ch&#x1EA1;y l&#x1EC7;nh CLI c&#xF3; t&#xE1;c d&#x1EE5;ng ph&#x1EE5;</td>
<td><strong>Lobster</strong></td>
<td>C&#x1EA7;n c&#x1ED5;ng ph&#xEA; duy&#x1EC7;t v&#xE0; token ti&#x1EBF;p t&#x1EE5;c</td>
</tr>
<tr>
<td>Theo d&#xF5;i thay &#x111;&#x1ED5;i, ph&#xE1;t t&#xED;n hi&#x1EC7;u khi c&#xF3; s&#x1EF1; kh&#xE1;c bi&#x1EC7;t</td>
<td><strong>Lobster</strong></td>
<td>So s&#xE1;nh tr&#x1EA1;ng th&#xE1;i (<code>diff.last</code>)</td>
</tr>
</tbody>
</table><!--kg-card-end: html--><hr><h2 id="6-k%E1%BA%BFt-h%E1%BB%A3p-openprose-lobster-c%C3%A1ch-l%C3%A0m-chu%E1%BA%A9n">6. K&#x1EBF;t H&#x1EE3;p OpenProse + Lobster: C&#xE1;ch L&#xE0;m Chu&#x1EA9;n</h2><p>&#x110;&#xE2;y l&#xE0; c&#xE1;ch t&#x1ED5; ch&#x1EE9;c n&#xEA;n tr&#x1EDF; th&#xE0;nh t&#x1B0; duy m&#x1EB7;c &#x111;&#x1ECB;nh c&#x1EE7;a b&#x1EA1;n khi thi&#x1EBF;t k&#x1EBF; quy tr&#xEC;nh ph&#x1EE9;c t&#x1EA1;p trong OpenClaw.</p><h3 id="61-ki%E1%BA%BFn-tr%C3%BAc-t%E1%BB%95ng-qu%C3%A1t">6.1 Ki&#x1EBF;n tr&#xFA;c t&#x1ED5;ng qu&#xE1;t</h3><pre><code>/prose run curriculum-pipeline.prose
          &#x2502;
          &#x25BC;
    [M&#xE1;y &#x1EA3;o OpenProse]
    &#x250C;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2510;
    &#x2502;                                         &#x2502;
    &#x2502;  &#x110;&#x1ECD;c y&#xEA;u c&#x1EA7;u, nghi&#xEA;n c&#x1EE9;u ng&#x1EEF; c&#x1EA3;nh      &#x2502; &#x2190; C&#xF4;ng vi&#x1EC7;c phi&#xEA;n AI
    &#x2502;  V&#xF2;ng l&#x1EB7;p qua c&#xE1;c giai &#x111;o&#x1EA1;n, l&#x1B0;u TT    &#x2502; &#x2190; Lu&#x1ED3;ng ki&#x1EC3;m so&#xE1;t OpenProse
    &#x2502;  T&#x1EA1;o nh&#xE2;n vi&#xEA;n b&#xE0;i h&#x1ECD;c song song        &#x2502; &#x2190; &#x110;a t&#xE1;c nh&#xE2;n t&#xED;ch h&#x1EE3;p s&#x1EB5;n
    &#x2502;                                         &#x2502;
    &#x2502;  Khi c&#x1EA7;n ph&#xEA; duy&#x1EC7;t tr&#x1B0;&#x1EDB;c t&#xE1;c d&#x1EE5;ng ph&#x1EE5;: &#x2502;
    &#x2502;  &#x2192; G&#x1ECD;i Lobster v&#x1EDB;i chu&#x1ED7;i l&#x1EC7;nh + c&#x1ED5;ng   &#x2502; &#x2190; Th&#x1EF1;c thi Lobster
    &#x2502;  &#x2192; Nh&#x1EAD;n resumeToken, ch&#x1EDD; ng&#x1B0;&#x1EDD;i d&#xF9;ng     &#x2502;
    &#x2502;  &#x2192; Ph&#xEA; duy&#x1EC7;t &#x2192; Lobster ti&#x1EBF;p t&#x1EE5;c         &#x2502;
    &#x2502;                                         &#x2502;
    &#x2502;  Khi c&#x1EA7;n ki&#x1EC3;m tra + l&#x1B0;u k&#x1EBF;t qu&#x1EA3;:        &#x2502;
    &#x2502;  &#x2192; G&#x1ECD;i Lobster v&#x1EDB;i chu&#x1ED7;i ki&#x1EC3;m tra      &#x2502; &#x2190; Th&#x1EF1;c thi Lobster
    &#x2502;  &#x2192; Nh&#x1EAD;n k&#x1EBF;t qu&#x1EA3; JSON, ti&#x1EBF;p t&#x1EE5;c          &#x2502;
    &#x2514;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2518;
</code></pre><h3 id="62-v%C3%AD-d%E1%BB%A5-th%E1%BB%B1c-t%E1%BA%BF-quy-tr%C3%ACnh-x%C3%A2y-d%E1%BB%B1ng-ch%C6%B0%C6%A1ng-tr%C3%ACnh-h%E1%BB%8Dc">6.2 V&#xED; d&#x1EE5; th&#x1EF1;c t&#x1EBF;: Quy Tr&#xEC;nh X&#xE2;y D&#x1EF1;ng Ch&#x1B0;&#x1A1;ng Tr&#xEC;nh H&#x1ECD;c</h3><p>D&#x1B0;&#x1EDB;i &#x111;&#xE2;y l&#xE0; c&#xE1;ch vi&#x1EBF;t l&#x1EA1;i ki&#x1EBF;n tr&#xFA;c t&#x1EEB; M&#x1EE5;c 4 theo &#x111;&#xFA;ng c&#xE1;ch l&#xE0;m:</p><p><strong><code>curriculum-pipeline.prose</code> &#x2014; T&#x1EA7;ng OpenProse:</strong></p><pre><code class="language-yaml">---
name: curriculum-pipeline
kind: program
---

requires:
  - project: t&#xEA;n d&#x1EF1; &#xE1;n c&#x1EA7;n t&#x1EA1;o ch&#x1B0;&#x1A1;ng tr&#xEC;nh

ensures:
  - full_curriculum: b&#x1ED9; h&#x1ECD;c li&#x1EC7;u ho&#xE0;n ch&#x1EC9;nh &#x111;&#xE3; qua ph&#xEA; duy&#x1EC7;t c&#x1EE7;a con ng&#x1B0;&#x1EDD;i

# Giai &#x111;o&#x1EA1;n 1&#x2013;3: C&#xF4;ng vi&#x1EC7;c phi&#xEA;n AI &#x2014; OpenProse x&#x1EED; l&#xFD;
session &quot;Thu th&#x1EAD;p y&#xEA;u c&#x1EA7;u t&#x1EEB; ng&#x1B0;&#x1EDD;i d&#xF9;ng qua k&#x1EF9; n&#x103;ng ph&#x1ECF;ng v&#x1EA5;n.&quot;
  skill: skills/phase-1/skill-interview
  output: requirements

session &quot;Nghi&#xEA;n c&#x1EE9;u b&#x1ED1;i c&#x1EA3;nh c&#xF4;ng ngh&#x1EC7; v&#xE0; x&#xE3; h&#x1ED9;i.&quot;
  skill: skills/phase-1/skill-research-synthesis
  context: { requirements }
  output: research_notes

session &quot;&#xC1;nh x&#x1EA1; y&#xEA;u c&#x1EA7;u th&#xE0;nh r&#xE0;ng bu&#x1ED9;c SMART.&quot;
  skill: skills/phase-3-5/skill-constraint-mapping
  context: { requirements, research_notes }
  output: constraints

# C&#x1ED5;ng 1: Ph&#xEA; duy&#x1EC7;t c&#xF3; t&#xE1;c d&#x1EE5;ng ph&#x1EE5; &#x2014; Lobster x&#x1EED; l&#xFD;
invoke lobster:
  pipeline: workflows/gate-approval.lobster
  args: { gate: 1, file: constraints }
  wait_for_approval: true

# Giai &#x111;o&#x1EA1;n 4&#x2013;5: C&#xF4;ng vi&#x1EC7;c phi&#xEA;n AI ti&#x1EBF;p t&#x1EE5;c
session &quot;Thi&#x1EBF;t k&#x1EBF; s&#x1EA3;n ph&#x1EA9;m h&#x1ECD;c t&#x1EAD;p.&quot;
  skill: skills/phase-4/skill-product-design
  context: { constraints }
  output: product_map

session &quot;X&#xE2;y d&#x1EF1;ng khung &#x111;&#x1A1;n v&#x1ECB; h&#x1ECD;c t&#x1EAD;p.&quot;
  skill: skills/phase-3-5/skill-unit-framework
  context: { constraints, product_map }
  output: unit_framework

# C&#x1ED5;ng 2
invoke lobster:
  pipeline: workflows/gate-approval.lobster
  args: { gate: 2, file: unit_framework }
  wait_for_approval: true

# Giai &#x111;o&#x1EA1;n 6&#x2013;7: V&#xF2;ng l&#x1EB7;p &#x2014; OpenProse x&#x1EED; l&#xFD; t&#x1EF1; nhi&#xEA;n
session &quot;Ph&#xE2;n r&#xE3; th&#xE0;nh &#x111;&#x1EB7;c t&#x1EA3; b&#xE0;i h&#x1ECD;c.&quot;
  skill: skills/phase-7/skill-lesson-spec
  context: { unit_framework, constraints }
  output: lesson_specs

# C&#x1ED5;ng 3
invoke lobster:
  pipeline: workflows/gate-approval.lobster
  args: { gate: 3, file: lesson_specs }
  wait_for_approval: true

# Giai &#x111;o&#x1EA1;n 8: &#x110;a t&#xE1;c nh&#xE2;n &#x2014; OpenProse t&#xED;ch h&#x1EE3;p s&#x1EB5;n
parallel:
  for lesson in lesson_specs:
    materials_{lesson.id} = session: lesson_worker
      prompt: &quot;Sinh &#x111;&#x1EA7;y &#x111;&#x1EE7; h&#x1ECD;c li&#x1EC7;u cho {lesson.title}.&quot;
      context: { lesson, constraints, unit_framework }
      tools_allow: [&quot;lobster&quot;]  # Cho ph&#xE9;p nh&#xE2;n vi&#xEA;n g&#x1ECD;i Lobster
</code></pre><p><strong><code>workflows/gate-approval.lobster</code> &#x2014; T&#x1EA7;ng Lobster:</strong></p><pre><code class="language-yaml">name: gate-approval
args:
  gate:
    required: true
  file:
    required: true

steps:
  - id: display
    command: python tools/file_manager.py display_gate_checklist --gate &quot;${gate}&quot; --file &quot;${file}&quot;

  - id: show_content
    command: cat &quot;${file}&quot;

  - id: human_gate
    command: echo &quot;C&#x1ED5;ng ${gate} &#x2014; Ch&#x1EDD; ph&#xEA; duy&#x1EC7;t t&#x1EEB; ng&#x1B0;&#x1EDD;i d&#xF9;ng&quot;
    stdin: $show_content.stdout
    approval: required

  - id: mark_approved
    command: python tools/progress_tracker.py mark_gate &quot;${gate}&quot; approved
    condition: $human_gate.approved
</code></pre><p><strong>Nh&#xE2;n vi&#xEA;n b&#xE0;i h&#x1ECD;c &#x2014; v&#x1EAB;n c&#xF3; th&#x1EC3; d&#xF9;ng Lobster b&#xEA;n trong:</strong></p><pre><code class="language-yaml"># Lobster ch&#x1EA1;y b&#xEA;n trong m&#x1ED7;i t&#xE1;c nh&#xE2;n nh&#xE2;n vi&#xEA;n b&#xE0;i h&#x1ECD;c
# V&#x1EAB;n c&#x1EA7;n v&#xEC; th&#x1EE9; t&#x1EF1; t&#x1EA1;o k&#x1EBF;t qu&#x1EA3; ph&#x1EA3;i t&#x1EA5;t &#x111;&#x1ECB;nh

name: lesson-materials
args:
  lesson_json:
    required: true

steps:
  - id: gen_lesson_plan
    command: &gt;
      openclaw.invoke --tool llm-task --action json --args-json &apos;{
        &quot;prompt&quot;: &quot;Sinh gi&#xE1;o &#xE1;n 5E theo &#x111;&#x1EB7;c t&#x1EA3; b&#xE0;i h&#x1ECD;c.&quot;,
        &quot;model&quot;: &quot;ollama/qwen3.5:14b&quot;,
        &quot;temperature&quot;: 0.4,
        &quot;maxTokens&quot;: 6000
      }&apos;

  - id: validate_lesson_plan
    command: python tools/validator.py validate --schema schemas/lesson_plan.schema.json
    stdin: $gen_lesson_plan.stdout

  - id: save_lesson_plan
    command: python tools/file_manager.py save_artifact --artifact lesson_plan
    stdin: $validate_lesson_plan.stdout

  # ... c&#xE1;c k&#x1EBF;t qu&#x1EA3; ti&#x1EBF;p theo theo th&#x1EE9; t&#x1EF1; x&#xE1;c &#x111;&#x1ECB;nh

  - id: critique
    command: &gt;
      openclaw.invoke --tool llm-task --action json --args-json &apos;{
        &quot;prompt&quot;: &quot;&#x110;&#xE1;nh gi&#xE1; to&#xE0;n b&#x1ED9; h&#x1ECD;c li&#x1EC7;u theo ti&#xEA;u ch&#xED; s&#x1B0; ph&#x1EA1;m.&quot;,
        &quot;model&quot;: &quot;ollama/qwen3.5:14b&quot;,
        &quot;temperature&quot;: 0.2,
        &quot;maxTokens&quot;: 3000
      }&apos;

  - id: check_threshold
    command: python tools/validator.py check_critique_threshold --min-score 85
    stdin: $critique.stdout
</code></pre><h3 id="63-t%E1%BA%A1i-sao-lobster-v%E1%BA%ABn-c%E1%BA%A7n-thi%E1%BA%BFt-b%C3%AAn-trong-nh%C3%A2n-vi%C3%AAn-b%C3%A0i-h%E1%BB%8Dc">6.3 T&#x1EA1;i sao Lobster v&#x1EAB;n c&#x1EA7;n thi&#x1EBF;t b&#xEA;n trong nh&#xE2;n vi&#xEA;n b&#xE0;i h&#x1ECD;c?</h3><p>C&#xF3; th&#x1EC3; b&#x1EA1;n h&#x1ECF;i: t&#x1EA1;i sao kh&#xF4;ng &#x111;&#x1EC3; OpenProse x&#x1EED; l&#xFD; c&#x1EA3; nh&#xE2;n vi&#xEA;n b&#xE0;i h&#x1ECD;c? T&#x1EA1;i sao ph&#x1EA3;i d&#xF9;ng Lobster b&#xEA;n trong nh&#xE2;n vi&#xEA;n?</p><p>C&#xE2;u tr&#x1EA3; l&#x1EDD;i: <strong>th&#x1EE9; t&#x1EF1; t&#x1EA1;o c&#xE1;c k&#x1EBF;t qu&#x1EA3; ph&#x1EA3;i ho&#xE0;n to&#xE0;n x&#xE1;c &#x111;&#x1ECB;nh</strong>.</p><p><code>lesson_plan</code> ph&#x1EA3;i &#x111;&#x1B0;&#x1EE3;c t&#x1EA1;o tr&#x1B0;&#x1EDB;c <code>slides_outline</code>, v&#xEC; ph&#x1EA7;n tr&#xEC;nh chi&#x1EBF;u d&#x1EF1;a tr&#xEA;n gi&#xE1;o &#xE1;n. <code>exercises</code> ph&#x1EA3;i tr&#x1B0;&#x1EDB;c <code>teacher_guide</code>, v&#xEC; h&#x1B0;&#x1EDB;ng d&#x1EAB;n gi&#xE1;o vi&#xEA;n tham chi&#x1EBF;u b&#xE0;i t&#x1EAD;p. &#x110;&#xE2;y l&#xE0; chu&#x1ED7;i ph&#x1EE5; thu&#x1ED9;c nghi&#xEA;m ng&#x1EB7;t.</p><p>Lobster &#x111;&#x1EA3;m b&#x1EA3;o &#x111;i&#x1EC1;u n&#xE0;y b&#x1EB1;ng c&#xFA; ph&#xE1;p <code>stdin: $step.stdout</code> &#x2014; kh&#xF4;ng c&#xF3; b&#x1B0;&#x1EDB;c n&#xE0;o b&#x1EAF;t &#x111;&#x1EA7;u tr&#x1B0;&#x1EDB;c b&#x1B0;&#x1EDB;c tr&#x1B0;&#x1EDB;c ho&#xE0;n th&#xE0;nh v&#xE0; xu&#x1EA5;t k&#x1EBF;t qu&#x1EA3;. OpenProse mang l&#x1EA1;i s&#x1EF1; &#x111;i&#x1EC1;u ph&#x1ED1;i th&#xF4;ng minh; Lobster mang l&#x1EA1;i th&#x1EF1;c thi x&#xE1;c &#x111;&#x1ECB;nh. C&#x1EA3; hai c&#x1EA7;n nhau.</p><h3 id="64-l%E1%BB%A3i-%C3%ADch-c%E1%BB%A5-th%E1%BB%83-c%E1%BB%A7a-c%C3%A1ch-k%E1%BA%BFt-h%E1%BB%A3p">6.4 L&#x1EE3;i &#xED;ch c&#x1EE5; th&#x1EC3; c&#x1EE7;a c&#xE1;ch k&#x1EBF;t h&#x1EE3;p</h3><p>So s&#xE1;nh ki&#x1EBF;n tr&#xFA;c c&#x169; (ch&#x1EC9; d&#xF9;ng Lobster) v&#xE0; ki&#x1EBF;n tr&#xFA;c m&#x1EDB;i (OpenProse + Lobster):</p><!--kg-card-begin: html--><table>
<thead>
<tr>
<th>Kh&#xED;a c&#x1EA1;nh</th>
<th>Ch&#x1EC9; d&#xF9;ng Lobster</th>
<th>OpenProse + Lobster</th>
</tr>
</thead>
<tbody>
<tr>
<td>&#x110;&#x1ECD;c k&#x1EF9; n&#x103;ng, x&#xE2;y d&#x1EF1;ng ng&#x1EEF; c&#x1EA3;nh</td>
<td><code>prepare_prompt.py</code> (c&#x1EA7;u n&#x1ED1;i th&#x1EE7; c&#xF4;ng)</td>
<td>OpenProse t&#x1EF1; x&#x1EED; l&#xFD; (kh&#xF4;ng c&#x1EA7;n m&#xE3; th&#xEA;m)</td>
</tr>
<tr>
<td>V&#xF2;ng l&#x1EB7;p qua b&#xE0;i h&#x1ECD;c</td>
<td>Script Python ri&#xEA;ng (gi&#x1EA3;i ph&#xE1;p v&#xE1; v&#xED;u)</td>
<td><code>for lesson in lessons:</code> (t&#xED;ch h&#x1EE3;p s&#x1EB5;n)</td>
</tr>
<tr>
<td>Th&#x1EF1;c thi song song</td>
<td>Kh&#xF4;ng c&#xF3;</td>
<td>Kh&#x1ED1;i <code>parallel:</code> (t&#xED;ch h&#x1EE3;p s&#x1EB5;n)</td>
</tr>
<tr>
<td>&#x110;i&#x1EC1;u ph&#x1ED1;i t&#xE1;c nh&#xE2;n con</td>
<td>T&#x1EF1; x&#xE2;y ba t&#x1EA7;ng + &#x111;&#x1B0;a v&#xE0;o AGENTS.md</td>
<td>&#x110;a t&#xE1;c nh&#xE2;n OpenProse (t&#xED;ch h&#x1EE3;p s&#x1EB5;n)</td>
</tr>
<tr>
<td>C&#xF4; l&#x1EAD;p ng&#x1EEF; c&#x1EA3;nh</td>
<td>T&#x1EF1; qu&#x1EA3;n l&#xFD;</td>
<td>M&#x1ED7;i phi&#xEA;n con c&#xF3; ng&#x1EEF; c&#x1EA3;nh ri&#xEA;ng</td>
</tr>
<tr>
<td>C&#x1ED5;ng ph&#xEA; duy&#x1EC7;t</td>
<td>Lobster <code>approval: required</code> &#x2713;</td>
<td>Lobster <code>approval: required</code> &#x2713;</td>
</tr>
<tr>
<td>Th&#x1EF1;c thi x&#xE1;c &#x111;&#x1ECB;nh</td>
<td>C&#xE1;c b&#x1B0;&#x1EDB;c Lobster &#x2713;</td>
<td>C&#xE1;c b&#x1B0;&#x1EDB;c Lobster &#x2713;</td>
</tr>
<tr>
<td>Ti&#x1EBF;p t&#x1EE5;c sau s&#x1EF1; c&#x1ED1;</td>
<td>resumeToken Lobster &#x2713;</td>
<td>resumeToken Lobster &#x2713;</td>
</tr>
<tr>
<td>S&#x1ED1; d&#xF2;ng m&#xE3; h&#x1EA1; t&#x1EA7;ng</td>
<td>~500 (c&#xF4;ng c&#x1EE5; Python)</td>
<td>~150 (c&#x1EA7;u n&#x1ED1;i t&#x1ED1;i gi&#x1EA3;n)</td>
</tr>
</tbody>
</table><!--kg-card-end: html--><hr><h2 id="7-k%E1%BA%BFt-lu%E1%BA%ADn">7. K&#x1EBF;t Lu&#x1EAD;n</h2><p>Lobster v&#xE0; OpenProse l&#xE0; hai c&#xF4;ng c&#x1EE5; ph&#x1EA3;n &#xE1;nh hai c&#xE1;ch t&#x1B0; duy kh&#xE1;c nhau, ph&#x1EE5;c v&#x1EE5; hai nhu c&#x1EA7;u kh&#xE1;c nhau &#x2014; nh&#x1B0;ng b&#x1ED5; sung cho nhau m&#x1ED9;t c&#xE1;ch t&#x1EF1; nhi&#xEA;n khi &#x111;&#x1B0;&#x1EE3;c d&#xF9;ng &#x111;&#xFA;ng.</p><p><strong>Lobster</strong> tr&#x1EA3; l&#x1EDD;i c&#xE2;u h&#x1ECF;i: <em>&quot;L&#xE0;m th&#x1EBF; n&#xE0;o &#x111;&#x1EC3; t&#xF4;i ch&#x1EAF;c ch&#x1EAF;n r&#x1EB1;ng chu&#x1ED7;i l&#x1EC7;nh n&#xE0;y ch&#x1EA1;y theo &#x111;&#xFA;ng th&#x1EE9; t&#x1EF1;, kh&#xF4;ng c&#xF3; g&#xEC; b&#x1EA5;t ng&#x1EDD;, v&#xE0; ng&#x1B0;&#x1EDD;i d&#xF9;ng c&#xF3; th&#x1EC3; ki&#x1EC3;m so&#xE1;t m&#x1ECD;i t&#xE1;c d&#x1EE5;ng ph&#x1EE5;?&quot;</em> C&#xE2;u tr&#x1EA3; l&#x1EDD;i c&#x1EE7;a n&#xF3; l&#xE0; t&#x1EA5;t &#x111;&#x1ECB;nh, c&#xF3; ki&#x1EC3;u d&#x1EEF; li&#x1EC7;u, minh b&#x1EA1;ch.</p><p><strong>OpenProse</strong> tr&#x1EA3; l&#x1EDD;i c&#xE2;u h&#x1ECF;i: <em>&quot;L&#xE0;m th&#x1EBF; n&#xE0;o &#x111;&#x1EC3; t&#xF4;i &#x111;i&#x1EC1;u ph&#x1ED1;i nhi&#x1EC1;u phi&#xEA;n AI th&#xF4;ng minh, v&#x1EDB;i ng&#x1EEF; c&#x1EA3;nh &#x111;&#x1EA7;y &#x111;&#x1EE7;, m&#xE0; kh&#xF4;ng c&#x1EA7;n vi&#x1EBF;t m&#xE3; h&#x1EA1; t&#x1EA7;ng cho nh&#x1EEF;ng th&#x1EE9; AI &#x111;&#xE3; bi&#x1EBF;t c&#xE1;ch l&#xE0;m?&quot;</em> C&#xE2;u tr&#x1EA3; l&#x1EDD;i c&#x1EE7;a n&#xF3; d&#x1EF1;a tr&#xEA;n m&#xF4; ph&#x1ECF;ng, khai b&#xE1;o, v&#xE0; &#x111;a n&#x1EC1;n t&#x1EA3;ng.</p><p><strong>Nguy&#xEA;n t&#x1EAF;c c&#x1ED1;t l&#xF5;i</strong> c&#x1EA7;n nh&#x1EDB; khi thi&#x1EBF;t k&#x1EBF; b&#x1EA5;t k&#x1EF3; quy tr&#xEC;nh t&#xE1;c nh&#xE2;n n&#xE0;o trong OpenClaw:</p><blockquote>N&#x1EBF;u b&#x1EA1;n &#x111;ang vi&#x1EBF;t m&#xE3; &#x111;&#x1EC3; <em>n&#xF3;i chuy&#x1EC7;n v&#x1EDB;i AI</em>, b&#x1EA1;n &#x111;ang &#x1EDF; sai t&#x1EA7;ng. &#x110;&#xF3; l&#xE0; vi&#x1EC7;c c&#x1EE7;a OpenProse. N&#x1EBF;u b&#x1EA1;n &#x111;ang x&#xE1;c &#x111;&#x1ECB;nh <em>nh&#x1EEF;ng g&#xEC; x&#x1EA3;y ra sau khi AI quy&#x1EBF;t &#x111;&#x1ECB;nh</em>, b&#x1EA1;n &#x111;ang &#x1EDF; &#x111;&#xFA;ng t&#x1EA7;ng. &#x110;&#xF3; l&#xE0; vi&#x1EC7;c c&#x1EE7;a Lobster.</blockquote><p>V&#xE0; khi c&#x1EA3; hai ph&#x1ED1;i h&#x1EE3;p: OpenProse suy ngh&#x129;, &#x111;i&#x1EC1;u ph&#x1ED1;i, v&#xE0; quy&#x1EBF;t &#x111;&#x1ECB;nh. Lobster th&#x1EF1;c thi, ki&#x1EC3;m so&#xE1;t, v&#xE0; b&#x1EA3;o v&#x1EC7;.</p><hr><p><em>Tham kh&#x1EA3;o: <a href="https://docs.openclaw.ai/tools/lobster">docs.openclaw.ai/tools/lobster</a> &#xB7; <a href="https://docs.openclaw.ai/prose">docs.openclaw.ai/prose</a> &#xB7; <a href="https://github.com/openprose/prose">github.com/openprose/prose</a></em></p>]]></content:encoded></item><item><title><![CDATA[Scratch - MakeCode - Blockly]]></title><description><![CDATA[Sự khác biệt chủ yếu nằm ở triết lý thiết kế, mục tiêu giáo dục và đối tượng người dùng mà đội ngũ phát triển nhắm đến]]></description><link>https://makexyz.fun/scratch-makecode-blockly/</link><guid isPermaLink="false">69c0bdbf44a68a6ca0047da2</guid><dc:creator><![CDATA[Tony Phạm]]></dc:creator><pubDate>Mon, 23 Mar 2026 04:15:47 GMT</pubDate><content:encoded><![CDATA[<p><strong>H&#x1ECF;i: Tri&#x1EBF;t l&#xFD; c&#x1EE7;a Scratch 3 v&#xE0; PXT-arcade v&#xE0; Blockly kh&#xE1;c g&#xEC; nhau m&#xE0; ch&#xFA;ng ta c&#xF3; c&#xE1;c s&#x1EA3;n ph&#x1EA9;m kh&#xE1;c nhau - d&#xF9; ch&#xFA;ng chung g&#x1ED1;c?</strong></p><p><strong>&#x110;&#xE1;p:</strong> D&#xF9; <strong>Scratch 3</strong>, <strong>PXT/MakeCode Arcade</strong> v&#xE0; <strong>Blockly g&#x1ED1;c</strong> &#x111;&#x1EC1;u c&#xF3; chung g&#x1ED1;c r&#x1EC5; (block-based visual programming, Scratch 3.0 v&#xE0; MakeCode &#x111;&#x1EC1;u x&#xE2;y d&#x1EF1;ng tr&#xEA;n n&#x1EC1;n t&#x1EA3;ng <strong>Blockly</strong> c&#x1EE7;a Google), nh&#x1B0;ng ch&#xFA;ng l&#x1EA1;i t&#x1EA1;o ra c&#xE1;c s&#x1EA3;n ph&#x1EA9;m r&#x1EA5;t kh&#xE1;c nhau. S&#x1EF1; kh&#xE1;c bi&#x1EC7;t ch&#x1EE7; y&#x1EBF;u n&#x1EB1;m &#x1EDF; <strong>tri&#x1EBF;t l&#xFD; thi&#x1EBF;t k&#x1EBF; (design philosophy)</strong>, <strong>m&#x1EE5;c ti&#xEA;u gi&#xE1;o d&#x1EE5;c</strong> v&#xE0; <strong>&#x111;&#x1ED1;i t&#x1B0;&#x1EE3;ng ng&#x1B0;&#x1EDD;i d&#xF9;ng</strong> m&#xE0; &#x111;&#x1ED9;i ng&#x169; ph&#xE1;t tri&#x1EC3;n nh&#x1EAF;m &#x111;&#x1EBF;n.</p><p>D&#x1B0;&#x1EDB;i &#x111;&#xE2;y l&#xE0; b&#x1EA3;ng so s&#xE1;nh r&#xF5; r&#xE0;ng c&#xE1;c tri&#x1EBF;t l&#xFD; c&#x1ED1;t l&#xF5;i:</p><!--kg-card-begin: html--><table>
<thead>
<tr>
<th>Ti&#xEA;u ch&#xED;</th>
<th><strong>Scratch 3 (MIT Media Lab)</strong></th>
<th><strong>PXT / MakeCode Arcade (Microsoft)</strong></th>
<th><strong>Blockly g&#x1ED1;c (Google)</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Tri&#x1EBF;t l&#xFD; gi&#xE1;o d&#x1EE5;c ch&#xED;nh</strong></td>
<td><strong>Constructionism</strong> (Seymour Papert/Resnick): H&#x1ECD;c qua vi&#x1EC7;c <strong>t&#x1EA1;o ra</strong> v&#xE0; <strong>chia s&#x1EBB;</strong> s&#x1EA3;n ph&#x1EA9;m &#xFD; ngh&#x129;a, s&#xE1;ng t&#x1EA1;o c&#xE1; nh&#xE2;n. T&#x1EAD;p trung v&#xE0;o &quot;low floor, high ceiling, wide walls&quot; (d&#x1EC5; b&#x1EAF;t &#x111;&#x1EA7;u, kh&#xF4;ng gi&#x1EDB;i h&#x1EA1;n, nhi&#x1EC1;u h&#x1B0;&#x1EDB;ng &#x111;i).</td>
<td><strong>Bridging blocks to text/real-world coding</strong>: D&#x1EA1;y l&#x1EAD;p tr&#xEC;nh nh&#x1B0; m&#x1ED9;t k&#x1EF9; n&#x103;ng th&#x1EF1;c t&#x1EBF;, chuy&#x1EC3;n ti&#x1EBF;p m&#x1B0;&#x1EE3;t m&#xE0; sang code text (JS/TS), k&#x1EBF;t n&#x1ED1;i v&#x1EDB;i ph&#x1EA7;n c&#x1EE9;ng v&#xE0; &#x1EE9;ng d&#x1EE5;ng th&#x1EF1;c t&#x1EBF;.</td>
<td><strong>C&#xF4;ng c&#x1EE5; linh ho&#x1EA1;t (library)</strong>: Kh&#xF4;ng ph&#x1EA3;i m&#xF4;i tr&#x1B0;&#x1EDD;ng ho&#xE0;n ch&#x1EC9;nh, m&#xE0; l&#xE0; &quot;engine&quot; &#x111;&#x1EC3; x&#xE2;y d&#x1EF1;ng editor block-based t&#xF9;y ch&#x1EC9;nh cho b&#x1EA5;t k&#x1EF3; m&#x1EE5;c &#x111;&#xED;ch n&#xE0;o (app, game, hardware...). T&#x1EAD;p trung v&#xE0;o t&#xED;nh <strong>modular</strong> v&#xE0; <strong>multi-language generation</strong>.</td>
</tr>
<tr>
<td><strong>4P c&#x1EE7;a Creative Learning</strong> (Projects, Passion, Peers, Play)</td>
<td>R&#x1EA5;t m&#x1EA1;nh: Khuy&#x1EBF;n kh&#xED;ch <strong>tinkering</strong> (th&#x1EED; nghi&#x1EC7;m ch&#x1A1;i &#x111;&#xF9;a), <strong>personalization</strong> (d&#x1EF1; &#xE1;n c&#xE1; nh&#xE2;n), <strong>sharing/remixing</strong> c&#x1ED9;ng &#x111;&#x1ED3;ng l&#x1EDB;n, <strong>play</strong> l&#xE0; trung t&#xE2;m.</td>
<td>&#xCD;t nh&#x1EA5;n m&#x1EA1;nh &quot;play&quot; thu&#x1EA7;n t&#xFA;y, thay v&#xE0;o &#x111;&#xF3; l&#xE0; <strong>structured creativity</strong> (s&#xE1;ng t&#x1EA1;o c&#xF3; c&#x1EA5;u tr&#xFA;c, h&#x1B0;&#x1EDB;ng &#x111;&#x1EBF;n m&#x1EE5;c ti&#xEA;u c&#x1EE5; th&#x1EC3; nh&#x1B0; l&#xE0;m game ho&#x1EB7;c &#x111;i&#x1EC1;u khi&#x1EC3;n thi&#x1EBF;t b&#x1ECB;).</td>
<td>Kh&#xF4;ng c&#xF3; tri&#x1EBF;t l&#xFD; gi&#xE1;o d&#x1EE5;c ri&#xEA;ng &#x2014; ch&#x1EC9; l&#xE0; c&#xF4;ng c&#x1EE5; k&#x1EF9; thu&#x1EAD;t, tri&#x1EBF;t l&#xFD; ph&#x1EE5; thu&#x1ED9;c v&#xE0;o ng&#x1B0;&#x1EDD;i d&#xF9;ng n&#xF3; (v&#xED; d&#x1EE5;: Scratch d&#xF9;ng n&#xF3; &#x111;&#x1EC3; creative, MakeCode d&#xF9;ng &#x111;&#x1EC3; practical).</td>
</tr>
<tr>
<td><strong>M&#x1EE5;c ti&#xEA;u ch&#xED;nh</strong></td>
<td>Khuy&#x1EBF;n kh&#xED;ch <strong>s&#xE1;ng t&#x1EA1;o</strong>, <strong>k&#x1EC3; chuy&#x1EC7;n</strong>, <strong>ngh&#x1EC7; thu&#x1EAD;t + code</strong>, ph&#xE1;t tri&#x1EC3;n computational thinking qua d&#x1EF1; &#xE1;n m&#x1EDF; (stories, animations, games &#x111;a d&#x1EA1;ng).</td>
<td>T&#x1EAD;p trung <strong>game development</strong> (Arcade) ho&#x1EB7;c <strong>physical computing/hardware</strong> (micro:bit, Adafruit...), d&#x1EA1;y <strong>problem-solving</strong> th&#x1EF1;c t&#x1EBF;, d&#x1EC5; chuy&#x1EC3;n sang l&#x1EAD;p tr&#xEC;nh chuy&#xEA;n nghi&#x1EC7;p.</td>
<td>Cung c&#x1EA5;p n&#x1EC1;n t&#x1EA3;ng &#x111;&#x1EC3; <strong>t&#xF9;y ch&#x1EC9;nh cao</strong> cho c&#xE1;c domain c&#x1EE5; th&#x1EC3; (puzzle, education, enterprise, robotics...), sinh code ra nhi&#x1EC1;u ng&#xF4;n ng&#x1EEF; (JS, Python, Lua...).</td>
</tr>
<tr>
<td><strong>T&#x1EA1;i sao s&#x1EA3;n ph&#x1EA9;m kh&#xE1;c nhau?</strong></td>
<td>Scratch l&#xE0; m&#xF4;i tr&#x1B0;&#x1EDD;ng <strong>ho&#xE0;n ch&#x1EC9;nh</strong>, c&#x1ED9;ng &#x111;&#x1ED3;ng-driven, &#x1B0;u ti&#xEA;n <strong>t&#x1EF1; do s&#xE1;ng t&#x1EA1;o</strong> &#x2192; d&#x1EAB;n &#x111;&#x1EBF;n h&#xE0;ng tri&#x1EC7;u d&#x1EF1; &#xE1;n &#x111;a d&#x1EA1;ng (kh&#xF4;ng ch&#x1EC9; game).</td>
<td>MakeCode Arcade l&#xE0; <strong>domain-specific</strong> (game retro), v&#x1EDB;i blocks chuy&#xEA;n bi&#x1EC7;t (sprites, overlap, tilemap), simulator m&#x1EA1;nh, d&#x1EC5; deploy &#x2192; s&#x1EA3;n ph&#x1EA9;m t&#x1EAD;p trung, polished cho game-making.</td>
<td>Blockly ch&#x1EC9; l&#xE0; <strong>th&#x1B0; vi&#x1EC7;n</strong> &#x2192; kh&#xF4;ng c&#xF3; s&#x1EA3;n ph&#x1EA9;m &quot;s&#x1EB5;n&quot;, n&#xEA;n khi d&#xF9;ng &#x111;&#x1EC3; x&#xE2;y Scratch &#x2192; creative &amp; open; d&#xF9;ng cho MakeCode &#x2192; structured &amp; hardware-oriented.</td>
</tr>
<tr>
<td><strong>S&#x1ED1; l&#x1B0;&#x1EE3;ng blocks &amp; complexity</strong></td>
<td>&#xCD;t blocks h&#x1A1;n, <strong>versatile</strong> (&#xED;t nh&#x1B0;ng linh ho&#x1EA1;t, khuy&#x1EBF;n kh&#xED;ch combine &#x111;&#x1EC3; gi&#x1EA3;i quy&#x1EBF;t v&#x1EA5;n &#x111;&#x1EC1;).</td>
<td>Nhi&#x1EC1;u blocks chuy&#xEA;n bi&#x1EC7;t h&#x1A1;n, ti&#x1EC7;n l&#x1EE3;i nh&#x1B0;ng c&#xF3; th&#x1EC3; l&#xE0;m ng&#x1B0;&#x1EDD;i h&#x1ECD;c &quot;search&quot; thay v&#xEC; &quot;think&quot;.</td>
<td>T&#xF9;y ng&#x1B0;&#x1EDD;i implement &#x2014; c&#xF3; th&#x1EC3; &#xED;t (demo &#x111;&#x1A1;n gi&#x1EA3;n) ho&#x1EB7;c nhi&#x1EC1;u (nh&#x1B0; MakeCode).</td>
</tr>
<tr>
<td><strong>Chuy&#x1EC3;n ti&#x1EBF;p sang text code</strong></td>
<td>Kh&#xF4;ng h&#x1ED7; tr&#x1EE3; tr&#x1EF1;c ti&#x1EBF;p (c&#xF3; extension nh&#x1B0;ng kh&#xF4;ng m&#x1B0;&#x1EE3;t).</td>
<td>R&#x1EA5;t m&#x1EA1;nh: Flip gi&#x1EEF;a blocks &#x2194; JavaScript ngay l&#x1EAD;p t&#x1EE9;c &#x2192; c&#x1EA7;u n&#x1ED1;i t&#x1ED1;t cho h&#x1ECD;c sinh l&#x1EDB;n h&#x1A1;n.</td>
<td>H&#x1ED7; tr&#x1EE3; generator &#x111;a ng&#xF4;n ng&#x1EEF; &#x2192; t&#xF9;y target (c&#xF3; th&#x1EC3; r&#x1EA5;t t&#x1ED1;t ho&#x1EB7;c c&#x1A1; b&#x1EA3;n).</td>
</tr>
<tr>
<td><strong>C&#x1ED9;ng &#x111;&#x1ED3;ng &amp; chia s&#x1EBB;</strong></td>
<td>C&#x1EF1;c m&#x1EA1;nh (scratch.mit.edu), remix l&#xE0; v&#x103;n h&#xF3;a c&#x1ED1;t l&#xF5;i.</td>
<td>C&#xF3; c&#x1ED9;ng &#x111;&#x1ED3;ng, nh&#x1B0;ng nh&#x1ECF; h&#x1A1;n; t&#x1EAD;p trung v&#xE0;o gallery projects/target-specific.</td>
<td>Kh&#xF4;ng c&#xF3; c&#x1ED9;ng &#x111;&#x1ED3;ng ri&#xEA;ng &#x2014; ph&#x1EE5; thu&#x1ED9;c v&#xE0;o s&#x1EA3;n ph&#x1EA9;m build tr&#xEA;n n&#xF3;.</td>
</tr>
</tbody>
</table><!--kg-card-end: html--><h3 id="t%C3%B3m-t%E1%BA%AFt-s%E1%BB%B1-kh%C3%A1c-bi%E1%BB%87t-c%E1%BB%91t-l%C3%B5i-khi%E1%BA%BFn-s%E1%BA%A3n-ph%E1%BA%A9m-ra-kh%C3%A1c-nhau-d%C3%B9-chung-g%E1%BB%91c-blockly">T&#xF3;m t&#x1EAF;t s&#x1EF1; kh&#xE1;c bi&#x1EC7;t c&#x1ED1;t l&#xF5;i khi&#x1EBF;n s&#x1EA3;n ph&#x1EA9;m &quot;ra kh&#xE1;c nhau&quot; d&#xF9; chung g&#x1ED1;c Blockly</h3><ul><li><strong>Scratch 3</strong>: &#x1AF;u ti&#xEA;n <strong>s&#xE1;ng t&#x1EA1;o t&#x1EF1; do, ch&#x1A1;i &#x111;&#xF9;a, c&#x1ED9;ng &#x111;&#x1ED3;ng</strong> &#x2192; gi&#x1ED1;ng nh&#x1B0; &quot;LEGO m&#x1EDF;&quot; cho k&#x1EC3; chuy&#x1EC7;n + ngh&#x1EC7; thu&#x1EAD;t + code. K&#x1EBF;t qu&#x1EA3;: H&#xE0;ng tri&#x1EC7;u d&#x1EF1; &#xE1;n &#x111;a d&#x1EA1;ng, &#xED;t &quot;c&#x1ED1; &#x111;&#x1ECB;nh&quot; m&#x1ED9;t domain.</li><li><strong>PXT/MakeCode Arcade</strong>: &#x1AF;u ti&#xEA;n <strong>t&#x1EAD;p trung domain (game/hardware)</strong> + <strong>chuy&#x1EC3;n ti&#x1EBF;p th&#x1EF1;c t&#x1EBF; sang code text</strong> &#x2192; gi&#x1ED1;ng nh&#x1B0; &quot;LEGO chuy&#xEA;n game&quot; v&#x1EDB;i h&#x1B0;&#x1EDB;ng d&#x1EAB;n r&#xF5; r&#xE0;ng, blocks ti&#x1EC7;n l&#x1EE3;i &#x2192; s&#x1EA3;n ph&#x1EA9;m polished, d&#x1EC5; &#x111;&#x1EA1;t k&#x1EBF;t qu&#x1EA3; &quot;wow&quot; nhanh (game ch&#x1EA1;y m&#x1B0;&#x1EE3;t tr&#xEA;n web/handheld).</li><li><strong>Blockly</strong>: Ch&#x1EC9; l&#xE0; <strong>c&#xF4;ng c&#x1EE5; n&#x1EC1;n t&#x1EA3;ng</strong> (engine) &#x2192; tri&#x1EBF;t l&#xFD; trung l&#x1EAD;p, n&#xEA;n s&#x1EA3;n ph&#x1EA9;m cu&#x1ED1;i c&#xF9;ng ph&#x1EE5; thu&#x1ED9;c ho&#xE0;n to&#xE0;n v&#xE0;o <strong>ng&#x1B0;&#x1EDD;i build</strong> (MIT build Scratch &#x2192; creative; Microsoft build MakeCode &#x2192; practical/hardware/game-focused).</li></ul><p>N&#xF3;i c&#xE1;ch kh&#xE1;c: <strong>c&#xF9;ng d&#xF9;ng &quot;&#x111;&#x1ED9;ng c&#x1A1; Blockly&quot;</strong>, nh&#x1B0;ng MIT &quot;l&#xE1;i&quot; theo h&#x1B0;&#x1EDB;ng <strong>ngh&#x1EC7; thu&#x1EAD;t + t&#x1EF1; do s&#xE1;ng t&#x1EA1;o</strong>, Microsoft &quot;l&#xE1;i&quot; theo h&#x1B0;&#x1EDB;ng <strong>&#x1EE9;ng d&#x1EE5;ng th&#x1EF1;c t&#x1EBF; + game/hardware</strong>, n&#xEA;n s&#x1EA3;n ph&#x1EA9;m m&#x1EDB;i kh&#xE1;c nhau r&#xF5; r&#x1EC7;t.</p><p>N&#x1EBF;u b&#x1EA1;n th&#xED;ch Arcade v&#xEC; c&#x1EA3;m gi&#xE1;c &quot;game m&#x1B0;&#x1EE3;t, blocks &#x111;&#x1EB9;p, simulator m&#x1EA1;nh&quot; th&#xEC; &#x111;&#xF3; ch&#xED;nh l&#xE0; k&#x1EBF;t qu&#x1EA3; c&#x1EE7;a tri&#x1EBF;t l&#xFD; <strong>focused + practical</strong> c&#x1EE7;a MakeCode. C&#xF2;n Scratch cho c&#x1EA3;m gi&#xE1;c &quot;t&#x1EF1; do tha h&#x1ED3; remix, k&#x1EC3; chuy&#x1EC7;n&quot; nh&#x1EDD; tri&#x1EBF;t l&#xFD; constructionist m&#x1EA1;nh m&#x1EBD; h&#x1A1;n.</p><p>B&#x1EA1;n th&#x1EA5;y tri&#x1EBF;t l&#xFD; n&#xE0;o g&#x1EA7;n v&#x1EDB;i m&#x1EE5;c ti&#xEA;u d&#x1EF1; &#xE1;n c&#x1EE7;a m&#xEC;nh h&#x1A1;n (s&#xE1;ng t&#x1EA1;o m&#x1EDF; hay game/hardware c&#x1EE5; th&#x1EC3;)? &#xA0;&#x1F60A;</p>]]></content:encoded></item><item><title><![CDATA[Cài đặt OpenClaw trên Linux VPS — Hướng dẫn toàn tập]]></title><description><![CDATA[Thiết lập OpenClaw để Bot Zalo AI chạy 24/7, truy cập từ xa qua domain riêng, tự khởi động khi server restart
]]></description><link>https://makexyz.fun/install-openclaw-on-linux-server/</link><guid isPermaLink="false">69c0afb444a68a6ca0047d88</guid><category><![CDATA[AI]]></category><dc:creator><![CDATA[Tony Phạm]]></dc:creator><pubDate>Mon, 23 Mar 2026 03:13:59 GMT</pubDate><content:encoded><![CDATA[<blockquote><strong>D&#xE0;nh cho:</strong> Ubuntu 22.04 / Debian 12 VPS<br><strong>K&#x1EBF;t qu&#x1EA3;:</strong> Bot Zalo AI ch&#x1EA1;y 24/7, truy c&#x1EAD;p t&#x1EEB; xa qua domain ri&#xEA;ng, t&#x1EF1; kh&#x1EDF;i &#x111;&#x1ED9;ng khi server restart</blockquote><hr><h2 id="t%E1%BB%95ng-quan-ki%E1%BA%BFn-tr%C3%BAc">T&#x1ED5;ng quan ki&#x1EBF;n tr&#xFA;c</h2><pre><code>Ng&#x1B0;&#x1EDD;i d&#xF9;ng Zalo
      &#x2193; nh&#x1EAF;n tin
Zalo Bot API
      &#x2193; polling (bot t&#x1EF1; l&#x1EA5;y tin)
OpenClaw Gateway (VPS)
      &#x2193;
Gemini / Claude / GPT (AI model)
      &#x2193; ph&#x1EA3;n h&#x1ED3;i
Zalo Bot API &#x2192; ng&#x1B0;&#x1EDD;i d&#xF9;ng

Dashboard (b&#x1EA1;n qu&#x1EA3;n l&#xFD;)
      &#x2193; truy c&#x1EAD;p qua browser
Cloudflare Tunnel &#x2192; yourdomain.com &#x2192; OpenClaw
</code></pre><p><strong>Y&#xEA;u c&#x1EA7;u:</strong></p><ul><li>Ubuntu 22.04 ho&#x1EB7;c Debian 12</li><li>RAM t&#x1ED1;i thi&#x1EC3;u 1GB (khuy&#x1EBF;n ngh&#x1ECB; 2GB+)</li><li>T&#xE0;i kho&#x1EA3;n Cloudflare (mi&#x1EC5;n ph&#xED;)</li><li>T&#xEA;n mi&#x1EC1;n &#x111;&#xE3; tr&#x1ECF; v&#x1EC1; Cloudflare</li><li>T&#xE0;i kho&#x1EA3;n Zalo Bot Platform</li></ul><hr><h2 id="ph%E1%BA%A7n-1-%E2%80%94-c%C3%A0i-%C4%91%E1%BA%B7t-m%C3%B4i-tr%C6%B0%E1%BB%9Dng">Ph&#x1EA7;n 1 &#x2014; C&#xE0;i &#x111;&#x1EB7;t m&#xF4;i tr&#x1B0;&#x1EDD;ng</h2><h3 id="11-c%E1%BA%ADp-nh%E1%BA%ADt-h%E1%BB%87-th%E1%BB%91ng">1.1 C&#x1EAD;p nh&#x1EAD;t h&#x1EC7; th&#x1ED1;ng</h3><pre><code class="language-bash">sudo apt update &amp;&amp; sudo apt upgrade -y
</code></pre><h3 id="12-c%C3%A0i-nodejs-20">1.2 C&#xE0;i Node.js 20+</h3><pre><code class="language-bash">curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
node --version  # ph&#x1EA3;i l&#xE0; v20+
</code></pre><h3 id="13-c%C3%A0i-pnpm">1.3 C&#xE0;i pnpm</h3><pre><code class="language-bash">curl -fsSL https://get.pnpm.io/install.sh | sh -
source ~/.bashrc
pnpm --version
</code></pre><h3 id="14-c%C3%A0i-docker-cho-cloudflare-tunnel">1.4 C&#xE0;i Docker (cho Cloudflare Tunnel)</h3><pre><code class="language-bash">curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
newgrp docker
</code></pre><hr><h2 id="ph%E1%BA%A7n-2-%E2%80%94-c%C3%A0i-%C4%91%E1%BA%B7t-openclaw">Ph&#x1EA7;n 2 &#x2014; C&#xE0;i &#x111;&#x1EB7;t OpenClaw</h2><h3 id="21-c%C3%A0i-openclaw">2.1 C&#xE0;i OpenClaw</h3><pre><code class="language-bash">pnpm add -g openclaw@latest
openclaw --version
</code></pre><h3 id="22-kh%E1%BB%9Fi-t%E1%BA%A1o-c%E1%BA%A5u-h%C3%ACnh">2.2 Kh&#x1EDF;i t&#x1EA1;o c&#x1EA5;u h&#xEC;nh</h3><pre><code class="language-bash">openclaw onboard
</code></pre><p>Wizard s&#x1EBD; h&#x1ECF;i:</p><ul><li><strong>AI model:</strong> Ch&#x1ECD;n Google Gemini &#x2192; nh&#x1EAD;p API key (l&#x1EA5;y t&#x1EEB; <a href="https://aistudio.google.com/">aistudio.google.com</a>)</li><li><strong>Workspace:</strong> Gi&#x1EEF; m&#x1EB7;c &#x111;&#x1ECB;nh <code>~/.openclaw/workspace</code></li><li><strong>Gateway mode:</strong> Local</li></ul><blockquote><strong>L&#x1EA5;y Google API key mi&#x1EC5;n ph&#xED;:</strong> V&#xE0;o <a href="https://aistudio.google.com/">aistudio.google.com</a> &#x2192; Get API Key &#x2192; Copy</blockquote><hr><h2 id="ph%E1%BA%A7n-3-%E2%80%94-thi%E1%BA%BFt-l%E1%BA%ADp-cloudflare-tunnel">Ph&#x1EA7;n 3 &#x2014; Thi&#x1EBF;t l&#x1EAD;p Cloudflare Tunnel</h2><h3 id="31-t%E1%BA%A1o-tunnel-tr%C3%AAn-cloudflare-dashboard">3.1 T&#x1EA1;o tunnel tr&#xEA;n Cloudflare Dashboard</h3><ol><li>V&#xE0;o <a href="https://one.dash.cloudflare.com/">one.dash.cloudflare.com</a></li><li>Ch&#x1ECD;n <strong>Networks &#x2192; Tunnels &#x2192; Create a tunnel</strong></li><li>&#x110;&#x1EB7;t t&#xEA;n tunnel (VD: <code>my-openclaw</code>)</li><li>Ch&#x1ECD;n <strong>Docker</strong> &#x111;&#x1EC3; l&#x1EA5;y token</li></ol><h3 id="32-ch%E1%BA%A1y-cloudflare-tunnel-b%E1%BA%B1ng-docker">3.2 Ch&#x1EA1;y Cloudflare Tunnel b&#x1EB1;ng Docker</h3><p>T&#x1EA1;o file <code>~/cloudflared/docker-compose.yml</code>:</p><pre><code class="language-bash">mkdir -p ~/cloudflared
cat &gt; ~/cloudflared/docker-compose.yml &lt;&lt; &apos;EOF&apos;
version: &quot;3&quot;
services:
  cloudflared:
    image: cloudflare/cloudflared:latest
    restart: unless-stopped
    command: tunnel --no-autoupdate run --token &lt;TUNNEL_TOKEN&gt;
    network_mode: host
EOF
</code></pre><blockquote>Thay <code>&lt;TUNNEL_TOKEN&gt;</code> b&#x1EB1;ng token l&#x1EA5;y t&#x1EEB; b&#x1B0;&#x1EDB;c 3.1</blockquote><pre><code class="language-bash">cd ~/cloudflared
docker compose up -d
docker compose logs  # ki&#x1EC3;m tra k&#x1EBF;t n&#x1ED1;i
</code></pre><h3 id="33-c%E1%BA%A5u-h%C3%ACnh-route-tr%C3%AAn-cloudflare-dashboard">3.3 C&#x1EA5;u h&#xEC;nh route tr&#xEA;n Cloudflare Dashboard</h3><ol><li>V&#xE0;o tunnel v&#x1EEB;a t&#x1EA1;o &#x2192; <strong>Public Hostname</strong></li><li>Th&#xEA;m route:</li></ol><ul><li><strong>Subdomain:</strong> <code>claw</code></li><li><strong>Domain:</strong> <code>yourdomain.com</code></li><li><strong>Service:</strong> <code>http://localhost:18789</code></li></ul><hr><h2 id="ph%E1%BA%A7n-4-%E2%80%94-c%E1%BA%A5u-h%C3%ACnh-openclaw">Ph&#x1EA7;n 4 &#x2014; C&#x1EA5;u h&#xEC;nh OpenClaw</h2><h3 id="41-c%E1%BA%A5u-h%C3%ACnh-gateway">4.1 C&#x1EA5;u h&#xEC;nh gateway</h3><pre><code class="language-bash"># Cho ph&#xE9;p k&#x1EBF;t n&#x1ED1;i t&#x1EEB; t&#x1EA5;t c&#x1EA3; interfaces (c&#x1EA7;n cho Cloudflare Tunnel tr&#xEA;n Linux)
openclaw config set gateway.bind lan

# Trust Cloudflare proxy
openclaw config set gateway.trustedProxies &apos;[&quot;127.0.0.1&quot;]&apos;

# Cho ph&#xE9;p truy c&#x1EAD;p t&#x1EEB; domain c&#x1EE7;a b&#x1EA1;n
openclaw config set gateway.controlUi.allowedOrigins &apos;[&quot;https://claw.yourdomain.com&quot;]&apos;

# &#x110;&#x1EB7;t password truy c&#x1EAD;p dashboard
openclaw config set gateway.auth.password &quot;mat-khau-cua-ban&quot;
</code></pre><h3 id="42-l%E1%BA%A5y-tokenized-url-%C4%91%E1%BB%83-truy-c%E1%BA%ADp-l%E1%BA%A7n-%C4%91%E1%BA%A7u">4.2 L&#x1EA5;y tokenized URL &#x111;&#x1EC3; truy c&#x1EAD;p l&#x1EA7;n &#x111;&#x1EA7;u</h3><pre><code class="language-bash">openclaw dashboard --no-open
</code></pre><p>Copy URL d&#x1EA1;ng <code>http://127.0.0.1:18789/#token=...</code> &#x2192; &#x111;&#x1ED5;i th&#xE0;nh <code>https://claw.yourdomain.com/#token=...</code></p><hr><h2 id="ph%E1%BA%A7n-5-%E2%80%94-thi%E1%BA%BFt-l%E1%BA%ADp-zalo-bot">Ph&#x1EA7;n 5 &#x2014; Thi&#x1EBF;t l&#x1EAD;p Zalo Bot</h2><h3 id="51-t%E1%BA%A1o-bot-tr%C3%AAn-zalo-platform">5.1 T&#x1EA1;o Bot tr&#xEA;n Zalo Platform</h3><ol><li>V&#xE0;o <a href="https://bot.zaloplatforms.com/">bot.zaloplatforms.com</a></li><li>&#x110;&#x103;ng nh&#x1EAD;p b&#x1EB1;ng t&#xE0;i kho&#x1EA3;n Zalo</li><li>T&#x1EA1;o bot m&#x1EDB;i &#x2192; &#x111;&#x1EB7;t t&#xEA;n</li><li>Copy <strong>Bot Token</strong> (d&#x1EA1;ng <code>123456789:abc-xyz-token</code>)</li></ol><h3 id="52-c%E1%BA%A5u-h%C3%ACnh-zalo-channel-trong-openclaw">5.2 C&#x1EA5;u h&#xEC;nh Zalo channel trong OpenClaw</h3><pre><code class="language-bash">openclaw configure
</code></pre><p>Ch&#x1ECD;n:</p><ul><li><strong>Channels &#x2192; Zalo (Bot API)</strong></li><li>Nh&#x1EAD;p Bot Token</li><li><strong>Use webhook mode:</strong> <code>No</code> (d&#xF9;ng polling &#x2014; &#x1ED5;n &#x111;&#x1ECB;nh h&#x1A1;n)</li><li><strong>DM Policy:</strong> <code>Open</code> (cho ph&#xE9;p m&#x1ECD;i ng&#x1B0;&#x1EDD;i nh&#x1EAF;n tin)</li></ul><h3 id="53-test-bot">5.3 Test bot</h3><p>M&#x1EDF; Zalo &#x2192; t&#xEC;m bot theo t&#xEA;n &#x2192; nh&#x1EAF;n &quot;xin ch&#xE0;o&quot;</p><p>Bot s&#x1EBD; ph&#x1EA3;n h&#x1ED3;i trong v&#xF2;ng 1-3 gi&#xE2;y.</p><hr><h2 id="ph%E1%BA%A7n-6-%E2%80%94-auto-start-b%E1%BA%B1ng-systemd">Ph&#x1EA7;n 6 &#x2014; Auto-start b&#x1EB1;ng systemd</h2><p>Tr&#xEA;n Linux kh&#xF4;ng c&#xF3; <code>openclaw gateway install</code> nh&#x1B0; macOS, c&#x1EA7;n t&#x1EA1;o systemd service th&#x1EE7; c&#xF4;ng.</p><h3 id="61-t%C3%ACm-%C4%91%C6%B0%E1%BB%9Dng-d%E1%BA%ABn-openclaw">6.1 T&#xEC;m &#x111;&#x1B0;&#x1EDD;ng d&#x1EAB;n openclaw</h3><pre><code class="language-bash">which openclaw
# VD: /root/.local/share/pnpm/openclaw
</code></pre><h3 id="62-t%E1%BA%A1o-systemd-service">6.2 T&#x1EA1;o systemd service</h3><pre><code class="language-bash">sudo tee /etc/systemd/system/openclaw.service &lt;&lt; EOF
[Unit]
Description=OpenClaw Gateway
After=network.target
Wants=network-online.target

[Service]
Type=simple
User=$USER
WorkingDirectory=$HOME
ExecStart=$(which openclaw) gateway
Restart=always
RestartSec=10
Environment=HOME=$HOME
Environment=PATH=/usr/local/bin:/usr/bin:/bin:$HOME/.local/share/pnpm

[Install]
WantedBy=multi-user.target
EOF
</code></pre><h3 id="63-enable-v%C3%A0-start-service">6.3 Enable v&#xE0; start service</h3><pre><code class="language-bash">sudo systemctl daemon-reload
sudo systemctl enable openclaw
sudo systemctl start openclaw
sudo systemctl status openclaw
</code></pre><h3 id="64-xem-log">6.4 Xem log</h3><pre><code class="language-bash">sudo journalctl -u openclaw -f
</code></pre><p><strong>C&#xE1;c l&#x1EC7;nh qu&#x1EA3;n l&#xFD;:</strong></p><!--kg-card-begin: html--><table>
<thead>
<tr>
<th>L&#x1EC7;nh</th>
<th>T&#xE1;c d&#x1EE5;ng</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>sudo systemctl start openclaw</code></td>
<td>Start gateway</td>
</tr>
<tr>
<td><code>sudo systemctl stop openclaw</code></td>
<td>Stop gateway</td>
</tr>
<tr>
<td><code>sudo systemctl restart openclaw</code></td>
<td>Restart gateway</td>
</tr>
<tr>
<td><code>sudo systemctl status openclaw</code></td>
<td>Xem tr&#x1EA1;ng th&#xE1;i</td>
</tr>
<tr>
<td><code>sudo journalctl -u openclaw -f</code></td>
<td>Xem log realtime</td>
</tr>
</tbody>
</table><!--kg-card-end: html--><hr><h2 id="ph%E1%BA%A7n-7-%E2%80%94-truy-c%E1%BA%ADp-dashboard-t%E1%BB%AB-xa">Ph&#x1EA7;n 7 &#x2014; Truy c&#x1EAD;p Dashboard t&#x1EEB; xa</h2><h3 id="71-truy-c%E1%BA%ADp-l%E1%BA%A7n-%C4%91%E1%BA%A7u">7.1 Truy c&#x1EAD;p l&#x1EA7;n &#x111;&#x1EA7;u</h3><p>D&#xF9;ng tokenized URL:</p><pre><code>https://claw.yourdomain.com/#token=&lt;gateway-token&gt;
</code></pre><p>L&#x1EA5;y token:</p><pre><code class="language-bash">openclaw dashboard --no-open
</code></pre><h3 id="72-truy-c%E1%BA%ADp-th%C6%B0%E1%BB%9Dng-xuy%C3%AAn">7.2 Truy c&#x1EAD;p th&#x1B0;&#x1EDD;ng xuy&#xEA;n</h3><p>Sau khi v&#xE0;o b&#x1EB1;ng tokenized URL l&#x1EA7;n &#x111;&#x1EA7;u, t&#x1EEB; l&#x1EA7;n sau ch&#x1EC9; c&#x1EA7;n v&#xE0;o <code>https://claw.yourdomain.com</code> v&#xE0; nh&#x1EAD;p password.</p><h3 id="73-chia-s%E1%BA%BB-v%E1%BB%9Bi-ng%C6%B0%E1%BB%9Di-kh%C3%A1c">7.3 Chia s&#x1EBB; v&#x1EDB;i ng&#x1B0;&#x1EDD;i kh&#xE1;c</h3><p>Share tokenized URL cho ng&#x1B0;&#x1EDD;i tin t&#x1B0;&#x1EDF;ng &#x2014; h&#x1ECD; v&#xE0;o th&#x1EB3;ng kh&#xF4;ng c&#x1EA7;n password.</p><p>&#x110;&#x1EC3; revoke quy&#x1EC1;n truy c&#x1EAD;p:</p><pre><code class="language-bash">openclaw config set gateway.auth.token &quot;$(openssl rand -hex 32)&quot;
sudo systemctl restart openclaw
</code></pre><hr><h2 id="ph%E1%BA%A7n-8-%E2%80%94-b%E1%BA%A3o-m%E1%BA%ADt-c%C6%A1-b%E1%BA%A3n">Ph&#x1EA7;n 8 &#x2014; B&#x1EA3;o m&#x1EAD;t c&#x1A1; b&#x1EA3;n</h2><h3 id="81-firewall-%E2%80%94-ch%E1%BB%89-cho-ph%C3%A9p-cloudflare">8.1 Firewall &#x2014; ch&#x1EC9; cho ph&#xE9;p Cloudflare</h3><pre><code class="language-bash">sudo ufw enable
sudo ufw allow ssh
sudo ufw allow 18789/tcp  # ch&#x1EC9; c&#x1EA7;n n&#x1EBF;u kh&#xF4;ng d&#xF9;ng Cloudflare Tunnel
</code></pre><p>N&#x1EBF;u d&#xF9;ng Cloudflare Tunnel, <strong>kh&#xF4;ng c&#x1EA7;n</strong> m&#x1EDF; port 18789 ra ngo&#xE0;i &#x2014; tunnel t&#x1EF1; k&#x1EBF;t n&#x1ED1;i t&#x1EEB; trong ra.</p><h3 id="82-%C4%91%E1%BB%95i-password-%C4%91%E1%BB%8Bnh-k%E1%BB%B3">8.2 &#x110;&#x1ED5;i password &#x111;&#x1ECB;nh k&#x1EF3;</h3><pre><code class="language-bash">openclaw config set gateway.auth.password &quot;password-moi&quot;
sudo systemctl restart openclaw
</code></pre><h3 id="83-kh%C3%B4ng-commit-token-v%C3%A0o-git">8.3 Kh&#xF4;ng commit token v&#xE0;o git</h3><p>File config n&#x1EB1;m t&#x1EA1;i <code>~/.openclaw/openclaw.json</code> &#x2014; kh&#xF4;ng bao gi&#x1EDD; commit file n&#xE0;y.</p><hr><h2 id="ph%E1%BA%A7n-9-%E2%80%94-troubleshoot-th%C6%B0%E1%BB%9Dng-g%E1%BA%B7p">Ph&#x1EA7;n 9 &#x2014; Troubleshoot th&#x1B0;&#x1EDD;ng g&#x1EB7;p</h2><h3 id="service-kh%C3%B4ng-start">Service kh&#xF4;ng start</h3><pre><code class="language-bash">sudo journalctl -u openclaw -n 50
openclaw doctor --fix
</code></pre><h3 id="zalo-kh%C3%B4ng-nh%E1%BA%ADng%E1%BB%ADi-tin">Zalo kh&#xF4;ng nh&#x1EAD;n/g&#x1EED;i tin</h3><pre><code class="language-bash">openclaw status
openclaw channels list
</code></pre><h3 id="cloudflare-502-bad-gateway">Cloudflare 502 Bad Gateway</h3><pre><code class="language-bash"># Ki&#x1EC3;m tra gateway &#x111;ang ch&#x1EA1;y
sudo systemctl status openclaw

# Ki&#x1EC3;m tra bind
openclaw config get gateway.bind
# Ph&#x1EA3;i l&#xE0;: lan

# Ki&#x1EC3;m tra Docker tunnel
docker ps | grep cloudflared
docker logs cloudflared
</code></pre><h3 id="dashboard-y%C3%AAu-c%E1%BA%A7u-pairing-li%C3%AAn-t%E1%BB%A5c">Dashboard y&#xEA;u c&#x1EA7;u pairing li&#xEA;n t&#x1EE5;c</h3><pre><code class="language-bash">openclaw config set gateway.trustedProxies &apos;[&quot;127.0.0.1&quot;]&apos;
openclaw config set gateway.controlUi.allowedOrigins &apos;[&quot;https://claw.yourdomain.com&quot;]&apos;
sudo systemctl restart openclaw
</code></pre><p>Sau &#x111;&#xF3; d&#xF9;ng tokenized URL &#x111;&#x1EC3; v&#xE0;o l&#x1EA7;n &#x111;&#x1EA7;u.</p><hr><h2 id="t%C3%B3m-t%E1%BA%AFt-c%C3%A1c-l%E1%BB%87nh-quan-tr%E1%BB%8Dng">T&#xF3;m t&#x1EAF;t c&#xE1;c l&#x1EC7;nh quan tr&#x1ECD;ng</h2><pre><code class="language-bash"># C&#xE0;i &#x111;&#x1EB7;t
pnpm add -g openclaw@latest
openclaw onboard

# C&#x1EA5;u h&#xEC;nh
openclaw config set gateway.bind lan
openclaw config set gateway.trustedProxies &apos;[&quot;127.0.0.1&quot;]&apos;
openclaw config set gateway.controlUi.allowedOrigins &apos;[&quot;https://claw.yourdomain.com&quot;]&apos;
openclaw config set gateway.auth.password &quot;password&quot;

# Zalo
openclaw configure  # ch&#x1ECD;n Channels &#x2192; Zalo

# Auto-start (systemd)
sudo systemctl enable openclaw
sudo systemctl start openclaw

# Ki&#x1EC3;m tra
openclaw status
sudo journalctl -u openclaw -f
</code></pre><hr><p><em>B&#xE0;i vi&#x1EBF;t tr&#x1B0;&#x1EDB;c: [C&#xE0;i &#x111;&#x1EB7;t OpenClaw tr&#xEA;n macOS]</em></p>]]></content:encoded></item><item><title><![CDATA[Cài đặt OpenClaw trên macOS — Hướng dẫn toàn tập]]></title><description><![CDATA[Thiết lập OpenClaw để Bot Zalo AI chạy 24/7, truy cập từ xa qua domain riêng, tự khởi động khi máy restart]]></description><link>https://makexyz.fun/install-openclaw-on-macos-server/</link><guid isPermaLink="false">69c0af1444a68a6ca0047d7b</guid><category><![CDATA[AI]]></category><dc:creator><![CDATA[Tony Phạm]]></dc:creator><pubDate>Mon, 23 Mar 2026 03:11:31 GMT</pubDate><content:encoded><![CDATA[<blockquote><strong>D&#xE0;nh cho:</strong> Mac mini / MacBook ch&#x1EA1;y macOS 13+<br><strong>K&#x1EBF;t qu&#x1EA3;:</strong> Bot Zalo AI ch&#x1EA1;y 24/7, truy c&#x1EAD;p t&#x1EEB; xa qua domain ri&#xEA;ng, t&#x1EF1; kh&#x1EDF;i &#x111;&#x1ED9;ng khi m&#xE1;y restart</blockquote><hr><h2 id="t%E1%BB%95ng-quan-ki%E1%BA%BFn-tr%C3%BAc">T&#x1ED5;ng quan ki&#x1EBF;n tr&#xFA;c</h2><pre><code>Ng&#x1B0;&#x1EDD;i d&#xF9;ng Zalo
      &#x2193; nh&#x1EAF;n tin
Zalo Bot API
      &#x2193; polling (bot t&#x1EF1; l&#x1EA5;y tin)
OpenClaw Gateway (Mac mini)
      &#x2193;
Gemini / Claude / GPT (AI model)
      &#x2193; ph&#x1EA3;n h&#x1ED3;i
Zalo Bot API &#x2192; ng&#x1B0;&#x1EDD;i d&#xF9;ng

Dashboard (b&#x1EA1;n qu&#x1EA3;n l&#xFD;)
      &#x2193; truy c&#x1EAD;p qua browser
Cloudflare Tunnel &#x2192; yourdomain.com &#x2192; OpenClaw
</code></pre><p><strong>Y&#xEA;u c&#x1EA7;u:</strong></p><ul><li>macOS 13 tr&#x1EDF; l&#xEA;n (Intel ho&#x1EB7;c Apple Silicon)</li><li>T&#xE0;i kho&#x1EA3;n Cloudflare (mi&#x1EC5;n ph&#xED;)</li><li>T&#xEA;n mi&#x1EC1;n &#x111;&#xE3; tr&#x1ECF; v&#x1EC1; Cloudflare</li><li>T&#xE0;i kho&#x1EA3;n Zalo Bot Platform</li></ul><hr><h2 id="ph%E1%BA%A7n-1-%E2%80%94-c%C3%A0i-%C4%91%E1%BA%B7t-openclaw">Ph&#x1EA7;n 1 &#x2014; C&#xE0;i &#x111;&#x1EB7;t OpenClaw</h2><h3 id="11-c%C3%A0i-pnpm-n%E1%BA%BFu-ch%C6%B0a-c%C3%B3">1.1 C&#xE0;i pnpm (n&#x1EBF;u ch&#x1B0;a c&#xF3;)</h3><pre><code class="language-bash">curl -fsSL https://get.pnpm.io/install.sh | sh -
source ~/.zshrc
</code></pre><p>Ki&#x1EC3;m tra:</p><pre><code class="language-bash">pnpm --version
</code></pre><h3 id="12-c%C3%A0i-openclaw">1.2 C&#xE0;i OpenClaw</h3><pre><code class="language-bash">pnpm add -g openclaw@latest
</code></pre><p>Ki&#x1EC3;m tra:</p><pre><code class="language-bash">openclaw --version
</code></pre><h3 id="13-kh%E1%BB%9Fi-t%E1%BA%A1o-c%E1%BA%A5u-h%C3%ACnh">1.3 Kh&#x1EDF;i t&#x1EA1;o c&#x1EA5;u h&#xEC;nh</h3><pre><code class="language-bash">openclaw onboard
</code></pre><p>Wizard s&#x1EBD; h&#x1ECF;i:</p><ul><li><strong>AI model:</strong> Ch&#x1ECD;n Google Gemini &#x2192; nh&#x1EAD;p API key (l&#x1EA5;y t&#x1EEB; <a href="https://aistudio.google.com/">aistudio.google.com</a>)</li><li><strong>Workspace:</strong> Gi&#x1EEF; m&#x1EB7;c &#x111;&#x1ECB;nh <code>~/.openclaw/workspace</code></li><li><strong>Gateway mode:</strong> Local</li></ul><blockquote><strong>L&#x1EA5;y Google API key mi&#x1EC5;n ph&#xED;:</strong> V&#xE0;o <a href="https://aistudio.google.com/">aistudio.google.com</a> &#x2192; Get API Key &#x2192; Copy</blockquote><hr><h2 id="ph%E1%BA%A7n-2-%E2%80%94-thi%E1%BA%BFt-l%E1%BA%ADp-cloudflare-tunnel">Ph&#x1EA7;n 2 &#x2014; Thi&#x1EBF;t l&#x1EAD;p Cloudflare Tunnel</h2><p>Cloudflare Tunnel cho ph&#xE9;p expose OpenClaw ra internet <strong>kh&#xF4;ng c&#x1EA7;n IP t&#x129;nh, kh&#xF4;ng c&#x1EA7;n m&#x1EDF; port router</strong>.</p><h3 id="21-t%E1%BA%A1o-tunnel-tr%C3%AAn-cloudflare-dashboard">2.1 T&#x1EA1;o tunnel tr&#xEA;n Cloudflare Dashboard</h3><ol><li>V&#xE0;o <a href="https://one.dash.cloudflare.com/">one.dash.cloudflare.com</a></li><li>Ch&#x1ECD;n <strong>Networks &#x2192; Tunnels &#x2192; Create a tunnel</strong></li><li>&#x110;&#x1EB7;t t&#xEA;n tunnel (VD: <code>my-openclaw</code>)</li><li>Ch&#x1ECD;n <strong>Docker</strong> ho&#x1EB7;c <strong>macOS</strong> &#x111;&#x1EC3; l&#x1EA5;y token</li></ol><h3 id="22-c%C3%A0i-cloudflared-b%E1%BA%B1ng-docker-khuy%E1%BA%BFn-ngh%E1%BB%8B">2.2 C&#xE0;i cloudflared b&#x1EB1;ng Docker (khuy&#x1EBF;n ngh&#x1ECB;)</h3><p>T&#x1EA1;o file <code>docker-compose.yml</code>:</p><pre><code class="language-yaml">version: &quot;3&quot;
services:
  cloudflared:
    image: cloudflare/cloudflared:latest
    restart: unless-stopped
    command: tunnel --no-autoupdate run --token &lt;TUNNEL_TOKEN&gt;
    network_mode: host
</code></pre><blockquote>Thay <code>&lt;TUNNEL_TOKEN&gt;</code> b&#x1EB1;ng token l&#x1EA5;y t&#x1EEB; b&#x1B0;&#x1EDB;c 2.1</blockquote><p>Ch&#x1EA1;y:</p><pre><code class="language-bash">docker compose up -d
</code></pre><h3 id="23-c%C3%A0i-cloudflared-native-kh%C3%B4ng-d%C3%B9ng-docker">2.3 C&#xE0;i cloudflared native (kh&#xF4;ng d&#xF9;ng Docker)</h3><pre><code class="language-bash">brew install cloudflared
cloudflared tunnel login
cloudflared tunnel create my-openclaw
cloudflared tunnel route dns my-openclaw claw.yourdomain.com
</code></pre><p>T&#x1EA1;o file <code>~/.cloudflared/config.yml</code>:</p><pre><code class="language-yaml">tunnel: &lt;TUNNEL_ID&gt;
credentials-file: ~/.cloudflared/&lt;TUNNEL_ID&gt;.json

ingress:
  - hostname: claw.yourdomain.com
    service: http://localhost:18789
  - service: http_status:404
</code></pre><p>Ch&#x1EA1;y:</p><pre><code class="language-bash">cloudflared tunnel run my-openclaw
</code></pre><h3 id="24-c%E1%BA%A5u-h%C3%ACnh-route-tr%C3%AAn-cloudflare-dashboard">2.4 C&#x1EA5;u h&#xEC;nh route tr&#xEA;n Cloudflare Dashboard</h3><ol><li>V&#xE0;o tunnel v&#x1EEB;a t&#x1EA1;o &#x2192; <strong>Public Hostname</strong></li><li>Th&#xEA;m route:</li></ol><ul><li><strong>Subdomain:</strong> <code>claw</code></li><li><strong>Domain:</strong> <code>yourdomain.com</code></li><li><strong>Service:</strong> <code>http://localhost:18789</code></li></ul><hr><h2 id="ph%E1%BA%A7n-3-%E2%80%94-c%E1%BA%A5u-h%C3%ACnh-openclaw">Ph&#x1EA7;n 3 &#x2014; C&#x1EA5;u h&#xEC;nh OpenClaw</h2><h3 id="31-c%E1%BA%A5u-h%C3%ACnh-gateway">3.1 C&#x1EA5;u h&#xEC;nh gateway</h3><pre><code class="language-bash"># Cho ph&#xE9;p k&#x1EBF;t n&#x1ED1;i t&#x1EEB; m&#x1EA1;ng LAN (c&#x1EA7;n thi&#x1EBF;t cho Cloudflare Tunnel)
openclaw config set gateway.bind lan

# Trust Cloudflare proxy
openclaw config set gateway.trustedProxies &apos;[&quot;127.0.0.1&quot;]&apos;

# Cho ph&#xE9;p truy c&#x1EAD;p t&#x1EEB; domain c&#x1EE7;a b&#x1EA1;n
openclaw config set gateway.controlUi.allowedOrigins &apos;[&quot;https://claw.yourdomain.com&quot;]&apos;

# &#x110;&#x1EB7;t password truy c&#x1EAD;p dashboard
openclaw config set gateway.auth.password &quot;mat-khau-cua-ban&quot;
</code></pre><h3 id="32-l%E1%BA%A5y-tokenized-url-%C4%91%E1%BB%83-truy-c%E1%BA%ADp-l%E1%BA%A7n-%C4%91%E1%BA%A7u">3.2 L&#x1EA5;y tokenized URL &#x111;&#x1EC3; truy c&#x1EAD;p l&#x1EA7;n &#x111;&#x1EA7;u</h3><pre><code class="language-bash">openclaw dashboard --no-open
</code></pre><p>Copy URL d&#x1EA1;ng <code>http://127.0.0.1:18789/#token=...</code> &#x2192; &#x111;&#x1ED5;i th&#xE0;nh <code>https://claw.yourdomain.com/#token=...</code></p><p>D&#xF9;ng URL n&#xE0;y &#x111;&#x1EC3; m&#x1EDF; dashboard l&#x1EA7;n &#x111;&#x1EA7;u, sau &#x111;&#xF3; bookmark l&#x1EA1;i.</p><hr><h2 id="ph%E1%BA%A7n-4-%E2%80%94-thi%E1%BA%BFt-l%E1%BA%ADp-zalo-bot">Ph&#x1EA7;n 4 &#x2014; Thi&#x1EBF;t l&#x1EAD;p Zalo Bot</h2><h3 id="41-t%E1%BA%A1o-bot-tr%C3%AAn-zalo-platform">4.1 T&#x1EA1;o Bot tr&#xEA;n Zalo Platform</h3><ol><li>V&#xE0;o <a href="https://bot.zaloplatforms.com/">bot.zaloplatforms.com</a></li><li>&#x110;&#x103;ng nh&#x1EAD;p b&#x1EB1;ng t&#xE0;i kho&#x1EA3;n Zalo</li><li>T&#x1EA1;o bot m&#x1EDB;i &#x2192; &#x111;&#x1EB7;t t&#xEA;n</li><li>Copy <strong>Bot Token</strong> (d&#x1EA1;ng <code>123456789:abc-xyz-token</code>)</li></ol><h3 id="42-c%E1%BA%A5u-h%C3%ACnh-zalo-channel-trong-openclaw">4.2 C&#x1EA5;u h&#xEC;nh Zalo channel trong OpenClaw</h3><pre><code class="language-bash">openclaw configure
</code></pre><p>Ch&#x1ECD;n:</p><ul><li><strong>Channels &#x2192; Zalo (Bot API)</strong></li><li>Nh&#x1EAD;p Bot Token</li><li><strong>Use webhook mode:</strong> <code>No</code> (d&#xF9;ng polling &#x2014; &#x1ED5;n &#x111;&#x1ECB;nh h&#x1A1;n)</li><li><strong>DM Policy:</strong> <code>Open</code> (cho ph&#xE9;p m&#x1ECD;i ng&#x1B0;&#x1EDD;i nh&#x1EAF;n tin)</li></ul><h3 id="43-test-bot">4.3 Test bot</h3><p>M&#x1EDF; Zalo &#x2192; t&#xEC;m bot theo t&#xEA;n &#x2192; nh&#x1EAF;n &quot;xin ch&#xE0;o&quot;</p><p>Bot s&#x1EBD; ph&#x1EA3;n h&#x1ED3;i trong v&#xF2;ng 1-3 gi&#xE2;y.</p><hr><h2 id="ph%E1%BA%A7n-5-%E2%80%94-auto-start-khi-m%C3%A1y-restart">Ph&#x1EA7;n 5 &#x2014; Auto-start khi m&#xE1;y restart</h2><h3 id="51-c%C3%A0i-launchagent">5.1 C&#xE0;i LaunchAgent</h3><pre><code class="language-bash">openclaw gateway install
</code></pre><h3 id="52-start-gateway">5.2 Start gateway</h3><pre><code class="language-bash">openclaw gateway start
</code></pre><h3 id="53-ki%E1%BB%83m-tra-tr%E1%BA%A1ng-th%C3%A1i">5.3 Ki&#x1EC3;m tra tr&#x1EA1;ng th&#xE1;i</h3><pre><code class="language-bash">openclaw gateway status
openclaw status
</code></pre><p>T&#x1EEB; gi&#x1EDD; gateway s&#x1EBD; <strong>t&#x1EF1; ch&#x1EA1;y m&#x1ED7;i khi m&#xE1;y kh&#x1EDF;i &#x111;&#x1ED9;ng</strong>, kh&#xF4;ng c&#x1EA7;n thao t&#xE1;c th&#x1EE7; c&#xF4;ng.</p><p><strong>C&#xE1;c l&#x1EC7;nh qu&#x1EA3;n l&#xFD;:</strong></p><!--kg-card-begin: html--><table>
<thead>
<tr>
<th>L&#x1EC7;nh</th>
<th>T&#xE1;c d&#x1EE5;ng</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>openclaw gateway start</code></td>
<td>Start gateway (ch&#x1EA1;y ng&#x1EA7;m)</td>
</tr>
<tr>
<td><code>openclaw gateway stop</code></td>
<td>Stop gateway</td>
</tr>
<tr>
<td><code>openclaw gateway status</code></td>
<td>Xem tr&#x1EA1;ng th&#xE1;i</td>
</tr>
<tr>
<td><code>openclaw logs --follow</code></td>
<td>Xem log realtime</td>
</tr>
</tbody>
</table><!--kg-card-end: html--><hr><h2 id="ph%E1%BA%A7n-6-%E2%80%94-truy-c%E1%BA%ADp-dashboard-t%E1%BB%AB-xa">Ph&#x1EA7;n 6 &#x2014; Truy c&#x1EAD;p Dashboard t&#x1EEB; xa</h2><h3 id="61-truy-c%E1%BA%ADp-l%E1%BA%A7n-%C4%91%E1%BA%A7u">6.1 Truy c&#x1EAD;p l&#x1EA7;n &#x111;&#x1EA7;u</h3><p>D&#xF9;ng tokenized URL:</p><pre><code>https://claw.yourdomain.com/#token=&lt;gateway-token&gt;
</code></pre><p>L&#x1EA5;y token:</p><pre><code class="language-bash">openclaw dashboard --no-open
</code></pre><h3 id="62-truy-c%E1%BA%ADp-th%C6%B0%E1%BB%9Dng-xuy%C3%AAn">6.2 Truy c&#x1EAD;p th&#x1B0;&#x1EDD;ng xuy&#xEA;n</h3><p>Sau khi v&#xE0;o b&#x1EB1;ng tokenized URL l&#x1EA7;n &#x111;&#x1EA7;u, browser s&#x1EBD; &#x111;&#x1B0;&#x1EE3;c approve t&#x1EF1; &#x111;&#x1ED9;ng. T&#x1EEB; l&#x1EA7;n sau ch&#x1EC9; c&#x1EA7;n v&#xE0;o <code>https://claw.yourdomain.com</code> v&#xE0; nh&#x1EAD;p password.</p><h3 id="63-chia-s%E1%BA%BB-v%E1%BB%9Bi-ng%C6%B0%E1%BB%9Di-kh%C3%A1c">6.3 Chia s&#x1EBB; v&#x1EDB;i ng&#x1B0;&#x1EDD;i kh&#xE1;c</h3><p>Share tokenized URL cho ng&#x1B0;&#x1EDD;i tin t&#x1B0;&#x1EDF;ng &#x2014; h&#x1ECD; c&#xF3; th&#x1EC3; v&#xE0;o th&#x1EB3;ng kh&#xF4;ng c&#x1EA7;n password.</p><p>&#x110;&#x1EC3; revoke: &#x111;&#x1ED5;i gateway token:</p><pre><code class="language-bash">openclaw config set gateway.auth.token &quot;$(openssl rand -hex 32)&quot;
</code></pre><hr><h2 id="ph%E1%BA%A7n-7-%E2%80%94-troubleshoot-th%C6%B0%E1%BB%9Dng-g%E1%BA%B7p">Ph&#x1EA7;n 7 &#x2014; Troubleshoot th&#x1B0;&#x1EDD;ng g&#x1EB7;p</h2><h3 id="gateway-kh%C3%B4ng-start">Gateway kh&#xF4;ng start</h3><pre><code class="language-bash">openclaw gateway status
openclaw doctor --fix
</code></pre><h3 id="zalo-kh%C3%B4ng-nh%E1%BA%ADng%E1%BB%ADi-tin">Zalo kh&#xF4;ng nh&#x1EAD;n/g&#x1EED;i tin</h3><pre><code class="language-bash">openclaw status
openclaw logs --follow
</code></pre><p>Ki&#x1EC3;m tra channel Zalo:</p><pre><code class="language-bash">openclaw channels list
</code></pre><h3 id="cloudflare-502-bad-gateway">Cloudflare 502 Bad Gateway</h3><p>Ki&#x1EC3;m tra gateway c&#xF3; bind &#x111;&#xFA;ng kh&#xF4;ng:</p><pre><code class="language-bash">openclaw config get gateway.bind
# Ph&#x1EA3;i l&#xE0;: lan
</code></pre><p>Ki&#x1EC3;m tra port:</p><pre><code class="language-bash">lsof -i :18789
</code></pre><h3 id="dashboard-y%C3%AAu-c%E1%BA%A7u-pairing-li%C3%AAn-t%E1%BB%A5c">Dashboard y&#xEA;u c&#x1EA7;u pairing li&#xEA;n t&#x1EE5;c</h3><p>D&#xF9;ng tokenized URL thay v&#xEC; v&#xE0;o tr&#x1EF1;c ti&#x1EBF;p domain, ho&#x1EB7;c:</p><pre><code class="language-bash">openclaw config set gateway.trustedProxies &apos;[&quot;127.0.0.1&quot;]&apos;
openclaw config set gateway.controlUi.allowedOrigins &apos;[&quot;https://claw.yourdomain.com&quot;]&apos;
openclaw gateway stop &amp;&amp; openclaw gateway start
</code></pre><hr><h2 id="t%C3%B3m-t%E1%BA%AFt-c%C3%A1c-l%E1%BB%87nh-quan-tr%E1%BB%8Dng">T&#xF3;m t&#x1EAF;t c&#xE1;c l&#x1EC7;nh quan tr&#x1ECD;ng</h2><pre><code class="language-bash"># C&#xE0;i &#x111;&#x1EB7;t
pnpm add -g openclaw@latest
openclaw onboard

# C&#x1EA5;u h&#xEC;nh
openclaw config set gateway.bind lan
openclaw config set gateway.trustedProxies &apos;[&quot;127.0.0.1&quot;]&apos;
openclaw config set gateway.controlUi.allowedOrigins &apos;[&quot;https://claw.yourdomain.com&quot;]&apos;
openclaw config set gateway.auth.password &quot;password&quot;

# Zalo
openclaw configure  # ch&#x1ECD;n Channels &#x2192; Zalo

# Auto-start
openclaw gateway install
openclaw gateway start

# Ki&#x1EC3;m tra
openclaw status
openclaw logs --follow
</code></pre><hr><p><em>B&#xE0;i vi&#x1EBF;t ti&#x1EBF;p theo: [C&#xE0;i &#x111;&#x1EB7;t OpenClaw tr&#xEA;n Linux VPS]</em></p>]]></content:encoded></item><item><title><![CDATA[Nghề Lập Trình Năm 2026: Dữ Liệu Nói Gì Khi Cơn Bão AI Đã Thực Sự Đổ Bộ?]]></title><description><![CDATA[Không phải góc nhìn "AI sẽ cướp việc của bạn". Không phải lời trấn an "Đừng lo, mọi thứ vẫn ổn." Đây là bức tranh thực tế — cùng những con đường thoát khỏi nó.]]></description><link>https://makexyz.fun/nghe-lap-trinh-nam-2026/</link><guid isPermaLink="false">69b10bf8ac3dc71e4179e38b</guid><category><![CDATA[AI]]></category><dc:creator><![CDATA[Tony Phạm]]></dc:creator><pubDate>Wed, 11 Mar 2026 06:31:43 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p><em>Kh&#xF4;ng ph&#x1EA3;i g&#xF3;c nh&#xEC;n &quot;AI s&#x1EBD; c&#x1B0;&#x1EDB;p vi&#x1EC7;c c&#x1EE7;a b&#x1EA1;n&quot;. Kh&#xF4;ng ph&#x1EA3;i l&#x1EDD;i tr&#x1EA5;n an &quot;&#x110;&#x1EEB;ng lo, m&#x1ECD;i th&#x1EE9; v&#x1EAB;n &#x1ED5;n.&quot; &#x110;&#xE2;y l&#xE0; b&#x1EE9;c tranh th&#x1EF1;c t&#x1EBF; &#x2014; c&#xF9;ng nh&#x1EEF;ng con &#x111;&#x1B0;&#x1EDD;ng tho&#xE1;t kh&#x1ECF;i n&#xF3;.</em></p>
<hr>
<p>C&#xF3; m&#x1ED9;t cu&#x1ED9;c tranh lu&#x1EAD;n &#x111;&#xE3; k&#xE9;o d&#xE0;i su&#x1ED1;t 3 n&#x103;m qua trong c&#x1ED9;ng &#x111;&#x1ED3;ng l&#x1EAD;p tr&#xEC;nh vi&#xEA;n to&#xE0;n c&#x1EA7;u: <em>AI c&#xF3; th&#x1EF1;c s&#x1EF1; thay th&#x1EBF; developer kh&#xF4;ng?</em></p>
<p>C&#xE2;u h&#x1ECF;i &#x111;&#xF3;, v&#xE0;o n&#x103;m 2026, &#x111;&#xE3; l&#x1ED7;i th&#x1EDD;i.</p>
<p>Kh&#xF4;ng ph&#x1EA3;i v&#xEC; c&#xE2;u tr&#x1EA3; l&#x1EDD;i l&#xE0; &quot;kh&#xF4;ng&quot;. M&#xE0; v&#xEC; th&#x1EF1;c t&#x1EBF; &#x111;&#xE3; x&#x1EA3;y ra r&#x1ED3;i &#x2014; ch&#x1EC9; l&#xE0; kh&#xF4;ng theo c&#xE1;ch ng&#x1B0;&#x1EDD;i ta t&#x1B0;&#x1EDF;ng t&#x1B0;&#x1EE3;ng. Kh&#xF4;ng ph&#x1EA3;i robot &#x111;&#x1EE9;ng g&#xF5; b&#xE0;n ph&#xED;m thay con ng&#x1B0;&#x1EDD;i. Kh&#xF4;ng ph&#x1EA3;i m&#x1ED9;t AI to&#xE0;n n&#x103;ng vi&#x1EBF;t to&#xE0;n b&#x1ED9; ph&#x1EA7;n m&#x1EC1;m t&#x1EEB; &#x111;&#x1EA7;u &#x111;&#x1EBF;n cu&#x1ED1;i. M&#xE0; l&#xE0; m&#x1ED9;t s&#x1EF1; d&#x1ECB;ch chuy&#x1EC3;n th&#x1EA7;m l&#x1EB7;ng, c&#xF3; h&#x1EC7; th&#x1ED1;ng, &#x111;ang t&#xE1;i &#x111;&#x1ECB;nh h&#xEC;nh ho&#xE0;n to&#xE0;n ai &#x111;&#x1B0;&#x1EE3;c thu&#xEA;, ai b&#x1ECB; th&#x1EA3;i, v&#xE0; &#x111;i&#x1EC1;u g&#xEC; th&#x1EF1;c s&#x1EF1; c&#xF3; gi&#xE1; tr&#x1ECB; trong ngh&#x1EC1; n&#xE0;y.</p>
<p>B&#xE0;i vi&#x1EBF;t n&#xE0;y kh&#xF4;ng &#x111;&#x1EBF;n &#x111;&#x1EC3; d&#x1EF1; b&#xE1;o t&#x1B0;&#x1A1;ng lai. N&#xF3; &#x111;&#x1EBF;n &#x111;&#x1EC3; nh&#xEC;n th&#x1EB3;ng v&#xE0;o nh&#x1EEF;ng g&#xEC; &#x111;ang x&#x1EA3;y ra &#x2014; b&#x1EB1;ng s&#x1ED1; li&#x1EC7;u, b&#x1EB1;ng xu h&#x1B0;&#x1EDB;ng th&#x1EF1;c t&#x1EBF; &#x2014; v&#xE0; quan tr&#x1ECD;ng h&#x1A1;n: <strong>b&#x1EA1;n n&#xEA;n l&#xE0;m g&#xEC; v&#x1EDB;i t&#x1EA5;t c&#x1EA3; &#x111;i&#x1EC1;u &#x111;&#xF3;.</strong></p>
<hr>
<h2 id="ph%E1%BA%A7n-i-k%E1%BB%B7-nguy%C3%AAn-code-chay-%C4%91%C3%A3-qua-%E2%80%94-nh%C6%B0ng-kh%C3%B4ng-theo-c%C3%A1ch-b%E1%BA%A1n-ngh%C4%A9">Ph&#x1EA7;n I: K&#x1EF7; Nguy&#xEA;n &quot;Code Chay&quot; &#x110;&#xE3; Qua &#x2014; Nh&#x1B0;ng Kh&#xF4;ng Theo C&#xE1;ch B&#x1EA1;n Ngh&#x129;</h2>
<h3 id="nh%E1%BB%AFng-con-s%E1%BB%91-kh%C3%B4ng-th%E1%BB%83-ph%E1%BB%A7-nh%E1%BA%ADn">Nh&#x1EEF;ng con s&#x1ED1; kh&#xF4;ng th&#x1EC3; ph&#x1EE7; nh&#x1EAD;n</h3>
<p>82% developer to&#xE0;n c&#x1EA7;u hi&#x1EC7;n &#x111;ang d&#xF9;ng AI coding tools h&#xE0;ng ng&#xE0;y ho&#x1EB7;c h&#xE0;ng tu&#x1EA7;n. 41% t&#x1ED5;ng l&#x1B0;&#x1EE3;ng code &#x111;&#x1B0;&#x1EE3;c vi&#x1EBF;t ra trong n&#x103;m 2025 c&#xF3; s&#x1EF1; tham gia c&#x1EE7;a AI. N&#x1EBF;u nh&#xEC;n v&#xE0;o c&#xE1;c Big Tech &#x2014; con s&#x1ED1; &#x111;&#xF3; c&#xF2;n cao h&#x1A1;n &#x111;&#xE1;ng k&#x1EC3;.</p>
<p>R&#xF5; r&#xE0;ng: vi&#x1EBF;t code ho&#xE0;n to&#xE0;n kh&#xF4;ng c&#xF3; AI h&#x1ED7; tr&#x1EE3; &#x111;ang tr&#x1EDF; th&#xE0;nh m&#x1ED9;t s&#x1EF1; l&#x1EF1;a ch&#x1ECD;n thi&#x1EC3;u s&#x1ED1;. Nh&#x1B0;ng &#x111;&#xE2;y l&#xE0; &#x111;i&#x1EC1;u quan tr&#x1ECD;ng m&#xE0; ph&#x1EA7;n l&#x1EDB;n c&#xE1;c b&#xE0;i ph&#xE2;n t&#xED;ch b&#x1ECF; qua:</p>
<p><strong>Ch&#x1EC9; 30% g&#x1EE3;i &#xFD; c&#x1EE7;a AI &#x111;&#x1B0;&#x1EE3;c developer ch&#x1EA5;p nh&#x1EAD;n.</strong></p>
<p>Ph&#x1EA7;n c&#xF2;n l&#x1EA1;i &#x2014; 70% &#x2014; b&#x1ECB; l&#x1ECD;c, b&#x1ECB; s&#x1EED;a, ho&#x1EB7;c b&#x1ECB; t&#x1EEB; ch&#x1ED1;i ho&#xE0;n to&#xE0;n. &#x110;i&#x1EC1;u &#x111;&#xF3; c&#xF3; ngh&#x129;a l&#xE0; ng&#x1B0;&#x1EDD;i d&#xF9;ng AI kh&#xF4;ng ph&#x1EA3;i &#x111;ang &quot;nh&#x1EAD;n code t&#x1EEB; AI&quot;. H&#x1ECD; &#x111;ang l&#xE0;m c&#xF4;ng vi&#x1EC7;c c&#x1EE7;a m&#x1ED9;t <strong>bi&#xEA;n t&#x1EAD;p vi&#xEA;n c&#x1EA5;p cao</strong>: li&#xEA;n t&#x1EE5;c &#x111;&#x1ECD;c, ph&#xE1;n x&#xE9;t, v&#xE0; quy&#x1EBF;t &#x111;&#x1ECB;nh c&#xE1;i g&#xEC; &#x111;&#x1EE7; t&#x1ED1;t &#x111;&#x1EC3; &#x111;i ti&#x1EBF;p.</p>
<p>V&#xE0; &#x111;&#xE2;y l&#xE0; &#x111;i&#x1EC3;m ph&#xE2;n k&#x1EF3; quan tr&#x1ECD;ng: kho&#x1EA3;ng 72% developer cho bi&#x1EBF;t &quot;vibe coding&quot; &#x2014; t&#x1EE9;c l&#xE0; prompt d&#x1EA1;o r&#x1ED3;i nh&#x1EAD;n s&#x1EA3;n ph&#x1EA9;m ho&#xE0;n ch&#x1EC9;nh &#x2014; kh&#xF4;ng ph&#x1EA3;i l&#xE0; m&#x1ED9;t ph&#x1EA7;n trong c&#xF4;ng vi&#x1EC7;c chuy&#xEA;n nghi&#x1EC7;p th&#x1EF1;c t&#x1EBF; c&#x1EE7;a h&#x1ECD;. Ph&#x1EA7;n l&#x1EDB;n th&#x1EF1;c t&#x1EBF; v&#x1EAB;n l&#xE0; <strong>con ng&#x1B0;&#x1EDD;i ki&#x1EC3;m so&#xE1;t, AI h&#x1ED7; tr&#x1EE3;</strong> &#x2014; kh&#xF4;ng ph&#x1EA3;i ng&#x1B0;&#x1EE3;c l&#x1EA1;i.</p>
<h3 id="v%E1%BA%ADy-%C4%91i%E1%BB%81u-g%C3%AC-%C4%91%C3%A3-th%E1%BB%B1c-s%E1%BB%B1-ch%E1%BA%BFt">V&#x1EAD;y &#x111;i&#x1EC1;u g&#xEC; &#x111;&#xE3; th&#x1EF1;c s&#x1EF1; ch&#x1EBF;t?</h3>
<p>Kh&#xF4;ng ph&#x1EA3;i vi&#x1EC7;c vi&#x1EBF;t code. M&#xE0; l&#xE0; vi&#x1EC7;c vi&#x1EBF;t code <strong>m&#xE0; kh&#xF4;ng suy ngh&#x129;</strong>. Nh&#x1EEF;ng t&#xE1;c v&#x1EE5; thu&#x1EA7;n c&#x1A1; h&#x1ECD;c &#x2014; generate boilerplate, vi&#x1EBF;t test case &#x111;&#x1A1;n gi&#x1EA3;n, d&#x1ECB;ch logic t&#x1EEB; pseudocode sang syntax &#x2014; &#x111;&#xE3; &#x111;&#x1B0;&#x1EE3;c AI h&#x1EA5;p th&#x1EE5; ho&#xE0;n to&#xE0;n. Kh&#xF4;ng ai c&#xF2;n &#x111;&#x1B0;&#x1EE3;c tr&#x1EA3; l&#x1B0;&#x1A1;ng ch&#x1EC9; &#x111;&#x1EC3; l&#xE0;m nh&#x1EEF;ng vi&#x1EC7;c &#x111;&#xF3; n&#x1EEF;a.</p>
<p>&#x110;i&#x1EC1;u &#x111;&#xE3; ch&#x1EBF;t l&#xE0; <strong>gi&#xE1; tr&#x1ECB; c&#x1EE7;a s&#x1EF1; th&#xE0;nh th&#x1EA1;o thu&#x1EA7;n t&#xFA;y v&#x1EC1; m&#x1EB7;t k&#x1EF9; thu&#x1EAD;t c&#xFA; ph&#xE1;p</strong>. Bi&#x1EBF;t vi&#x1EBF;t for-loop kh&#xF4;ng c&#xF2;n l&#xE0; &#x111;i&#x1EC3;m c&#x1ED9;ng &#x2014; &#x111;&#xF3; l&#xE0; &#x111;i&#x1EC1;u ki&#x1EC7;n t&#x1ED1;i thi&#x1EC3;u hi&#x1EC3;n nhi&#xEA;n &#x111;&#x1EBF;n m&#x1EE9;c kh&#xF4;ng &#x111;&#xE1;ng &#x111;&#x1EC1; c&#x1EAD;p.</p>
<hr>
<h2 id="ph%E1%BA%A7n-ii-kh%E1%BB%A7ng-ho%E1%BA%A3ng-junior-developer-%E2%80%94-nghi%C3%AAm-tr%E1%BB%8Dng-h%C6%A1n-nh%E1%BB%AFng-g%C3%AC-%C4%91%C6%B0%E1%BB%A3c-n%C3%B3i-%C4%91%E1%BA%BFn">Ph&#x1EA7;n II: Kh&#x1EE7;ng Ho&#x1EA3;ng Junior Developer &#x2014; Nghi&#xEA;m Tr&#x1ECD;ng H&#x1A1;n Nh&#x1EEF;ng G&#xEC; &#x110;&#x1B0;&#x1EE3;c N&#xF3;i &#x110;&#x1EBF;n</h2>
<h3 id="d%E1%BB%AF-li%E1%BB%87u-th%E1%BA%ADt-s%E1%BB%B1-%C4%91%C3%A1ng-lo-ng%E1%BA%A1i">D&#x1EEF; li&#x1EC7;u th&#x1EAD;t s&#x1EF1; &#x111;&#xE1;ng lo ng&#x1EA1;i</h3>
<p>S&#x1ED1; li&#x1EC7;u t&#x1EEB; 2024&#x2013;2025 kh&#xF4;ng d&#x1EC5; &#x111;&#x1ECD;c:</p>
<ul>
<li>T&#x1EA1;i M&#x1EF9;, t&#x1ED5;ng s&#x1ED1; l&#x1EAD;p tr&#xEC;nh vi&#xEA;n &#x111;&#x1B0;&#x1EE3;c tuy&#x1EC3;n d&#x1EE5;ng gi&#x1EA3;m 27.5% trong giai &#x111;o&#x1EA1;n 2023&#x2013;2025.</li>
<li>Developer &#x111;&#x1ED9; tu&#x1ED5;i 22&#x2013;25 m&#x1EA5;t g&#x1EA7;n 20% c&#x1A1; h&#x1ED9;i vi&#x1EC7;c l&#xE0;m so v&#x1EDB;i &#x111;&#x1EC9;nh &#x111;i&#x1EC3;m cu&#x1ED1;i 2022.</li>
<li>Trong 3 n&#x103;m qua, s&#x1ED1; l&#x1B0;&#x1EE3;ng sinh vi&#xEA;n m&#x1EDB;i t&#x1ED1;t nghi&#x1EC7;p &#x111;&#x1B0;&#x1EE3;c tuy&#x1EC3;n b&#x1EDF;i Big Tech to&#xE0;n c&#x1EA7;u gi&#x1EA3;m h&#x1A1;n 50%.</li>
<li>T&#x1EA1;i EU, LinkedIn, Indeed v&#xE0; Eures ghi nh&#x1EAD;n m&#x1EE9;c gi&#x1EA3;m 35% v&#x1ECB; tr&#xED; junior tech trong n&#x103;m 2024.</li>
</ul>
<p>Nh&#x1EEF;ng con s&#x1ED1; n&#xE0;y kh&#xF4;ng &#x111;&#x1EBF;n t&#x1EEB; l&#xE0;n s&#xF3;ng sa th&#x1EA3;i &#x1ED3; &#x1EA1;t. Ch&#xFA;ng &#x111;&#x1EBF;n t&#x1EEB; m&#x1ED9;t &#x111;i&#x1EC1;u &#x111;&#x1A1;n gi&#x1EA3;n h&#x1A1;n v&#xE0; &#x111;&#xE1;ng s&#x1EE3; h&#x1A1;n: <strong>c&#xE1;c c&#xF4;ng ty kh&#xF4;ng c&#xF2;n m&#x1EDF; v&#x1ECB; tr&#xED; m&#x1EDB;i n&#x1EEF;a.</strong></p>
<p>M&#x1ED9;t nghi&#xEA;n c&#x1EE9;u t&#x1EEB; Harvard ph&#xE1;t hi&#x1EC7;n: sau cu&#x1ED1;i 2022, c&#xE1;c c&#xF4;ng ty &#xE1;p d&#x1EE5;ng AI &#x111;&#xE3; tuy&#x1EC3;n &#xED;t h&#x1A1;n 5 nh&#xE2;n s&#x1EF1; junior m&#x1ED7;i qu&#xFD; &#x2014; v&#xE0; s&#x1EF1; thay &#x111;&#x1ED5;i n&#xE0;y kh&#xF4;ng &#x111;&#x1EBF;n t&#x1EEB; sa th&#x1EA3;i, m&#xE0; t&#x1EEB; vi&#x1EC7;c ng&#x1EEB;ng tuy&#x1EC3;n d&#x1EE5;ng ho&#xE0;n to&#xE0;n.</p>
<h3 id="h%E1%BB%87-qu%E1%BA%A3-m%C3%A0-kh%C3%B4ng-ai-mu%E1%BB%91n-n%C3%B3i-th%E1%BA%B3ng">H&#x1EC7; qu&#x1EA3; m&#xE0; kh&#xF4;ng ai mu&#x1ED1;n n&#xF3;i th&#x1EB3;ng</h3>
<p>AI c&#xF3; th&#x1EC3; generate code boilerplate, vi&#x1EBF;t test case, t&#x1EA1;o UI component t&#x1EEB; m&#xF4; t&#x1EA3;. &#x110;&#xE2;y ch&#xED;nh x&#xE1;c l&#xE0; nh&#x1EEF;ng g&#xEC; Junior Developer l&#xE0;m trong 1&#x2013;2 n&#x103;m &#x111;&#x1EA7;u s&#x1EF1; nghi&#x1EC7;p. V&#x1EAD;y c&#xE2;u h&#x1ECF;i &#x111;&#x1EB7;t ra l&#xE0;: n&#x1EBF;u kh&#xF4;ng c&#xF3; nh&#x1EEF;ng c&#xF4;ng vi&#x1EC7;c &#x111;&#xF3;, Junior h&#x1ECD;c v&#xE0; t&#xED;ch l&#x169;y kinh nghi&#x1EC7;m t&#x1EEB; &#x111;&#xE2;u?</p>
<p><strong>&#x110;&#xE2;y l&#xE0; v&#x1EA5;n &#x111;&#x1EC1; c&#x1EA5;u tr&#xFA;c nghi&#xEA;m tr&#x1ECD;ng m&#xE0; to&#xE0;n ng&#xE0;nh &#x111;ang c&#x1ED1; t&#xEC;nh b&#x1ECF; qua:</strong></p>
<p>N&#x1EBF;u h&#xF4;m nay kh&#xF4;ng c&#xF3; Junior, th&#xEC; 5 n&#x103;m n&#x1EEF;a l&#x1EA5;y &#x111;&#xE2;u ra Senior? Ch&#xFA;ng ta &#x111;ang c&#x1B0;a &#x111;&#x1EE9;t ch&#xED;nh nh&#xE1;nh c&#xE2;y m&#xEC;nh &#x111;ang ng&#x1ED3;i &#x2014; b&#x1EB1;ng c&#xE1;ch t&#x1ED1;i &#x1B0;u h&#xF3;a hi&#x1EC7;u qu&#x1EA3; ng&#x1EAF;n h&#x1EA1;n m&#xE0; b&#x1ECF; qua ho&#xE0;n to&#xE0;n vi&#x1EC7;c t&#xE1;i t&#x1EA1;o nh&#xE2;n l&#x1EF1;c d&#xE0;i h&#x1EA1;n.</p>
<p>M&#x1ED9;t s&#x1ED1; nh&#xE0; nghi&#xEA;n c&#x1EE9;u g&#x1ECD;i &#x111;&#xE2;y l&#xE0; &quot;L&#x1ED7; h&#x1ED5;ng th&#x1EBF; h&#x1EC7; k&#x1EF9; s&#x1B0;&quot; (<em>Engineer Generation Gap</em>). V&#xE0; kh&#xF4;ng ai c&#xF3; c&#xE2;u tr&#x1EA3; l&#x1EDD;i t&#x1ED1;t cho n&#xF3;.</p>
<h3 id="con-%C4%91%C6%B0%E1%BB%9Dng-s%E1%BB%91ng-s%C3%B3t-duy-nh%E1%BA%A5t-cho-junior-n%C4%83m-2026">Con &#x111;&#x1B0;&#x1EDD;ng s&#x1ED1;ng s&#xF3;t duy nh&#x1EA5;t cho Junior n&#x103;m 2026</h3>
<p>N&#x1EBF;u b&#x1EA1;n &#x111;ang l&#xE0; sinh vi&#xEA;n ho&#x1EB7;c m&#x1EDB;i v&#xE0;o ngh&#x1EC1;, &#x111;&#xE2;y l&#xE0; th&#x1EF1;c t&#x1EBF; b&#x1EA1;n c&#x1EA7;n ch&#x1EA5;p nh&#x1EAD;n: ch&#x1EC9; bi&#x1EBF;t code kh&#xF4;ng &#x111;&#x1EE7; n&#x1EEF;a. Ch&#x1B0;a bao gi&#x1EDD; l&#xE0; &#x111;&#x1EE7;, nh&#x1B0;ng b&#xE2;y gi&#x1EDD; kho&#x1EA3;ng c&#xE1;ch c&#xF2;n r&#xF5; r&#xE0;ng h&#x1A1;n bao gi&#x1EDD; h&#x1EBF;t.</p>
<p>&#x110;i&#x1EC1;u AI kh&#xF4;ng th&#x1EC3; l&#xE0;m t&#x1ED1;t &#x2014; v&#xE0; c&#xF3; th&#x1EC3; s&#x1EBD; kh&#xF4;ng l&#xE0;m t&#x1ED1;t trong nhi&#x1EC1;u n&#x103;m t&#x1EDB;i &#x2014; l&#xE0; <strong>hi&#x1EC3;u nghi&#x1EC7;p v&#x1EE5;</strong>. Hi&#x1EC3;u t&#x1EA1;i sao m&#x1ED9;t h&#x1EC7; th&#x1ED1;ng DeFi c&#x1EA7;n thi&#x1EBF;t k&#x1EBF; liquidation theo c&#xE1;ch n&#xE0;y ch&#x1EE9; kh&#xF4;ng ph&#x1EA3;i c&#xE1;ch kia. Hi&#x1EC3;u t&#x1EA1;i sao lu&#x1ED3;ng thanh to&#xE1;n c&#x1EE7;a m&#x1ED9;t s&#xE0;n th&#x1B0;&#x1A1;ng m&#x1EA1;i &#x111;i&#x1EC7;n t&#x1EED; c&#x1EA7;n x&#x1EED; l&#xFD; edge case c&#x1EE5; th&#x1EC3; n&#xE0;y. Hi&#x1EC3;u t&#x1EA1;i sao quy&#x1EBF;t &#x111;&#x1ECB;nh ki&#x1EBF;n tr&#xFA;c h&#xF4;m nay s&#x1EBD; &#x1EA3;nh h&#x1B0;&#x1EDF;ng &#x111;&#x1EBF;n kh&#x1EA3; n&#x103;ng m&#x1EDF; r&#x1ED9;ng 2 n&#x103;m sau.</p>
<p>&#x110;&#xF3; l&#xE0; <strong>Domain Knowledge</strong> &#x2014; ki&#x1EBF;n th&#x1EE9;c chuy&#xEA;n ng&#xE0;nh s&#xE2;u trong m&#x1ED9;t l&#x129;nh v&#x1EF1;c c&#x1EE5; th&#x1EC3;. Kh&#xF4;ng h&#x1ECD;c &#x111;&#x1B0;&#x1EE3;c qua m&#x1ED9;t prompt. Kh&#xF4;ng thay th&#x1EBF; &#x111;&#x1B0;&#x1EE3;c b&#x1EB1;ng m&#x1ED9;t model. V&#xE0; &#x111;&#xE2;y ch&#xED;nh l&#xE0; th&#x1EE9; bi&#x1EBF;n b&#x1EA1;n t&#x1EEB; &quot;ng&#x1B0;&#x1EDD;i g&#xF5; code&quot; th&#xE0;nh &quot;ng&#x1B0;&#x1EDD;i ch&#x1EC9; &#x111;&#x1EA1;o AI&quot;.</p>
<p><strong>G&#x1EE3;i &#xFD; th&#x1EF1;c t&#x1EBF;:</strong></p>
<ul>
<li>Ch&#x1ECD;n m&#x1ED9;t domain &#x111;&#x1EC3; &#x111;&#x1EA7;u t&#x1B0; s&#xE2;u: fintech, healthtech, logistics, e-commerce, ho&#x1EB7;c b&#x1EA5;t c&#x1EE9; l&#x129;nh v&#x1EF1;c n&#xE0;o b&#x1EA1;n th&#x1EF1;c s&#x1EF1; quan t&#xE2;m.</li>
<li>H&#x1ECD;c ng&#xF4;n ng&#x1EEF; nghi&#x1EC7;p v&#x1EE5; c&#x1EE7;a domain &#x111;&#xF3; &#x2014; kh&#xF4;ng ph&#x1EA3;i ch&#x1EC9; code, m&#xE0; c&#x1EA3; quy tr&#xEC;nh, quy &#x111;&#x1ECB;nh, r&#x1EE7;i ro &#x111;&#x1EB7;c th&#xF9;.</li>
<li>T&#xEC;m c&#xE1;ch tham gia d&#x1EF1; &#xE1;n th&#x1EF1;c t&#x1EBF; c&#xE0;ng s&#x1EDB;m c&#xE0;ng t&#x1ED1;t, d&#xF9; nh&#x1ECF; &#x2014; &#x111;&#x1EC3; x&#xE2;y d&#x1EF1;ng context m&#xE0; AI kh&#xF4;ng c&#xF3;.</li>
</ul>
<hr>
<h2 id="ph%E1%BA%A7n-iii-ai-technical-debt-%E2%80%94-qu%E1%BA%A3-bom-h%E1%BA%B9n-gi%E1%BB%9D-m%C3%A0-%C3%ADt-ng%C6%B0%E1%BB%9Di-nh%E1%BA%AFc-%C4%91%E1%BA%BFn">Ph&#x1EA7;n III: AI Technical Debt &#x2014; Qu&#x1EA3; Bom H&#x1EB9;n Gi&#x1EDD; M&#xE0; &#xCD;t Ng&#x1B0;&#x1EDD;i Nh&#x1EAF;c &#x110;&#x1EBF;n</h2>
<h3 id="t%E1%BB%91c-%C4%91%E1%BB%99-t%E1%BA%A1o-ra-code-%E2%89%A0-t%E1%BB%91c-%C4%91%E1%BB%99-hi%E1%BB%83u-code">T&#x1ED1;c &#x111;&#x1ED9; t&#x1EA1;o ra code &#x2260; T&#x1ED1;c &#x111;&#x1ED9; hi&#x1EC3;u code</h3>
<p>T&#x1ED1;c &#x111;&#x1ED9; s&#x1EA3;n xu&#x1EA5;t code t&#x103;ng 10&#x2013;20 l&#x1EA7;n. Nh&#x1B0;ng kh&#x1EA3; n&#x103;ng &#x111;&#x1ECD;c hi&#x1EC3;u v&#xE0; debug c&#x1EE7;a con ng&#x1B0;&#x1EDD;i th&#xEC; kh&#xF4;ng.</p>
<p>GitClear Research 2025 ghi nh&#x1EAD;n m&#x1ED9;t xu h&#x1B0;&#x1EDB;ng &#x111;&#xE1;ng lo: code b&#x1ECB; copy-paste &#x111;&#xE3; t&#x103;ng v&#x1B0;&#x1EE3;t code &#x111;&#x1B0;&#x1EE3;c t&#xE1;i c&#x1EA5;u tr&#xFA;c t&#x1EEB; n&#x103;m 2022 &#x111;&#x1EBF;n nay &#x2014; v&#xE0; &#x111;&#x1B0;&#x1EDD;ng cong ti&#x1EBF;p t&#x1EE5;c &#x111;i l&#xEA;n. &#x110;&#xE2;y l&#xE0; ch&#x1EC9; b&#xE1;o r&#xF5; r&#xE0;ng c&#x1EE7;a m&#x1ED9;t h&#x1EC7; th&#x1ED1;ng &#x111;ang t&#xED;ch l&#x169;y technical debt &#x1EDF; t&#x1ED1;c &#x111;&#x1ED9; ch&#x1B0;a t&#x1EEB;ng c&#xF3;.</p>
<p>Addy Osmani t&#x1EEB; Google &#x111;&#xE3; m&#xF4; t&#x1EA3; r&#x1EA5;t th&#x1EB3;ng th&#x1EAF;n: <em>&quot;Vi&#x1EC7;c d&#xF9;ng AI &#x111;&#x1EC3; t&#x103;ng t&#x1ED1;c &#x111;&#x1ED9; &#x111;&#x1ED3;ng ngh&#x129;a v&#x1EDB;i vi&#x1EC7;c nhi&#x1EC1;u code h&#x1A1;n b&#x1ECB; &apos;n&#xE9;m qua t&#x1B0;&#x1EDD;ng&apos;, v&#xE0; ai &#x111;&#xF3; ph&#x1EA3;i review n&#xF3;. Ch&#xFA;ng ta &#x111;ang b&#x1EAF;t &#x111;&#x1EA7;u th&#x1EA5;y code review tr&#x1EDF; th&#xE0;nh n&#xFA;t th&#x1EAF;t c&#x1ED5; chai m&#x1EDB;i.&quot;</em></p>
<h3 id="s%E1%BB%B1-c%E1%BB%91-3-gi%E1%BB%9D-s%C3%A1ng-v%C3%A0-c%C3%A2u-h%E1%BB%8Fi-%C4%91au-%C4%91%E1%BB%9Bn">S&#x1EF1; c&#x1ED1; 3 gi&#x1EDD; s&#xE1;ng v&#xE0; c&#xE2;u h&#x1ECF;i &#x111;au &#x111;&#x1EDB;n</h3>
<p>AI c&#xF3; th&#x1EC3; t&#x1EA1;o ra code ch&#x1EA1;y &#x111;&#x1B0;&#x1EE3;c. Nh&#x1B0;ng &quot;ch&#x1EA1;y &#x111;&#x1B0;&#x1EE3;c&quot; v&#xE0; &quot;b&#x1EC1;n v&#x1EEF;ng&quot; l&#xE0; hai &#x111;i&#x1EC1;u kh&#xE1;c nhau. AI-generated code th&#x1B0;&#x1EDD;ng ho&#x1EA1;t &#x111;&#x1ED9;ng t&#x1ED1;t trong happy path, nh&#x1B0;ng ch&#x1EE9;a &#x111;&#x1EA7;y nh&#x1EEF;ng edge case b&#x1ECB; b&#x1ECF; qua, l&#x1ED7; h&#x1ED5;ng b&#x1EA3;o m&#x1EAD;t &#x1EA9;n, v&#xE0; ki&#x1EBF;n tr&#xFA;c r&#x1ED1;i r&#x1EAF;m m&#xE0; ch&#x1EC9; b&#x1ED9;c l&#x1ED9; khi h&#x1EC7; th&#x1ED1;ng ch&#x1ECB;u t&#x1EA3;i th&#x1EF1;c t&#x1EBF;.</p>
<p>V&#xE0; khi h&#x1EC7; th&#x1ED1;ng s&#x1EE5;p &#x111;&#x1ED5; l&#xFA;c 3 gi&#x1EDD; s&#xE1;ng &#x2014; ng&#x1B0;&#x1EDD;i c&#x1EA7;n x&#x1EED; l&#xFD; kh&#xF4;ng ph&#x1EA3;i l&#xE0; AI. Ng&#x1B0;&#x1EDD;i &#x111;&#xF3; l&#xE0; b&#x1EA1;n.</p>
<p>MIT Sloan Review &#x111;&#xE3; &#x111;&#x1EB7;t ra m&#x1ED9;t c&#x1EA3;nh b&#xE1;o &#x111;&#xE1;ng suy ng&#x1EAB;m: developer thi&#x1EBF;u kinh nghi&#x1EC7;m c&#xF3; th&#x1EC3; vi&#x1EBF;t code nhanh ngang Senior khi d&#xF9;ng AI, nh&#x1B0;ng <em>&quot;h&#x1ECD; kh&#xF4;ng c&#xF3; c&#x1EA3;m gi&#xE1;c nh&#x1EAD;n th&#x1EE9;c v&#x1EC1; vi&#x1EC7;c h&#x1ECD; &#x111;ang l&#xE0;m g&#xEC;, hay v&#x1EA5;n &#x111;&#x1EC1; h&#x1ECD; &#x111;ang t&#x1EA1;o ra.&quot;</em></p>
<p>&#x110;&#xE2;y &#x111;&#x1EB7;c bi&#x1EC7;t nguy hi&#x1EC3;m trong m&#xF4;i tr&#x1B0;&#x1EDD;ng <strong>brownfield</strong> &#x2014; c&#xE1;c h&#x1EC7; th&#x1ED1;ng hi&#x1EC7;n c&#xF3; v&#x1EDB;i legacy code ph&#x1EE9;c t&#x1EA1;p &#x2014; n&#x1A1;i AI-generated code kh&#xF4;ng gi&#x1EA3;i quy&#x1EBF;t technical debt m&#xE0; c&#xF2;n c&#xF3; th&#x1EC3; nh&#xE2;n l&#xEA;n n&#xF3;.</p>
<h3 id="k%E1%BB%B9-n%C4%83ng-quan-tr%E1%BB%8Dng-nh%E1%BA%A5t-c%E1%BB%A7a-n%C4%83m-2026">K&#x1EF9; n&#x103;ng quan tr&#x1ECD;ng nh&#x1EA5;t c&#x1EE7;a n&#x103;m 2026</h3>
<p>Theo kh&#x1EA3;o s&#xE1;t State of Code 2026, k&#x1EF9; n&#x103;ng &#x111;&#x1B0;&#x1EE3;c &#x111;&#xE1;nh gi&#xE1; quan tr&#x1ECD;ng nh&#x1EA5;t trong k&#x1EF7; nguy&#xEA;n AI l&#xE0; &quot;review v&#xE0; x&#xE1;c th&#x1EF1;c code do AI t&#x1EA1;o ra v&#x1EC1; ch&#x1EA5;t l&#x1B0;&#x1EE3;ng v&#xE0; b&#x1EA3;o m&#x1EAD;t&quot; (47%) &#x2014; &#x111;&#x1EE9;ng tr&#xEA;n c&#x1EA3; &quot;k&#x1EF9; n&#x103;ng prompt AI hi&#x1EC7;u qu&#x1EA3;&quot; (42%).</p>
<p>&#x110;i&#x1EC1;u &#x111;&#xF3; c&#xF3; ngh&#x129;a l&#xE0;: <strong>Senior Engineer n&#x103;m 2026 kh&#xF4;ng c&#x1EA7;n code gi&#x1ECF;i h&#x1A1;n AI. H&#x1ECD; c&#x1EA7;n &#x111;&#x1ECD;c &#x111;&#x1B0;&#x1EE3;c nh&#x1EEF;ng g&#xEC; AI t&#x1EA1;o ra v&#xE0; bi&#x1EBF;t &#x111;&#xE2;u l&#xE0; &#x111;i&#x1EC3;m nguy hi&#x1EC3;m.</strong></p>
<p><strong>G&#x1EE3;i &#xFD; th&#x1EF1;c t&#x1EBF;:</strong></p>
<ul>
<li>Luy&#x1EC7;n t&#x1EAD;p &#x111;&#x1ECD;c code l&#x1EA1; &#x2014; open source projects l&#xE0; ngu&#x1ED3;n t&#xE0;i nguy&#xEA;n tuy&#x1EC7;t v&#x1EDD;i cho vi&#x1EC7;c n&#xE0;y.</li>
<li>H&#x1ECD;c System Design v&#xE0; ki&#x1EBF;n tr&#xFA;c ph&#x1EA7;n m&#x1EC1;m &#x2014; kh&#xF4;ng &#x111;&#x1EC3; code nhanh h&#x1A1;n, m&#xE0; &#x111;&#x1EC3; ph&#xE1;n x&#xE9;t t&#x1ED1;t h&#x1A1;n.</li>
<li>X&#xE2;y d&#x1EF1;ng th&#xF3;i quen review AI output v&#x1EDB;i t&#x1B0; duy &quot;k&#x1EBB; th&#xF9;&quot;: h&#x1ECF;i &quot;&#x111;o&#x1EA1;n code n&#xE0;y c&#xF3; th&#x1EC3; fail &#x1EDF; &#x111;&#xE2;u?&quot; tr&#x1B0;&#x1EDB;c khi h&#x1ECF;i &quot;n&#xF3; c&#xF3; ch&#x1EA1;y kh&#xF4;ng?&quot;</li>
<li>L&#xE0;m quen v&#x1EDB;i c&#xE1;c c&#xF4;ng c&#x1EE5; static analysis, security scanning &#x2014; ch&#xFA;ng s&#x1EBD; tr&#x1EDF; th&#xE0;nh &#x111;&#x1ED3;ng nghi&#x1EC7;p quan tr&#x1ECD;ng nh&#x1EA5;t c&#x1EE7;a b&#x1EA1;n.</li>
</ul>
<hr>
<h2 id="ph%E1%BA%A7n-iv-th%E1%BB%8B-tr%C6%B0%E1%BB%9Dng-it-ph%C3%A2n-h%C3%B3a-h%C3%ACnh-ch%E1%BB%AF-k-%E2%80%94-v%C3%A0-b%E1%BA%A1n-%C4%91ang-%E1%BB%9F-%C4%91%C3%A2u">Ph&#x1EA7;n IV: Th&#x1ECB; Tr&#x1B0;&#x1EDD;ng IT Ph&#xE2;n H&#xF3;a H&#xEC;nh Ch&#x1EEF; K &#x2014; V&#xE0; B&#x1EA1;n &#x110;ang &#x1EDE; &#x110;&#xE2;u?</h2>
<h3 id="d%E1%BB%AF-li%E1%BB%87u-x%C3%A1c-nh%E1%BA%ADn-s%E1%BB%B1-ph%C3%A2n-h%C3%B3a">D&#x1EEF; li&#x1EC7;u x&#xE1;c nh&#x1EAD;n s&#x1EF1; ph&#xE2;n h&#xF3;a</h3>
<p>Stanford Digital Economy x&#xE1;c nh&#x1EAD;n: v&#x1EDB;i c&#xE1;c c&#xF4;ng vi&#x1EC7;c c&#xF3; m&#x1EE9;c &#x111;&#x1ED9; ph&#x1A1;i nhi&#x1EC5;m AI cao nh&#x1EA5;t nh&#x1B0; IT v&#xE0; software engineering, vi&#x1EC7;c l&#xE0;m gi&#x1EA3;m 6% v&#x1EDB;i nh&#xF3;m tu&#x1ED5;i 22&#x2013;25, trong khi <strong>t&#x103;ng 9%</strong> v&#x1EDB;i nh&#xF3;m 35&#x2013;49 tu&#x1ED5;i &#x2014; c&#xF9;ng m&#x1ED9;t th&#x1ECB; tr&#x1B0;&#x1EDD;ng, hai chi&#x1EC1;u ng&#x1B0;&#x1EE3;c nhau.</p>
<p>V&#x1EC1; l&#x1B0;&#x1A1;ng: developer gi&#x1ECF;i AI &#x111;ang nh&#x1EAD;n $90K&#x2013;$130K &#x1EDF; v&#x1ECB; tr&#xED; entry-level AI, so v&#x1EDB;i $65K&#x2013;$85K &#x1EDF; v&#x1ECB; tr&#xED; dev truy&#x1EC1;n th&#x1ED1;ng &#x2014; ch&#xEA;nh l&#x1EC7;ch 40&#x2013;50% ngay t&#x1EEB; &#x111;&#x1EA7;u s&#x1EF1; nghi&#x1EC7;p.</p>
<h3 id="hai-nh%C3%B3m-%C4%91ang-ph%C3%A2n-k%E1%BB%B3">Hai nh&#xF3;m &#x111;ang ph&#xE2;n k&#x1EF3;</h3>
<p><strong>Nh&#xF3;m &#x111;i l&#xEA;n</strong> kh&#xF4;ng ph&#x1EA3;i l&#xE0; nh&#x1EEF;ng ng&#x1B0;&#x1EDD;i d&#xF9;ng AI nhi&#x1EC1;u nh&#x1EA5;t. &#x110;&#xF3; l&#xE0; nh&#x1EEF;ng ng&#x1B0;&#x1EDD;i d&#xF9;ng AI <strong>th&#xF4;ng minh nh&#x1EA5;t</strong> &#x2014; v&#x1EEF;ng n&#x1EC1;n t&#x1EA3;ng System Design, hi&#x1EC3;u s&#xE2;u m&#x1ED9;t domain, v&#xE0; coi AI nh&#x1B0; c&#xF4;ng c&#x1EE5; khu&#x1EBF;ch &#x111;&#x1EA1;i t&#x1B0; duy c&#x1EE7;a m&#xEC;nh ch&#x1EE9; kh&#xF4;ng ph&#x1EA3;i thay th&#x1EBF; n&#xF3;. H&#x1ECD; c&#xF3; th&#x1EC3; m&#x1ED9;t m&#xEC;nh v&#x1EAD;n h&#xE0;nh d&#x1EF1; &#xE1;n b&#x1EB1;ng c&#x1EA3; team 10 ng&#x1B0;&#x1EDD;i tr&#x1B0;&#x1EDB;c &#x111;&#xE2;y.</p>
<p><strong>Nh&#xF3;m &#x111;i xu&#x1ED1;ng</strong> g&#x1ED3;m hai ki&#x1EC3;u ho&#xE0;n to&#xE0;n &#x111;&#x1ED1;i l&#x1EAD;p nhau: nh&#x1EEF;ng ng&#x1B0;&#x1EDD;i t&#x1EEB; ch&#x1ED1;i h&#x1ECD;c AI v&#xE0; c&#x1ED1; gi&#x1EEF; c&#xE1;ch l&#xE0;m c&#x169; &#x2014; v&#xE0; nh&#x1EEF;ng ng&#x1B0;&#x1EDD;i ph&#x1EE5; thu&#x1ED9;c 100% v&#xE0;o AI m&#xE0; kh&#xF4;ng c&#xF3; n&#x1EC1;n t&#x1EA3;ng t&#x1B0; duy h&#x1EC7; th&#x1ED1;ng. C&#x1EA3; hai &#x111;&#x1EC1;u &#x111;ang d&#x1EA7;n b&#x1ECB; lo&#x1EA1;i kh&#x1ECF;i cu&#x1ED9;c ch&#x1A1;i, ch&#x1EC9; l&#xE0; theo nh&#x1EEF;ng con &#x111;&#x1B0;&#x1EDD;ng kh&#xE1;c nhau.</p>
<h3 id="c%E1%BA%A3nh-b%C3%A1o-d%C3%A0i-h%E1%BA%A1n-m%C3%A0-kh%C3%B4ng-ai-mu%E1%BB%91n-nghe">C&#x1EA3;nh b&#xE1;o d&#xE0;i h&#x1EA1;n m&#xE0; kh&#xF4;ng ai mu&#x1ED1;n nghe</h3>
<p>S&#x1EF1; ph&#xE2;n h&#xF3;a hi&#x1EC7;n t&#x1EA1;i c&#xF3; th&#x1EC3; t&#x1EA1;o ra ph&#x1EA3;n &#x1EE9;ng ng&#x1B0;&#x1EE3;c trong v&#xE0;i n&#x103;m t&#x1EDB;i. N&#x1EBF;u kh&#xF4;ng c&#xF3; lu&#x1ED3;ng nh&#xE2;n s&#x1EF1; entry-level, c&#xE1;c c&#xF4;ng ty s&#x1EBD; &#x111;&#x1ED1;i m&#x1EB7;t v&#x1EDB;i t&#xEC;nh tr&#x1EA1;ng thi&#x1EBF;u h&#x1EE5;t mid-level talent nghi&#xEA;m tr&#x1ECD;ng v&#xE0;o cu&#x1ED1;i th&#x1EAD;p k&#x1EF7; n&#xE0;y. &#x110;&#xE2;y kh&#xF4;ng ph&#x1EA3;i d&#x1EF1; b&#xE1;o &#x2014; &#x111;&#xE2;y l&#xE0; h&#x1EC7; qu&#x1EA3; t&#x1EA5;t y&#x1EBF;u c&#x1EE7;a to&#xE1;n h&#x1ECD;c &#x111;&#x1A1;n gi&#x1EA3;n: kh&#xF4;ng c&#xF3; Junior h&#xF4;m nay = kh&#xF4;ng c&#xF3; Senior ng&#xE0;y mai.</p>
<p>M&#x1ED9;t s&#x1ED1; c&#xF4;ng ty ti&#xEA;n phong &#x111;&#xE3; b&#x1EAF;t &#x111;&#x1EA7;u &#x111;&#x1EA7;u t&#x1B0; l&#x1EA1;i v&#xE0;o ch&#x1B0;&#x1A1;ng tr&#xEC;nh &#x111;&#xE0;o t&#x1EA1;o n&#x1ED9;i b&#x1ED9; d&#xE0;i h&#x1EA1;n. Nh&#x1B0;ng &#x111;&#xE2;y v&#x1EAB;n l&#xE0; thi&#x1EC3;u s&#x1ED1; &#x2014; v&#xE0; ph&#x1EA7;n l&#x1EDB;n ng&#xE0;nh v&#x1EAB;n &#x111;ang t&#x1ED1;i &#x1B0;u h&#xF3;a cho qu&#xFD; hi&#x1EC7;n t&#x1EA1;i thay v&#xEC; th&#x1EAD;p k&#x1EF7; ti&#x1EBF;p theo.</p>
<hr>
<h2 id="ph%E1%BA%A7n-v-nh%E1%BB%AFng-g%C3%AC-ch%C6%B0a-%C4%91%C6%B0%E1%BB%A3c-n%C3%B3i-%C4%91%E1%BA%BFn-%C4%91%E1%BB%A7">Ph&#x1EA7;n V: Nh&#x1EEF;ng G&#xEC; Ch&#x1B0;a &#x110;&#x1B0;&#x1EE3;c N&#xF3;i &#x110;&#x1EBF;n &#x110;&#x1EE7;</h2>
<h3 id="trust-gap-%E2%80%94-kho%E1%BA%A3ng-c%C3%A1ch-ni%E1%BB%81m-tin-%C4%91ang-m%E1%BB%9F-r%E1%BB%99ng">Trust Gap &#x2014; Kho&#x1EA3;ng c&#xE1;ch ni&#x1EC1;m tin &#x111;ang m&#x1EDF; r&#x1ED9;ng</h3>
<p>C&#xF3; m&#x1ED9;t m&#xE2;u thu&#x1EAB;n &#x111;&#xE1;ng lo ng&#x1EA1;i: t&#x1EF7; l&#x1EC7; d&#xF9;ng AI t&#x103;ng nh&#x1B0;ng ni&#x1EC1;m tin v&#xE0;o AI l&#x1EA1;i gi&#x1EA3;m. T&#x1EF7; l&#x1EC7; developer c&#xF3; quan &#x111;i&#x1EC3;m t&#xED;ch c&#x1EF1;c v&#x1EDB;i AI &#x111;&#xE3; gi&#x1EA3;m t&#x1EEB; h&#x1A1;n 70% n&#x103;m 2023&#x2013;2024 xu&#x1ED1;ng c&#xF2;n 60% v&#xE0;o 2025. Kho&#x1EA3;ng 46% developer kh&#xF4;ng tin t&#x1B0;&#x1EDF;ng v&#xE0;o k&#x1EBF;t qu&#x1EA3; t&#x1EEB; AI.</p>
<p>&#x110;i&#x1EC1;u n&#xE0;y kh&#xF4;ng &#x111;&#x1ED3;ng ngh&#x129;a v&#x1EDB;i vi&#x1EC7;c h&#x1ECD; ng&#x1EEB;ng d&#xF9;ng AI &#x2014; m&#xE0; l&#xE0; h&#x1ECD; d&#xF9;ng v&#x1EDB;i m&#x1EE9;c &#x111;&#x1ED9; ki&#x1EC3;m tra cao h&#x1A1;n, th&#x1EAD;n tr&#x1ECD;ng h&#x1A1;n. &#x110;&#xE2;y th&#x1EF1;c ra l&#xE0; d&#x1EA5;u hi&#x1EC7;u tr&#x1B0;&#x1EDF;ng th&#xE0;nh c&#x1EE7;a c&#x1EA3; ng&#xE0;nh: t&#x1EEB; &quot;&#x1ED3; &#x1EA1;t h&#xE0;o h&#x1EE9;ng&quot; sang &quot;t&#xED;ch h&#x1EE3;p c&#xF3; ch&#x1ECD;n l&#x1ECD;c&quot;.</p>
<h3 id="deskilling-%E2%80%94-m%E1%BA%A5t-k%E1%BB%B9-n%C4%83ng-n%E1%BB%81n-t%E1%BA%A3ng">Deskilling &#x2014; M&#x1EA5;t k&#x1EF9; n&#x103;ng n&#x1EC1;n t&#x1EA3;ng</h3>
<p>&#x110;&#xE2;y l&#xE0; v&#xF2;ng l&#x1EB7;p nguy hi&#x1EC3;m &#xED;t &#x111;&#x1B0;&#x1EE3;c n&#xF3;i &#x111;&#x1EBF;n: Junior d&#xF9;ng AI &#x2192; kh&#xF4;ng th&#x1EF1;c s&#x1EF1; x&#xE2;y d&#x1EF1;ng &#x111;&#x1B0;&#x1EE3;c n&#x1EC1;n t&#x1EA3;ng &#x2192; khi AI th&#x1EA5;t b&#x1EA1;i, kh&#xF4;ng c&#xF3; g&#xEC; &#x111;&#x1EC3; fallback. Nhi&#x1EC1;u nh&#xE0; nghi&#xEA;n c&#x1EE9;u &#x111;&#xE3; b&#x1EAF;t &#x111;&#x1EA7;u ghi nh&#x1EAD;n hi&#x1EC7;n t&#x1B0;&#x1EE3;ng n&#xE0;y v&#xE0; g&#x1ECD;i n&#xF3; l&#xE0; <em>deskilling</em> &#x2014; m&#x1EA5;t d&#x1EA7;n kh&#x1EA3; n&#x103;ng l&#xE0;m nh&#x1EEF;ng vi&#x1EC7;c c&#x1A1; b&#x1EA3;n v&#xEC; qu&#xE1; quen d&#x1EF1;a v&#xE0;o c&#xF4;ng c&#x1EE5;.</p>
<p>&#x110;&#xE2;y kh&#xF4;ng ph&#x1EA3;i l&#xFD; do &#x111;&#x1EC3; tr&#xE1;nh d&#xF9;ng AI. &#x110;&#xE2;y l&#xE0; l&#xFD; do &#x111;&#x1EC3; d&#xF9;ng AI m&#x1ED9;t c&#xE1;ch <strong>c&#xF3; ch&#x1EE7; &#x111;&#xED;ch</strong> &#x2014; kh&#xF4;ng ph&#x1EA3;i &#x111;&#x1EC3; bypass vi&#x1EC7;c h&#x1ECD;c, m&#xE0; &#x111;&#x1EC3; t&#x103;ng t&#x1ED1;c vi&#x1EC7;c h&#x1ECD;c sau khi b&#x1EA1;n &#x111;&#xE3; hi&#x1EC3;u v&#x1EA5;n &#x111;&#x1EC1;.</p>
<h3 id="2026-l%C3%A0-n%C4%83m-c%E1%BB%A7a-ch%E1%BA%A5t-l%C6%B0%E1%BB%A3ng-kh%C3%B4ng-ph%E1%BA%A3i-t%E1%BB%91c-%C4%91%E1%BB%99">2026 l&#xE0; &quot;N&#x103;m c&#x1EE7;a Ch&#x1EA5;t l&#x1B0;&#x1EE3;ng&quot;, kh&#xF4;ng ph&#x1EA3;i T&#x1ED1;c &#x111;&#x1ED9;</h3>
<p>Ng&#xE0;nh &#x111;ang chuy&#x1EC3;n t&#x1EEB; &quot;2025: N&#x103;m c&#x1EE7;a t&#x1ED1;c &#x111;&#x1ED9; AI&quot; sang &quot;2026: N&#x103;m c&#x1EE7;a ch&#x1EA5;t l&#x1B0;&#x1EE3;ng AI&quot;. Tr&#x1ECD;ng t&#xE2;m &#x111;ang d&#x1ECB;ch chuy&#x1EC3;n m&#x1EA1;nh sang code review, b&#x1EA3;o m&#x1EAD;t, v&#xE0; m&#x1EDF; r&#x1ED9;ng AI v&#xE0;o testing v&#xE0; DevOps.</p>
<p>&#x110;i&#x1EC1;u n&#xE0;y c&#xF3; ngh&#x129;a: k&#x1EF3; v&#x1ECD;ng t&#x1EEB; ph&#xED;a doanh nghi&#x1EC7;p &#x111;ang tr&#x1EDF; n&#xEA;n tinh vi h&#x1A1;n. Kh&#xF4;ng c&#xF2;n ch&#x1EC9; &#x111;&#x1A1;n thu&#x1EA7;n l&#xE0; &quot;d&#xF9;ng AI &#x111;&#x1EC3; code nhanh h&#x1A1;n&quot; &#x2014; m&#xE0; l&#xE0; &quot;d&#xF9;ng AI v&#xE0; v&#x1EAB;n &#x111;&#x1EA3;m b&#x1EA3;o ch&#x1EA5;t l&#x1B0;&#x1EE3;ng&quot;. &#x110;&#xE2;y l&#xE0; chu&#x1EA9;n m&#x1EF1;c m&#x1EDB;i.</p>
<hr>
<h2 id="k%E1%BA%BFt-lu%E1%BA%ADn-ba-l%E1%BB%B1a-ch%E1%BB%8Dn-tr%C6%B0%E1%BB%9Bc-m%E1%BA%B7t-b%E1%BA%A1n">K&#x1EBF;t Lu&#x1EAD;n: Ba L&#x1EF1;a Ch&#x1ECD;n Tr&#x1B0;&#x1EDB;c M&#x1EB7;t B&#x1EA1;n</h2>
<p>Nh&#xEC;n l&#x1EA1;i to&#xE0;n b&#x1ED9; b&#x1EE9;c tranh, c&#xF3; ba nh&#xF3;m ng&#x1B0;&#x1EDD;i &#x111;ang h&#xEC;nh th&#xE0;nh r&#xF5; n&#xE9;t trong ng&#xE0;nh l&#x1EAD;p tr&#xEC;nh:</p>
<p><strong>Nh&#xF3;m 1 &#x2014; Ng&#x1B0;&#x1EDD;i t&#x1EEB; ch&#x1ED1;i th&#x1EF1;c t&#x1EBF;:</strong> Ti&#x1EBF;p t&#x1EE5;c l&#xE0;m theo c&#xE1;ch c&#x169;, b&#xE0;i tr&#x1EEB; AI, ho&#x1EB7;c xem s&#x1EF1; thay &#x111;&#x1ED5;i l&#xE0; t&#x1EA1;m th&#x1EDD;i. H&#x1ECD; &#x111;ang &#x111;&#xFA;ng r&#x1EB1;ng ki&#x1EBF;n th&#x1EE9;c n&#x1EC1;n t&#x1EA3;ng quan tr&#x1ECD;ng. Nh&#x1B0;ng h&#x1ECD; sai khi ngh&#x129; r&#x1EB1;ng th&#x1ECB; tr&#x1B0;&#x1EDD;ng s&#x1EBD; ch&#x1EDD; &#x111;&#x1EE3;i h&#x1ECD;.</p>
<p><strong>Nh&#xF3;m 2 &#x2014; Ng&#x1B0;&#x1EDD;i vibe coding:</strong> D&#xF9;ng AI nh&#x1B0; c&#xE2;y &#x111;&#x169;a th&#x1EA7;n, t&#x1EA1;o ra s&#x1EA3;n ph&#x1EA9;m nhanh, nh&#x1B0;ng kh&#xF4;ng hi&#x1EC3;u m&#xEC;nh &#x111;ang t&#x1EA1;o ra g&#xEC;. H&#x1ECD; s&#x1EBD; &#x1ED5;n cho &#x111;&#x1EBF;n khi h&#x1EC7; th&#x1ED1;ng s&#x1EE5;p &#x111;&#x1ED5; &#x2014; v&#xE0; &#x111;&#xF3; th&#x1B0;&#x1EDD;ng l&#xE0; l&#xFA;c s&#x1EF1; nghi&#x1EC7;p c&#x169;ng s&#x1EE5;p &#x111;&#x1ED5; theo.</p>
<p><strong>Nh&#xF3;m 3 &#x2014; Ng&#x1B0;&#x1EDD;i d&#xF9;ng AI c&#xF3; t&#x1B0; duy:</strong> Hi&#x1EC3;u &#x111;&#x1EE7; s&#xE2;u &#x111;&#x1EC3; ph&#xE1;n x&#xE9;t AI output. C&#xF3; domain knowledge &#x111;&#x1EE7; m&#x1EA1;nh &#x111;&#x1EC3; ch&#x1EC9; &#x111;&#x1EA1;o AI &#x111;&#xFA;ng h&#x1B0;&#x1EDB;ng. C&#xF3; n&#x1EC1;n t&#x1EA3;ng h&#x1EC7; th&#x1ED1;ng &#x111;&#x1EE7; v&#x1EEF;ng &#x111;&#x1EC3; debug khi m&#x1ECD;i th&#x1EE9; v&#x1EE1;. V&#xE0; &#x111;&#x1EE7; t&#xF2; m&#xF2; &#x111;&#x1EC3; li&#xEA;n t&#x1EE5;c h&#x1ECD;c c&#xE1;ch d&#xF9;ng AI t&#x1ED1;t h&#x1A1;n.</p>
<hr>
<p>AI kh&#xF4;ng l&#x1EA5;y vi&#x1EC7;c c&#x1EE7;a b&#x1EA1;n. Nh&#x1B0;ng m&#x1ED9;t ng&#x1B0;&#x1EDD;i thu&#x1ED9;c Nh&#xF3;m 3 &#x2014; m&#x1ED9;t ng&#x1B0;&#x1EDD;i hi&#x1EC3;u ngh&#x1EC1;, t&#x1B0; duy h&#x1EC7; th&#x1ED1;ng, v&#xE0; d&#xF9;ng AI th&#xE0;nh th&#x1EA1;o &#x2014; ng&#x1B0;&#x1EDD;i &#x111;&#xF3; s&#x1EBD; l&#xE0;m &#x111;i&#x1EC1;u &#x111;&#xF3;.</p>
<p>Ranh gi&#x1EDB;i kh&#xF4;ng n&#x1EB1;m &#x1EDF; ch&#x1ED7; b&#x1EA1;n d&#xF9;ng AI hay kh&#xF4;ng. Ranh gi&#x1EDB;i n&#x1EB1;m &#x1EDF; ch&#x1ED7; <strong>b&#x1EA1;n c&#xF3; hi&#x1EC3;u nh&#x1EEF;ng g&#xEC; b&#x1EA1;n &#x111;ang l&#xE0;m hay kh&#xF4;ng</strong>.</p>
<p>C&#xE2;u h&#x1ECF;i ch&#x1EC9; c&#xF2;n l&#xE0;: b&#x1EA1;n mu&#x1ED1;n l&#xE0; ai trong c&#xE2;u chuy&#x1EC7;n n&#xE0;y?</p>
<hr>
<p><em>B&#xE0;i vi&#x1EBF;t t&#x1ED5;ng h&#x1EE3;p v&#xE0; ph&#xE2;n t&#xED;ch t&#x1EEB; d&#x1EEF; li&#x1EC7;u: GitHub Copilot Research 2025, GitClear Research 2025, Stanford Digital Economy Lab, Harvard Business Review, MIT Sloan Review, State of Code 2026, Stack Overflow Developer Survey 2025.</em></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Gemini API Free Tier: The Complete Guide to Maximizing Every Request (Feb 2026)]]></title><description><![CDATA[<!--kg-card-begin: markdown--><blockquote>
<p>Google&apos;s Gemini API Free Tier is surprisingly powerful. With the right fallback strategy, smart use of the Thinking system, and model selection, a single API key can handle serious workloads at zero cost. This guide breaks down everything you need to know.</p>
</blockquote>
<hr>
<h2 id="table-of-contents">Table of Contents</h2>
<ol>
<li><a href="#why">Why Gemini Free</a></li></ol>]]></description><link>https://makexyz.fun/gemini-api-free-tier-the-complete-guide-to-maximizing-every-request-feb-2026/</link><guid isPermaLink="false">699e370b783e931c5ea6e3f9</guid><category><![CDATA[AI]]></category><dc:creator><![CDATA[Tony Phạm]]></dc:creator><pubDate>Tue, 24 Feb 2026 23:44:25 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><blockquote>
<p>Google&apos;s Gemini API Free Tier is surprisingly powerful. With the right fallback strategy, smart use of the Thinking system, and model selection, a single API key can handle serious workloads at zero cost. This guide breaks down everything you need to know.</p>
</blockquote>
<hr>
<h2 id="table-of-contents">Table of Contents</h2>
<ol>
<li><a href="#why">Why Gemini Free Tier Deserves Your Attention</a></li>
<li><a href="#quota">Understanding the Quota System (RPM / TPM / RPD)</a></li>
<li><a href="#text">Group 1 &#x2014; Text Models</a></li>
<li><a href="#image">Group 2 &#x2014; Image Models</a></li>
<li><a href="#voice">Group 3 &#x2014; Voice &amp; Audio Models</a></li>
<li><a href="#thinking">The Thinking System &#x2014; Use It Right or Burn Your Quota</a></li>
<li><a href="#fallback">Fallback Rotation &#x2014; How Many Requests Can You Actually Get?</a></li>
<li><a href="#pricing">Paid Tier Pricing &#x2014; When and What to Upgrade</a></li>
<li><a href="#bestpractices">Best Practices &amp; Deployment Checklist</a></li>
<li><a href="#conclusion">Choosing Your Model by Project Stage</a></li>
</ol>
<hr>
<p><a name="why"></a></p>
<h2 id="1-why-gemini-free-tier-deserves-your-attention">1. Why Gemini Free Tier Deserves Your Attention</h2>
<p>Most developers glance at &quot;Free Tier&quot; limits and assume they&apos;re too restrictive to build anything real. With Gemini, that assumption is wrong.</p>
<p>Google&apos;s Free Tier in 2026 gives you access to <strong>genuinely capable models</strong> &#x2014; not stripped-down demos &#x2014; including models that outperform last year&apos;s Pro-grade offerings on major benchmarks. You get text generation, image synthesis, real-time voice, embeddings, and even robotics preview models, all under one API key.</p>
<p>This matters especially if you are:</p>
<ul>
<li>An <strong>indie developer</strong> prototyping an AI-powered product before committing to costs</li>
<li>A <strong>startup</strong> running multi-agent orchestration pipelines that need to scale gradually</li>
<li>A <strong>researcher</strong> who needs sustained, daily access without billing surprises</li>
<li>A <strong>builder</strong> experimenting with multi-model fallback architectures</li>
</ul>
<p>The key insight: <strong>Free Tier quotas are per model, not per key.</strong> A smart fallback strategy across multiple models can multiply your effective throughput dramatically. This guide shows you exactly how.</p>
<hr>
<p><a name="quota"></a></p>
<h2 id="2-understanding-the-quota-system-rpm-tpm-rpd">2. Understanding the Quota System (RPM / TPM / RPD)</h2>
<p>Before diving into models, you need to understand how limits actually work &#x2014; because the logic is stricter than most people expect.</p>
<h3 id="the-three-dimensions">The Three Dimensions</h3>
<table>
<thead>
<tr>
<th>Dimension</th>
<th>Full Name</th>
<th>What It Measures</th>
<th>Resets</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>RPM</strong></td>
<td>Requests Per Minute</td>
<td>Number of API calls in any 60-second window</td>
<td>Rolling</td>
</tr>
<tr>
<td><strong>TPM</strong></td>
<td>Tokens Per Minute</td>
<td>Total tokens (input + output) in any 60-second window</td>
<td>Rolling</td>
</tr>
<tr>
<td><strong>RPD</strong></td>
<td>Requests Per Day</td>
<td>Total API calls in a calendar day</td>
<td>Daily at 00:00 Pacific Time</td>
</tr>
</tbody>
</table>
<h3 id="the-and-rule-%E2%80%94-the-most-important-thing-to-understand">The AND Rule &#x2014; The Most Important Thing to Understand</h3>
<p>All three limits apply <strong>simultaneously</strong>. Exceeding <strong>any single one</strong> of them triggers a <code>429 Too Many Requests</code> error. This is not an OR condition.</p>
<p>For example, if your model allows 5 RPM / 250K TPM / 20 RPD:</p>
<ul>
<li>Sending 6 requests in one minute &#x2192; <strong>429</strong> (RPM exceeded)</li>
<li>Sending 5 requests but using 300K tokens total in one minute &#x2192; <strong>429</strong> (TPM exceeded)</li>
<li>Sending 21 requests across the day, even slowly &#x2192; <strong>429</strong> (RPD exceeded)</li>
</ul>
<h3 id="practical-implication">Practical Implication</h3>
<p>With an average request size of 8,000 input tokens + 5,000 output tokens = <strong>13,000 tokens per request</strong>, the TPM limit of 250,000 effectively allows up to ~19 requests per minute &#x2014; well above the 5 RPM cap. This means <strong>RPM is typically the binding constraint per minute</strong>, and <strong>RPD is the binding constraint per day</strong>.</p>
<h3 id="one-key-point-on-model-independence">One Key Point on Model Independence</h3>
<p>Each model maintains its own independent quota counters, even when using the same API key. Running 8 requests on Gemini 3 Flash does not affect Gemini 2.5 Flash&apos;s RPM counter at all. This is the foundation of the fallback strategy described later.</p>
<hr>
<p><a name="text"></a></p>
<h2 id="3-group-1-%E2%80%94-text-models">3. Group 1 &#x2014; Text Models</h2>
<p>This is where most of your workload will live. The Free Tier text group includes three tiers of Flash models and five Gemma open models.</p>
<h3 id="free-tier-quota-at-a-glance">Free Tier Quota at a Glance</h3>
<table>
<thead>
<tr>
<th>Model</th>
<th>RPM</th>
<th>TPM</th>
<th>RPD</th>
<th>Category</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Gemini 3 Flash</strong></td>
<td>5</td>
<td>250,000</td>
<td>20</td>
<td>Text-out</td>
</tr>
<tr>
<td><strong>Gemini 2.5 Flash</strong></td>
<td>5</td>
<td>250,000</td>
<td>20</td>
<td>Text-out</td>
</tr>
<tr>
<td><strong>Gemini 2.5 Flash Lite</strong></td>
<td>10</td>
<td>250,000</td>
<td>20</td>
<td>Text-out</td>
</tr>
<tr>
<td><strong>Gemma 3 27B</strong></td>
<td>30</td>
<td>15,000</td>
<td>14,400</td>
<td>Open model</td>
</tr>
<tr>
<td><strong>Gemma 3 12B</strong></td>
<td>30</td>
<td>15,000</td>
<td>14,400</td>
<td>Open model</td>
</tr>
<tr>
<td><strong>Gemma 3 4B</strong></td>
<td>30</td>
<td>15,000</td>
<td>14,400</td>
<td>Open model</td>
</tr>
<tr>
<td><strong>Gemma 3 2B</strong></td>
<td>30</td>
<td>15,000</td>
<td>14,400</td>
<td>Open model</td>
</tr>
<tr>
<td><strong>Gemma 3 1B</strong></td>
<td>30</td>
<td>15,000</td>
<td>14,400</td>
<td>Open model</td>
</tr>
<tr>
<td><strong>Gemini Embedding 1</strong></td>
<td>100</td>
<td>30,000</td>
<td>1,000</td>
<td>Embedding</td>
</tr>
</tbody>
</table>
<blockquote>
<p><strong>Note:</strong> Pro-tier models (Gemini 2.5 Pro, Gemini 3 Pro, Gemini 3.1 Pro) all show 0/0 quotas &#x2014; they are <strong>not available on Free Tier</strong> as of Feb 2026.</p>
</blockquote>
<hr>
<h3 id="model-by-model-breakdown">Model-by-Model Breakdown</h3>
<h4 id="%F0%9F%A5%87-gemini-3-flash-%E2%80%94-best-overall-for-free-tier">&#x1F947; Gemini 3 Flash &#x2014; Best Overall for Free Tier</h4>
<p>Gemini 3 Flash is the flagship Free Tier model as of early 2026. Google positions it as achieving &quot;Pro-grade reasoning at Flash speed,&quot; and independent benchmarks confirm it outperforms Gemini 2.5 Pro on 18 out of 20 standard evaluations.</p>
<p><strong>Best for:</strong></p>
<ul>
<li>Complex multi-step reasoning and planning</li>
<li>Agentic coding tasks (function calling, tool use)</li>
<li>Data extraction from unstructured documents (contracts, financial reports, handwriting)</li>
<li>Root-level orchestration decisions &#x2014; acting as the &quot;brain&quot; of a multi-agent system</li>
<li>Final synthesis when merging outputs from multiple agents</li>
</ul>
<p><strong>Limitations:</strong> Only 20 RPD means you exhaust the daily budget quickly under heavy load. Use it where it matters most.</p>
<hr>
<h4 id="%F0%9F%A5%88-gemini-25-flash-%E2%80%94-best-price-performance-balance">&#x1F948; Gemini 2.5 Flash &#x2014; Best Price-Performance Balance</h4>
<p>A well-rounded model that handles the majority of real-world tasks reliably. Slightly behind Gemini 3 Flash on complex reasoning benchmarks, but still significantly stronger than older Flash versions.</p>
<p><strong>Best for:</strong></p>
<ul>
<li>Large-scale text processing and summarization</li>
<li>Analysis tasks requiring moderate reasoning depth</li>
<li>Agentic workflows with function calling and grounding</li>
<li>Primary worker agent in parallel pipelines</li>
<li>Intermediate summary steps between heavy stages</li>
</ul>
<p><strong>Key advantage:</strong> Its quota is identical to Gemini 3 Flash (5 RPM / 250K TPM / 20 RPD), making it an ideal fallback without sacrificing much quality.</p>
<hr>
<h4 id="%F0%9F%A5%89-gemini-25-flash-lite-%E2%80%94-best-for-high-volume-light-tasks">&#x1F949; Gemini 2.5 Flash Lite &#x2014; Best for High-Volume Light Tasks</h4>
<p>The lightest of the Flash family. Designed for low-latency, high-throughput scenarios. Notably, it offers <strong>10 RPM</strong> &#x2014; double the other Flash models &#x2014; making it capable of sustaining heavier burst loads.</p>
<p><strong>Best for:</strong></p>
<ul>
<li>Classification and routing (yes/no decisions, category tagging)</li>
<li>Translation and simple text rewriting</li>
<li>Filtering and extraction from structured data</li>
<li>Any step in a pipeline where correctness is straightforward and speed matters</li>
<li>High-frequency micro-tasks (hundreds of calls per hour)</li>
</ul>
<hr>
<h4 id="gemma-3-series-27b-12b-4b-2b-1b-%E2%80%94-the-open-model-safety-net">Gemma 3 Series (27B / 12B / 4B / 2B / 1B) &#x2014; The Open Model Safety Net</h4>
<p>The Gemma family is Google&apos;s open-weight model lineup. Through the API, they carry generous RPM limits (30 RPM) but much lower TPM (15,000 per model) and much lower per-request token capacity. With 13,000 tokens per request, each Gemma model can only sustain about <strong>1.15 requests per minute</strong> before hitting TPM &#x2014; far below its RPM ceiling.</p>
<p>However, the RPD is enormous (14,400/day per model), making them excellent as <strong>sustained overnight fallbacks</strong> for lighter tasks.</p>
<p><strong>Best for:</strong></p>
<ul>
<li>Simple classification and extraction tasks that fit within lower token limits</li>
<li>Privacy-sensitive workloads (Gemma can be self-hosted via Ollama or LM Studio at no cloud cost)</li>
<li>Edge or on-device deployment (smaller variants)</li>
<li>Fallback layer when all Flash quotas are exhausted</li>
</ul>
<p><strong>On self-hosting:</strong> If you run Gemma 3 27B locally, it costs nothing per token. For private data pipelines or compliance-sensitive workloads, this is a compelling option that integrates naturally into a fallback chain.</p>
<hr>
<h4 id="gemini-embedding-1-%E2%80%94-the-rag-foundation">Gemini Embedding 1 &#x2014; The RAG Foundation</h4>
<p>Not a generative model, but arguably the most important model in a knowledge-intensive system. It converts text into high-dimensional vectors for semantic search, clustering, and retrieval-augmented generation (RAG).</p>
<p><strong>Quota:</strong> 100 RPM / 30,000 TPM / 1,000 RPD</p>
<p><strong>Best for:</strong></p>
<ul>
<li>Building and querying vector databases (Supabase, Pinecone, pgvector)</li>
<li>Powering the retrieval stage before any generative agent call</li>
<li>Semantic deduplication of large document sets</li>
<li>Cross-lingual similarity matching</li>
</ul>
<p>In a multi-agent system, Embedding 1 should run <strong>before every other agent call</strong> &#x2014; it feeds the relevant context that makes downstream generation accurate.</p>
<hr>
<h3 id="recommended-task-mapping-text-models">Recommended Task Mapping (Text Models)</h3>
<table>
<thead>
<tr>
<th>Task Type</th>
<th>Recommended Model</th>
<th>Thinking Config</th>
</tr>
</thead>
<tbody>
<tr>
<td>Root planner / orchestrator</td>
<td>Gemini 3 Flash</td>
<td>High</td>
</tr>
<tr>
<td>Complex coding / deep analysis</td>
<td>Gemini 3 Flash</td>
<td>High</td>
</tr>
<tr>
<td>Content generation (medium complexity)</td>
<td>Gemini 2.5 Flash</td>
<td>Medium</td>
</tr>
<tr>
<td>Summarization / rewriting</td>
<td>Gemini 2.5 Flash</td>
<td>Medium</td>
</tr>
<tr>
<td>Classification / routing / filtering</td>
<td>Gemini 2.5 Flash Lite</td>
<td>None (0)</td>
</tr>
<tr>
<td>Translation / simple extraction</td>
<td>Gemini 2.5 Flash Lite</td>
<td>None (0)</td>
</tr>
<tr>
<td>Vector retrieval (RAG)</td>
<td>Gemini Embedding 1</td>
<td>N/A</td>
</tr>
<tr>
<td>Privacy-sensitive / local tasks</td>
<td>Gemma 3 27B (self-hosted)</td>
<td>N/A</td>
</tr>
</tbody>
</table>
<hr>
<p><a name="image"></a></p>
<h2 id="4-group-2-%E2%80%94-image-models">4. Group 2 &#x2014; Image Models</h2>
<p>The Free Tier includes three Imagen 4 variants, all with the same daily limit of <strong>25 images per day (RPD)</strong>. RPM and TPM do not apply to image generation.</p>
<table>
<thead>
<tr>
<th>Model</th>
<th>RPD</th>
<th>Best For</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Imagen 4 Ultra Generate</strong></td>
<td>25</td>
<td>Maximum photorealism, fine detail, commercial-grade output</td>
</tr>
<tr>
<td><strong>Imagen 4 Generate</strong></td>
<td>25</td>
<td>Balanced quality and generation speed</td>
</tr>
<tr>
<td><strong>Imagen 4 Fast Generate</strong></td>
<td>25</td>
<td>Fastest generation, good for iteration and prototyping</td>
</tr>
</tbody>
</table>
<h3 id="choosing-between-the-three">Choosing Between the Three</h3>
<p>All three share the same RPD bucket per model, so they do <strong>not</strong> share a combined 75-image pool &#x2014; each model has its own 25/day. A fallback strategy across all three gives you up to <strong>75 images per day</strong> from a single API key.</p>
<p><strong>Use Ultra</strong> when the image is the final output seen by end users or clients. <strong>Use Fast</strong> when you&apos;re iterating on prompts or generating thumbnails for internal use. <strong>Use Standard</strong> as the default when neither extreme is necessary.</p>
<hr>
<p><a name="voice"></a></p>
<h2 id="5-group-3-%E2%80%94-voice-audio-models">5. Group 3 &#x2014; Voice &amp; Audio Models</h2>
<p>Two Free Tier models cover voice use cases, and they serve very different purposes.</p>
<table>
<thead>
<tr>
<th>Model</th>
<th>RPM</th>
<th>TPM</th>
<th>RPD</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Gemini 2.5 Flash Native Audio Dialog</strong></td>
<td>Unlimited</td>
<td>1,000,000</td>
<td>Unlimited</td>
<td>Live API (real-time)</td>
</tr>
<tr>
<td><strong>Gemini 2.5 Flash TTS</strong></td>
<td>3</td>
<td>10,000</td>
<td>10</td>
<td>Text-to-Speech</td>
</tr>
</tbody>
</table>
<h3 id="gemini-25-flash-native-audio-dialog">Gemini 2.5 Flash Native Audio Dialog</h3>
<p>This is the standout entry in the Voice group. With <strong>unlimited RPM and RPD</strong>, it is the only Free Tier model without a hard daily cap on requests. The 1M TPM limit is generous for conversational use cases.</p>
<p>It operates through the <strong>Live API</strong>, supporting real-time, bidirectional voice conversations &#x2014; the model can listen and respond in a streaming, human-like dialogue rather than processing fixed text inputs.</p>
<p><strong>Best for:</strong></p>
<ul>
<li>Real-time voice assistants and customer-facing chatbots</li>
<li>Interactive voice interfaces in applications</li>
<li>Live coaching or tutoring experiences</li>
<li>Any use case requiring low-latency, back-and-forth audio interaction</li>
</ul>
<h3 id="gemini-25-flash-tts">Gemini 2.5 Flash TTS</h3>
<p>A traditional text-to-speech model. You provide text, it returns synthesized speech. The Free Tier is modest (10 RPD), making it suitable for light usage &#x2014; narrating generated content, building audio previews, or accessibility features.</p>
<hr>
<p><a name="thinking"></a></p>
<h2 id="6-the-thinking-system-%E2%80%94-use-it-right-or-burn-your-quota">6. The Thinking System &#x2014; Use It Right or Burn Your Quota</h2>
<p>Gemini&apos;s &quot;Thinking&quot; feature allows the model to perform internal chain-of-thought reasoning before generating its final response. It significantly improves accuracy on complex tasks &#x2014; but consumes additional tokens and increases latency. Defaulting to maximum thinking on every call is one of the most common ways to unnecessarily exhaust Free Tier quota.</p>
<h3 id="two-configuration-apis">Two Configuration APIs</h3>
<p><strong>Gemini 3 Flash</strong> uses <code>thinkingLevel</code>:</p>
<table>
<thead>
<tr>
<th>Level</th>
<th>When to Use</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>&quot;minimal&quot;</code></td>
<td>Classification, extraction, translation, simple routing</td>
</tr>
<tr>
<td><code>&quot;low&quot;</code></td>
<td>Instruction following, summarization, high-throughput tasks</td>
</tr>
<tr>
<td><code>&quot;medium&quot;</code></td>
<td>Analysis, moderate coding, data processing (recommended default)</td>
</tr>
<tr>
<td><code>&quot;high&quot;</code></td>
<td>Multi-step planning, agentic coding, deep analysis, orchestration</td>
</tr>
</tbody>
</table>
<p><strong>Gemini 2.5 Flash / Flash Lite</strong> uses <code>thinkingBudget</code> (token count):</p>
<table>
<thead>
<tr>
<th>Budget</th>
<th>Equivalent Level</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>0</code></td>
<td>Minimal &#x2014; no thinking</td>
</tr>
<tr>
<td><code>512&#x2013;2048</code></td>
<td>Low to Medium</td>
</tr>
<tr>
<td><code>4096&#x2013;8192</code></td>
<td>High</td>
</tr>
</tbody>
</table>
<blockquote>
<p>&#x26A0;&#xFE0F; <strong>Important:</strong> You cannot use <code>thinkingLevel</code> and <code>thinkingBudget</code> simultaneously &#x2014; it will return a 400 error. Use the correct parameter for the model series.</p>
</blockquote>
<blockquote>
<p>&#x26A0;&#xFE0F; <strong>Gemini 3 Flash defaults to <code>high</code></strong> &#x2014; meaning if you don&apos;t set anything, every call uses maximum thinking. This is often unnecessary and wasteful for simple tasks.</p>
</blockquote>
<h3 id="the-8020-rule-for-thinking">The 80/20 Rule for Thinking</h3>
<p>In a typical multi-agent pipeline, <strong>80% of your calls are routine</strong> &#x2014; classification, extraction, translation, formatting. These need <code>minimal</code> or <code>0</code>. Only the remaining 20% (planners, synthesizers, complex reasoners) justify <code>high</code>.</p>
<p>Applying this rule consistently can reduce total token consumption by <strong>40&#x2013;70%</strong> across a pipeline, directly extending how long your Free Tier quota lasts each day.</p>
<h3 id="thinking-in-a-multi-agent-system">Thinking in a Multi-Agent System</h3>
<table>
<thead>
<tr>
<th>Agent Role</th>
<th>Model</th>
<th>Thinking Config</th>
</tr>
</thead>
<tbody>
<tr>
<td>Root Planner / Orchestrator</td>
<td>Gemini 3 Flash</td>
<td><code>high</code></td>
</tr>
<tr>
<td>Heavy Reasoning / Coding Agent</td>
<td>Gemini 3 Flash</td>
<td><code>high</code></td>
</tr>
<tr>
<td>Content Generator / Analyst</td>
<td>Gemini 2.5 Flash</td>
<td><code>budget: 2048</code></td>
</tr>
<tr>
<td>Summarizer / Rewriter</td>
<td>Gemini 2.5 Flash</td>
<td><code>medium</code></td>
</tr>
<tr>
<td>Classifier / Filter / Router</td>
<td>Gemini 2.5 Flash Lite</td>
<td><code>budget: 0</code></td>
</tr>
<tr>
<td>Final Synthesizer</td>
<td>Gemini 3 Flash</td>
<td><code>high</code></td>
</tr>
</tbody>
</table>
<h3 id="code-example-python-google-genai-sdk-2026">Code Example (Python, Google GenAI SDK 2026)</h3>
<pre><code class="language-python">import google.generativeai as genai

genai.configure(api_key=&quot;YOUR_API_KEY&quot;)

model = genai.GenerativeModel(&quot;gemini-3-flash&quot;)

response = model.generate_content(
    contents=&quot;Analyze the following business proposal and identify key risks...&quot;,
    generation_config=genai.GenerationConfig(
        thinking_config=genai.ThinkingConfig(
            thinking_level=&quot;high&quot;,   # &quot;minimal&quot; | &quot;low&quot; | &quot;medium&quot; | &quot;high&quot;
            include_thoughts=True    # Optional: expose reasoning trace for debugging
        )
    )
)

# Access the internal reasoning trace (useful for debugging agent decisions)
if hasattr(response, &apos;thoughts&apos;):
    print(&quot;Reasoning trace:&quot;, response.thoughts)

print(&quot;Final answer:&quot;, response.text)
</code></pre>
<hr>
<p><a name="fallback"></a></p>
<h2 id="7-fallback-rotation-%E2%80%94-how-many-requests-can-you-actually-get">7. Fallback Rotation &#x2014; How Many Requests Can You Actually Get?</h2>
<p>This is the question that determines whether Free Tier is viable for your workload. The math is straightforward once you understand that quotas are independent per model.</p>
<h3 id="setup-baseline-assumptions">Setup: Baseline Assumptions</h3>
<ul>
<li>Input per request: <strong>8,000 tokens</strong></li>
<li>Output per request: <strong>5,000 tokens</strong></li>
<li>Total per request: <strong>13,000 tokens</strong></li>
<li>Single API key, fallback chain: Gemini 3 Flash &#x2192; Gemini 2.5 Flash &#x2192; Gemini 2.5 Flash Lite &#x2192; Gemma 3 27B &#x2192; Gemma 3 12B &#x2192; ...</li>
</ul>
<h3 id="flash-family-the-primary-workhorse">Flash Family (the primary workhorse)</h3>
<table>
<thead>
<tr>
<th>Model</th>
<th>RPD</th>
<th>Requests at 13K tokens</th>
</tr>
</thead>
<tbody>
<tr>
<td>Gemini 3 Flash</td>
<td>20</td>
<td>20</td>
</tr>
<tr>
<td>Gemini 2.5 Flash</td>
<td>20</td>
<td>20</td>
</tr>
<tr>
<td>Gemini 2.5 Flash Lite</td>
<td>20</td>
<td>20</td>
</tr>
<tr>
<td><strong>Flash Total</strong></td>
<td><strong>60</strong></td>
<td><strong>60</strong></td>
</tr>
</tbody>
</table>
<blockquote>
<p>Note: TPM (250K/model) allows ~19 requests per minute per model, well above the RPM cap of 5&#x2013;10. RPM is the per-minute bottleneck; RPD is the daily ceiling.</p>
</blockquote>
<h3 id="gemma-family-supplementary-lower-quality">Gemma Family (supplementary, lower quality)</h3>
<p>Each Gemma model has <strong>14,400 RPD</strong> but only 15,000 TPM. At 13,000 tokens per request, each Gemma model supports only <strong>~1.15 requests per minute</strong> before hitting TPM. Across 5 models in parallel, that&apos;s roughly <strong>5&#x2013;6 RPM total</strong> for the Gemma group.</p>
<h3 id="throughput-summary">Throughput Summary</h3>
<table>
<thead>
<tr>
<th>Scenario</th>
<th>Requests / Hour</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Sustainable (24h continuous)</strong></td>
<td>~2&#x2013;3</td>
<td>60 RPD Flash &#xF7; 24h = 2.5 avg. Preserves quota for the full day.</td>
</tr>
<tr>
<td><strong>Burst mode (drain Flash fast)</strong></td>
<td>~45&#x2013;55</td>
<td>Exhaust ~60 Flash RPD in 30&#x2013;45 minutes. Then Gemma continues at lower quality.</td>
</tr>
<tr>
<td><strong>Full fallback (Flash + all Gemma)</strong></td>
<td>~60&#x2013;70</td>
<td>Combined throughput with quality degradation on Gemma requests.</td>
</tr>
</tbody>
</table>
<h3 id="recommended-fallback-chain">Recommended Fallback Chain</h3>
<pre><code>Gemini 3 Flash (primary)
    &#x2193; [quota exhausted or 429]
Gemini 2.5 Flash
    &#x2193; [quota exhausted or 429]
Gemini 2.5 Flash Lite
    &#x2193; [quota exhausted or 429]
Gemma 3 27B (via API or self-hosted)
    &#x2193; [quota exhausted]
Gemma 3 12B &#x2192; Gemma 3 4B &#x2192; Gemma 3 2B &#x2192; Gemma 3 1B
</code></pre>
<h3 id="choosing-your-mode">Choosing Your Mode</h3>
<p><strong>Burst mode</strong> is ideal when you have a defined batch to process (e.g., analyzing 50 documents) and can tolerate the daily quota being spent in one session.</p>
<p><strong>Sustainable mode</strong> is ideal for continuous applications (chatbots, live pipelines) that need to remain available throughout the day without interruption.</p>
<hr>
<p><a name="pricing"></a></p>
<h2 id="8-paid-tier-pricing-%E2%80%94-when-and-what-to-upgrade">8. Paid Tier Pricing &#x2014; When and What to Upgrade</h2>
<p>When your workload consistently exceeds Free Tier limits, upgrading specific models to pay-as-you-go is more cost-effective than upgrading everything. Here is the current pricing landscape (context &#x2264; 200K tokens, Feb 2026):</p>
<h3 id="cost-per-model-pay-as-you-go">Cost per Model (Pay-as-you-go)</h3>
<table>
<thead>
<tr>
<th>Model</th>
<th>Input (per 1M tokens)</th>
<th>Output (per 1M tokens)</th>
<th>Cost per Request (8K in + 5K out)</th>
<th>Cost per 1,000 Requests</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Gemini 2.5 Flash Lite</strong></td>
<td>$0.10</td>
<td>$0.40</td>
<td>$0.0028</td>
<td>$2.80</td>
</tr>
<tr>
<td><strong>Gemini 2.5 Flash</strong></td>
<td>$0.30</td>
<td>$2.50</td>
<td>$0.0149</td>
<td>$14.90</td>
</tr>
<tr>
<td><strong>Gemini 3 Flash</strong></td>
<td>$0.50</td>
<td>$3.00</td>
<td>$0.0190</td>
<td>$19.00</td>
</tr>
<tr>
<td><strong>Gemini 2.5 Pro</strong></td>
<td>$1.25</td>
<td>$10.00</td>
<td>$0.0600</td>
<td>$60.00</td>
</tr>
<tr>
<td><strong>Gemini 3 Pro</strong></td>
<td>$2.00</td>
<td>$12.00</td>
<td>$0.0760</td>
<td>$76.00</td>
</tr>
</tbody>
</table>
<h3 id="key-observations">Key Observations</h3>
<p><strong>Flash Lite is extremely affordable.</strong> At $2.80 per 1,000 requests, it&apos;s viable for high-volume classification and extraction tasks even at significant scale.</p>
<p><strong>Gemini 2.5 Flash offers the best value for production workloads.</strong> At $14.90 per 1,000 requests, it handles the vast majority of real-world tasks well.</p>
<p><strong>Gemini 3 Flash is worth it for reasoning-heavy tasks.</strong> The ~28% premium over 2.5 Flash often pays back in reduced error rates and fewer retries on complex operations.</p>
<p><strong>Pro models (2.5 Pro, 3 Pro) should be reserved for genuinely hard tasks.</strong> The 4&#x2013;5x cost jump over Flash models is only justified when accuracy on extremely complex tasks is critical.</p>
<h3 id="cost-saving-strategies">Cost-Saving Strategies</h3>
<p><strong>Context Caching</strong> &#x2014; If your system prompt or document context is repeated across many calls (common in pipelines), enabling context caching can reduce input token costs by 80&#x2013;90%.</p>
<p><strong>Batch API</strong> &#x2014; For non-real-time workloads (overnight document processing, bulk analysis), the Batch API typically reduces costs by ~50%.</p>
<p><strong>Mixed model strategy</strong> &#x2014; Running 80% of requests on Flash Lite and 20% on Gemini 3 Flash often achieves the quality of a full Flash deployment at roughly half the cost.</p>
<p><strong>Self-hosted Gemma</strong> &#x2014; For privacy-sensitive workloads or pure cost elimination on non-critical tasks, Gemma 3 27B via Ollama or LM Studio is $0 per token.</p>
<hr>
<p><a name="bestpractices"></a></p>
<h2 id="9-best-practices-deployment-checklist">9. Best Practices &amp; Deployment Checklist</h2>
<h3 id="before-you-deploy">Before You Deploy</h3>
<ul>
<li>[ ] Map each stage in your pipeline to a model based on task complexity</li>
<li>[ ] Set <code>thinkingLevel</code> or <code>thinkingBudget</code> explicitly for every model call (never rely on defaults)</li>
<li>[ ] Implement exponential backoff with jitter for all 429 responses</li>
<li>[ ] Build a quota tracker that counts RPM, TPM, and RPD per model in memory</li>
<li>[ ] Establish clear fallback priority ordering in your model router</li>
<li>[ ] Decide: burst mode or sustainable mode based on your traffic pattern</li>
</ul>
<h3 id="during-development">During Development</h3>
<ul>
<li>[ ] Use <code>include_thoughts: true</code> during debugging to inspect model reasoning &#x2014; disable it in production to save tokens</li>
<li>[ ] Test your fallback chain end-to-end with artificial 429 simulation before going live</li>
<li>[ ] Profile actual token usage per pipeline stage &#x2014; your estimate is likely off by &#xB1;30%</li>
<li>[ ] Confirm that context + prompt + output fits within context limits before scaling</li>
</ul>
<h3 id="in-production">In Production</h3>
<ul>
<li>[ ] Log RPD consumption per model daily and alert at 80% utilization</li>
<li>[ ] Set up automatic fallback so that quota exhaustion is invisible to end users</li>
<li>[ ] For image generation, distribute across all three Imagen 4 variants to triple daily output</li>
<li>[ ] Use Gemini Embedding 1 with a persistent vector database &#x2014; avoid re-embedding the same content repeatedly (it eats RPD fast)</li>
<li>[ ] Reset expectations: RPD resets at <strong>00:00 Pacific Time</strong> daily, not at midnight in your local timezone</li>
</ul>
<h3 id="five-habits-that-save-the-most-quota">Five Habits That Save the Most Quota</h3>
<p><strong>1. Default to minimal thinking.</strong> Unless a task genuinely requires multi-step reasoning, <code>minimal</code> or <code>budget: 0</code> is always the right choice. Add thinking only when you observe quality failures.</p>
<p><strong>2. Use embedding caching aggressively.</strong> Store embeddings in a vector database. Never re-embed content you&apos;ve already processed. At 1,000 RPD, Embedding 1 runs out faster than you expect.</p>
<p><strong>3. Keep prompts tight.</strong> Every 1,000 extra tokens in your system prompt costs you across every single call. Compact, precise prompts preserve TPM for actual content.</p>
<p><strong>4. Let Flash Lite absorb your high-frequency tasks.</strong> Classification, routing, filtering, and extraction rarely require a powerful model. Shifting these to Flash Lite protects your Flash quota for work that actually needs it.</p>
<p><strong>5. Build in graceful degradation.</strong> When all Flash models are exhausted, your system should continue functioning (at lower quality) using Gemma rather than failing hard. Users shouldn&apos;t see errors &#x2014; they should see slightly simpler responses.</p>
<hr>
<p><a name="conclusion"></a></p>
<h2 id="10-choosing-your-model-by-project-stage">10. Choosing Your Model by Project Stage</h2>
<p>If you&apos;re unsure where to start, here is a simple decision framework based on where your project currently is.</p>
<h3 id="early-prototyping">Early Prototyping</h3>
<p>Use <strong>Gemini 3 Flash</strong> for everything. Don&apos;t optimize yet &#x2014; understand what your pipeline actually needs before deciding where to cut costs. The 20 RPD limit is enough for initial testing.</p>
<h3 id="active-development">Active Development</h3>
<p>Split your workload: <strong>Gemini 3 Flash</strong> for complex stages, <strong>Gemini 2.5 Flash</strong> for standard generation, <strong>Gemini 2.5 Flash Lite</strong> for routine tasks. Add <strong>Gemini Embedding 1</strong> once you&apos;re building any knowledge retrieval layer.</p>
<h3 id="pre-launch-scaling">Pre-Launch / Scaling</h3>
<p>Implement the full fallback chain. Profile token usage per stage precisely. Start testing Context Caching on repeated prompts. Evaluate whether Gemma 3 self-hosting makes sense for your heaviest, lowest-criticality tasks.</p>
<h3 id="production">Production</h3>
<p>Move to Pay-as-you-go on models that consistently hit RPD limits. Keep Free Tier as your burst buffer and fallback. At this point, the mixed model strategy (mostly Flash Lite + selective Flash/3 Flash) is the cost-efficient default.</p>
<hr>
<h2 id="final-thoughts">Final Thoughts</h2>
<p>Gemini&apos;s Free Tier in 2026 is not a marketing tool &#x2014; it&apos;s a functional development and production resource if you use it strategically. The three things that matter most are:</p>
<ol>
<li><strong>Know your quota constraints cold.</strong> RPM, TPM, and RPD all apply simultaneously. Plan around RPD as your primary constraint.</li>
<li><strong>Match model capability to task complexity.</strong> Routing a simple classification call through Gemini 3 Flash with high thinking is pure waste.</li>
<li><strong>Build fallback from the start.</strong> Quota exhaustion is not an edge case &#x2014; it&apos;s a predictable event. Systems that handle it gracefully perform better than systems that assume quota will never run out.</li>
</ol>
<p>Done right, a single Free Tier key can support meaningful production workloads, especially in architectures that distribute work intelligently across the model family. Start free, measure what you actually need, and upgrade only what earns its cost.</p>
<hr>
<p><em>Data sourced from Google AI Studio Rate Limits and Google DeepMind documentation (February 2026). Quotas and pricing are subject to change &#x2014; always verify current limits at <a href="https://aistudio.google.com/app/rate-limits">https://aistudio.google.com/app/rate-limits</a> and <a href="https://ai.google.dev/gemini-api/docs/pricing">https://ai.google.dev/gemini-api/docs/pricing</a>.</em></p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Chiến Lược Gọi Vốn Đột Phá Trên Kickstarter Và Mô Hình Thương Mại Hóa Phần Mềm Mã Nguồn Mở]]></title><description><![CDATA[Báo cáo cung cấp phương pháp luận chi tiết, bóc tách cấu trúc của các chiến dịch gọi vốn thành công, các rủi ro pháp lý tiềm ẩn và những mô hình kinh doanh chiến lược đang chi phối kỷ nguyên mới của phần mềm mã nguồn mở.]]></description><link>https://makexyz.fun/chien-luoc-goi-von-dot-pha-tren-kickstarter-va-mo-hinh-thuong-mai-hoa-phan-mem-ma-nguon-mo/</link><guid isPermaLink="false">699be189a83e9f7b01cce3b1</guid><dc:creator><![CDATA[Tony Phạm]]></dc:creator><pubDate>Mon, 23 Feb 2026 05:17:17 GMT</pubDate><content:encoded><![CDATA[<p>S&#x1EF1; giao thoa gi&#x1EEF;a n&#x1EC1;n kinh t&#x1EBF; s&#xE1;ng t&#x1EA1;o to&#xE0;n c&#x1EA7;u v&#xE0; h&#x1EC7; sinh th&#xE1;i ph&#x1EA7;n m&#x1EC1;m m&#xE3; ngu&#x1ED3;n m&#x1EDF; (Open Source Software - OSS) &#x111;&#xE3; &#x111;&#x1ECB;nh h&#xEC;nh l&#x1EA1;i c&#xE1;c ranh gi&#x1EDB;i c&#x1EE7;a vi&#x1EC7;c huy &#x111;&#x1ED9;ng v&#x1ED1;n, ph&#xE1;t tri&#x1EC3;n s&#x1EA3;n ph&#x1EA9;m v&#xE0; th&#x1B0;&#x1A1;ng m&#x1EA1;i h&#xF3;a c&#xF4;ng ngh&#x1EC7;. Tuy nhi&#xEA;n, vi&#x1EC7;c chuy&#x1EC3;n h&#xF3;a m&#x1ED9;t &#xFD; t&#x1B0;&#x1EDF;ng &#x111;&#x1ED9;t ph&#xE1; th&#xE0;nh m&#x1ED9;t chi&#x1EBF;n d&#x1ECB;ch g&#xE2;y qu&#x1EF9; th&#xE0;nh c&#xF4;ng tr&#xEA;n c&#xE1;c n&#x1EC1;n t&#x1EA3;ng c&#x1ED9;ng &#x111;&#x1ED3;ng nh&#x1B0; Kickstarter, c&#x169;ng nh&#x1B0; vi&#x1EC7;c thi&#x1EBF;t l&#x1EAD;p m&#x1ED9;t lu&#x1ED3;ng doanh thu b&#x1EC1;n v&#x1EEF;ng t&#x1EEB; c&#xE1;c d&#x1EF1; &#xE1;n m&#xE3; ngu&#x1ED3;n m&#x1EDF;, &#x111;&#xF2;i h&#x1ECF;i s&#x1EF1; am hi&#x1EC3;u s&#xE2;u s&#x1EAF;c v&#x1EC1; k&#x1EF9; thu&#x1EAD;t n&#x1EC1;n t&#x1EA3;ng, c&#x1A1; s&#x1EDF; h&#x1EA1; t&#x1EA7;ng ph&#xE1;p l&#xFD; xuy&#xEA;n bi&#xEA;n gi&#x1EDB;i, v&#xE0; t&#xE2;m l&#xFD; h&#x1ECD;c h&#xE0;nh vi c&#x1EE7;a ng&#x1B0;&#x1EDD;i ti&#xEA;u d&#xF9;ng. B&#xE1;o c&#xE1;o ph&#xE2;n t&#xED;ch to&#xE0;n di&#x1EC7;n n&#xE0;y &#x111;&#x1B0;&#x1EE3;c thi&#x1EBF;t k&#x1EBF; nh&#x1EB1;m cung c&#x1EA5;p m&#x1ED9;t ph&#x1B0;&#x1A1;ng ph&#xE1;p lu&#x1EAD;n chi ti&#x1EBF;t, b&#xF3;c t&#xE1;ch c&#x1EA5;u tr&#xFA;c c&#x1EE7;a c&#xE1;c chi&#x1EBF;n d&#x1ECB;ch g&#x1ECD;i v&#x1ED1;n th&#xE0;nh c&#xF4;ng, c&#xE1;c r&#x1EE7;i ro ph&#xE1;p l&#xFD; ti&#x1EC1;m &#x1EA9;n &#x111;&#x1ED1;i v&#x1EDB;i c&#xE1;c nh&#xE0; s&#xE1;ng l&#x1EAD;p qu&#x1ED1;c t&#x1EBF;, v&#xE0; nh&#x1EEF;ng m&#xF4; h&#xEC;nh kinh doanh chi&#x1EBF;n l&#x1B0;&#x1EE3;c &#x111;ang chi ph&#x1ED1;i k&#x1EF7; nguy&#xEA;n m&#x1EDB;i c&#x1EE7;a ph&#x1EA7;n m&#x1EC1;m m&#xE3; ngu&#x1ED3;n m&#x1EDF;.</p><h2 id="ph%E1%BA%A7n-i-ki%E1%BA%BFn-tr%C3%BAc-chi%E1%BA%BFn-l%C6%B0%E1%BB%A3c-v%C3%A0-khung-ph%C3%A1p-l%C3%BD-cho-chi%E1%BA%BFn-d%E1%BB%8Bch-kickstarter-to%C3%A0n-c%E1%BA%A7u">Ph&#x1EA7;n I: Ki&#x1EBF;n Tr&#xFA;c Chi&#x1EBF;n L&#x1B0;&#x1EE3;c V&#xE0; Khung Ph&#xE1;p L&#xFD; Cho Chi&#x1EBF;n D&#x1ECB;ch Kickstarter To&#xE0;n C&#x1EA7;u</h2><p>M&#xF4; h&#xEC;nh t&#xE0;i tr&#x1EE3; &quot;t&#x1EA5;t c&#x1EA3; ho&#x1EB7;c kh&#xF4;ng c&#xF3; g&#xEC;&quot; (all-or-nothing) c&#x1EE7;a Kickstarter t&#x1EA1;o ra m&#x1ED9;t &#xE1;p l&#x1EF1;c kh&#x1ED5;ng l&#x1ED3; nh&#x1B0;ng &#x111;&#x1ED3;ng th&#x1EDD;i c&#x169;ng l&#xE0; ch&#x1EA5;t x&#xFA;c t&#xE1;c cho s&#x1EF1; b&#xF9;ng n&#x1ED5; c&#x1EE7;a c&#xE1;c chi&#x1EBF;n d&#x1ECB;ch g&#xE2;y qu&#x1EF9;. Kh&#xE1;c v&#x1EDB;i vi&#x1EC7;c ti&#x1EBF;p c&#x1EAD;n v&#x1ED1;n &#x111;&#x1EA7;u t&#x1B0; m&#x1EA1;o hi&#x1EC3;m truy&#x1EC1;n th&#x1ED1;ng, n&#x1A1;i c&#xE1;c nh&#xE0; s&#xE1;ng l&#x1EAD;p ph&#x1EA3;i ch&#x1EE9;ng minh &#x111;&#x1ECB;nh gi&#xE1; doanh nghi&#x1EC7;p tr&#x1B0;&#x1EDB;c c&#xE1;c h&#x1ED9;i &#x111;&#x1ED3;ng &#x111;&#x1EA7;u t&#x1B0;, Kickstarter d&#xE2;n ch&#x1EE7; h&#xF3;a qu&#xE1; tr&#xEC;nh c&#x1EA5;p v&#x1ED1;n b&#x1EB1;ng c&#xE1;ch cho ph&#xE9;p th&#x1ECB; tr&#x1B0;&#x1EDD;ng ti&#xEA;u d&#xF9;ng tr&#x1EF1;c ti&#x1EBF;p b&#x1ECF; phi&#x1EBF;u b&#x1EB1;ng v&#xED; ti&#x1EC1;n c&#x1EE7;a h&#x1ECD;. Tuy nhi&#xEA;n, &#x111;&#x1EC3; tham gia v&#xE0;o s&#xE2;n ch&#x1A1;i n&#xE0;y, c&#xE1;c nh&#xE0; s&#xE1;ng l&#x1EAD;p ph&#x1EA3;i v&#x1B0;&#x1EE3;t qua m&#x1ED9;t r&#xE0;o c&#x1EA3;n &#x111;&#x1ECB;a l&#xFD; v&#xE0; ph&#xE1;p l&#xFD; v&#xF4; c&#xF9;ng nghi&#xEA;m ng&#x1EB7;t.</p><h3 id="v%C6%B0%E1%BB%A3t-qua-r%C3%A0o-c%E1%BA%A3n-%C4%91%E1%BB%8Ba-l%C3%BD-c%E1%BA%A5u-tr%C3%BAc-ph%C3%A1p-l%C3%BD-xuy%C3%AAn-bi%C3%AAn-gi%E1%BB%9Bi-cho-nh%C3%A0-s%C3%A1ng-l%E1%BA%ADp-kh%C3%B4ng-c%C6%B0-tr%C3%BA">V&#x1B0;&#x1EE3;t Qua R&#xE0;o C&#x1EA3;n &#x110;&#x1ECB;a L&#xFD;: C&#x1EA5;u Tr&#xFA;c Ph&#xE1;p L&#xFD; Xuy&#xEA;n Bi&#xEA;n Gi&#x1EDB;i Cho Nh&#xE0; S&#xE1;ng L&#x1EAD;p Kh&#xF4;ng C&#x1B0; Tr&#xFA;</h3><p>T&#xED;nh &#x111;&#x1EBF;n th&#x1EDD;i &#x111;i&#x1EC3;m hi&#x1EC7;n t&#x1EA1;i, Kickstarter ch&#x1EC9; h&#x1ED7; tr&#x1EE3; vi&#x1EC7;c kh&#x1EDF;i t&#x1EA1;o d&#x1EF1; &#xE1;n tr&#x1EF1;c ti&#x1EBF;p cho c&#xE1;c c&#xE1; nh&#xE2;n v&#xE0; th&#x1EF1;c th&#x1EC3; &#x111;&#x1B0;&#x1EE3;c &#x111;&#x103;ng k&#xFD; h&#x1EE3;p ph&#xE1;p t&#x1EA1;i 25 qu&#x1ED1;c gia c&#x1EE5; th&#x1EC3;. Danh s&#xE1;ch n&#xE0;y bao g&#x1ED3;m M&#x1EF9;, Anh, &#xDA;c, &#xC1;o, B&#x1EC9;, Canada, &#x110;an M&#x1EA1;ch, Ph&#xE1;p, &#x110;&#x1EE9;c, Hy L&#x1EA1;p, H&#x1ED3;ng K&#xF4;ng, Ireland, &#xDD;, Nh&#x1EAD;t B&#x1EA3;n, Luxembourg, Mexico, H&#xE0; Lan, New Zealand, Na Uy, Ba Lan, Singapore, Slovenia, T&#xE2;y Ban Nha, Th&#x1EE5;y &#x110;i&#x1EC3;n v&#xE0; Th&#x1EE5;y S&#x129;. Nh&#x1EEF;ng c&#xE1; nh&#xE2;n ho&#x1EB7;c doanh nghi&#x1EC7;p c&#x1B0; tr&#xFA; ngo&#xE0;i 25 qu&#x1ED1;c gia n&#xE0;y, ch&#x1EB3;ng h&#x1EA1;n nh&#x1B0; c&#xE1;c nh&#xE0; s&#xE1;ng l&#x1EAD;p t&#x1EA1;i Vi&#x1EC7;t Nam, kh&#xF4;ng th&#x1EC3; tr&#x1EF1;c ti&#x1EBF;p kh&#x1EDF;i ch&#x1EA1;y m&#x1ED9;t chi&#x1EBF;n d&#x1ECB;ch tr&#xEA;n n&#x1EC1;n t&#x1EA3;ng. D&#xF9; v&#x1EAD;y, c&#xE1;c ch&#xED;nh s&#xE1;ch c&#x1EE7;a Kickstarter v&#x1EAB;n &#x111;&#x1EC3; m&#x1EDF; m&#x1ED9;t con &#x111;&#x1B0;&#x1EDD;ng h&#x1EE3;p ph&#xE1;p: c&#xE1;c nh&#xE0; s&#xE1;ng t&#x1EA1;o qu&#x1ED1;c t&#x1EBF; c&#xF3; th&#x1EC3; th&#xE0;nh l&#x1EAD;p m&#x1ED9;t ph&#xE1;p nh&#xE2;n kinh doanh t&#x1EA1;i m&#x1ED9;t trong nh&#x1EEF;ng qu&#x1ED1;c gia &#x111;&#x1B0;&#x1EE3;c h&#x1ED7; tr&#x1EE3;, &#x111;i&#x1EC3;n h&#xEC;nh l&#xE0; vi&#x1EC7;c &#x111;&#x103;ng k&#xFD; m&#x1ED9;t C&#xF4;ng ty Tr&#xE1;ch nhi&#x1EC7;m H&#x1EEF;u h&#x1EA1;n (LLC) ho&#x1EB7;c T&#x1EAD;p &#x111;o&#xE0;n (C-Corporation) t&#x1EA1;i Hoa K&#x1EF3; th&#xF4;ng qua c&#xE1;c d&#x1ECB;ch v&#x1EE5; trung gian nh&#x1B0; Stripe Atlas.</p><p>Vi&#x1EC7;c thi&#x1EBF;t l&#x1EAD;p m&#x1ED9;t th&#x1EF1;c th&#x1EC3; t&#x1EA1;i Hoa K&#x1EF3; mang l&#x1EA1;i kh&#x1EA3; n&#x103;ng ti&#x1EBF;p c&#x1EAD;n h&#x1EC7; th&#x1ED1;ng thanh to&#xE1;n v&#xE0; &#x111;&#xE1;p &#x1EE9;ng c&#xE1;c y&#xEA;u c&#x1EA7;u n&#x1EC1;n t&#x1EA3;ng c&#x1EE7;a Kickstarter, bao g&#x1ED3;m vi&#x1EC7;c s&#x1EDF; h&#x1EEF;u m&#x1ED9;t &#x111;&#x1ECB;a ch&#x1EC9; v&#x1EAD;t l&#xFD; t&#x1EA1;i M&#x1EF9;, m&#x1ED9;t t&#xE0;i kho&#x1EA3;n ng&#xE2;n h&#xE0;ng n&#x1ED9;i &#x111;&#x1ECB;a c&#xF3; kh&#x1EA3; n&#x103;ng nh&#x1EAD;n ti&#x1EC1;n g&#x1EED;i ACH, v&#xE0; th&#x1EBB; nh&#x1EAD;n d&#x1EA1;ng do ch&#xED;nh ph&#x1EE7; c&#x1EA5;p. M&#x1EB7;c d&#xF9; qu&#xE1; tr&#xEC;nh th&#xE0;nh l&#x1EAD;p m&#x1ED9;t LLC t&#x1EA1;i M&#x1EF9; hi&#x1EC7;n nay kh&#xE1; d&#x1EC5; d&#xE0;ng v&#xE0; c&#xF3; th&#x1EC3; th&#x1EF1;c hi&#x1EC7;n tr&#x1EF1;c tuy&#x1EBF;n, vi&#x1EC7;c v&#x1EAD;n h&#xE0;nh n&#xF3; &#x111;&#x1EC3; nh&#x1EAD;n qu&#x1EF9; t&#x1EEB; Kickstarter l&#x1EA1;i &#x1EA9;n ch&#x1EE9;a h&#xE0;ng lo&#x1EA1;t r&#x1EE7;i ro ph&#xE1;p l&#xFD; v&#xE0; thu&#x1EBF; quan kh&#x1ED5;ng l&#x1ED3; n&#x1EBF;u kh&#xF4;ng &#x111;&#x1B0;&#x1EE3;c c&#x1EA5;u tr&#xFA;c ch&#xED;nh x&#xE1;c.</p><p>M&#x1ED9;t sai l&#x1EA7;m ph&#x1ED5; bi&#x1EBF;n c&#x1EE7;a c&#xE1;c nh&#xE0; s&#xE1;ng l&#x1EAD;p qu&#x1ED1;c t&#x1EBF; l&#xE0; l&#x1EA7;m t&#x1B0;&#x1EDF;ng r&#x1EB1;ng m&#x1ED9;t LLC t&#x1EA1;i M&#x1EF9; &#x111;&#x1B0;&#x1EE3;c s&#x1EDF; h&#x1EEF;u b&#x1EDF;i ng&#x1B0;&#x1EDD;i n&#x1B0;&#x1EDB;c ngo&#xE0;i s&#x1EBD; t&#x1EF1; &#x111;&#x1ED9;ng tr&#x1EDF; th&#xE0;nh m&#x1ED9;t thi&#xEA;n &#x111;&#x1B0;&#x1EDD;ng tr&#x1ED1;n thu&#x1EBF;. Tr&#xEA;n th&#x1EF1;c t&#x1EBF;, C&#x1A1; quan Thu&#x1EBF; v&#x1EE5; Hoa K&#x1EF3; (IRS) &#xE1;p &#x111;&#x1EB7;t c&#xE1;c quy &#x111;&#x1ECB;nh tu&#xE2;n th&#x1EE7; v&#xF4; c&#xF9;ng kh&#x1EAF;t khe. &#x110;&#x1ED1;i v&#x1EDB;i m&#x1ED9;t LLC c&#xF3; th&#xE0;nh vi&#xEA;n &#x111;&#x1A1;n l&#x1EBB; (Single-Member LLC) &#x111;&#x1B0;&#x1EE3;c s&#x1EDF; h&#x1EEF;u to&#xE0;n b&#x1ED9; b&#x1EDF;i m&#x1ED9;t c&#xE1; nh&#xE2;n kh&#xF4;ng c&#x1B0; tr&#xFA;, IRS coi &#x111;&#xE2;y l&#xE0; m&#x1ED9;t th&#x1EF1;c th&#x1EC3; b&#x1ECB; b&#x1ECF; qua (disregarded entity) cho c&#xE1;c m&#x1EE5;c &#x111;&#xED;ch thu&#x1EBF; thu nh&#x1EAD;p, nh&#x1B0;ng l&#x1EA1;i &#xE1;p d&#x1EE5;ng c&#xE1;c y&#xEA;u c&#x1EA7;u b&#xE1;o c&#xE1;o th&#xF4;ng tin nghi&#xEA;m ng&#x1EB7;t nh&#x1B0; &#x111;&#x1ED1;i v&#x1EDB;i m&#x1ED9;t t&#x1EAD;p &#x111;o&#xE0;n theo M&#x1EE5;c 6038A c&#x1EE7;a B&#x1ED9; lu&#x1EAD;t Thu&#x1EBF; v&#x1EE5;. &#x110;i&#x1EC1;u n&#xE0;y &#x111;&#xF2;i h&#x1ECF;i ph&#xE1;p nh&#xE2;n ph&#x1EA3;i n&#x1ED9;p M&#x1EAB;u 5472 (Form 5472) k&#xE8;m theo M&#x1EAB;u 1120 gi&#x1EA3; &#x111;&#x1ECB;nh (Pro Forma Form 1120) h&#xE0;ng n&#x103;m &#x111;&#x1EC3; b&#xE1;o c&#xE1;o m&#x1ECD;i giao d&#x1ECB;ch c&#xF3; th&#x1EC3; b&#xE1;o c&#xE1;o (reportable transactions) gi&#x1EEF;a LLC v&#xE0; ch&#x1EE7; s&#x1EDF; h&#x1EEF;u n&#x1B0;&#x1EDB;c ngo&#xE0;i c&#x1EE7;a n&#xF3;. Ngay c&#x1EA3; vi&#x1EC7;c th&#xE0;nh l&#x1EAD;p c&#xF4;ng ty, b&#x1A1;m v&#x1ED1;n ban &#x111;&#x1EA7;u &#x111;&#x1EC3; ch&#x1EA1;y qu&#x1EA3;ng c&#xE1;o Kickstarter, hay r&#xFA;t doanh thu t&#x1EEB; chi&#x1EBF;n d&#x1ECB;ch v&#x1EC1; t&#xE0;i kho&#x1EA3;n c&#xE1; nh&#xE2;n t&#x1EA1;i qu&#x1ED1;c gia s&#x1EDF; t&#x1EA1;i &#x111;&#x1EC1;u c&#x1EA5;u th&#xE0;nh c&#xE1;c giao d&#x1ECB;ch ph&#x1EA3;i b&#xE1;o c&#xE1;o. Vi&#x1EC7;c n&#x1ED9;p ch&#x1EAD;m, thi&#x1EBF;u s&#xF3;t th&#xF4;ng tin ho&#x1EB7;c kh&#xF4;ng n&#x1ED9;p M&#x1EAB;u 5472 s&#x1EBD; d&#x1EAB;n &#x111;&#x1EBF;n m&#x1ED9;t kho&#x1EA3;n ti&#x1EC1;n ph&#x1EA1;t t&#x1EF1; &#x111;&#x1ED9;ng l&#xEA;n t&#x1EDB;i 25.000 USD t&#x1EEB; IRS. Kho&#x1EA3;n ph&#x1EA1;t mang t&#xED;nh tr&#x1EEB;ng ph&#x1EA1;t n&#xE0;y c&#xF3; th&#x1EC3; ngay l&#x1EAD;p t&#x1EE9;c x&#xF3;a s&#x1ED5; to&#xE0;n b&#x1ED9; l&#x1EE3;i nhu&#x1EAD;n c&#x1EE7;a m&#x1ED9;t chi&#x1EBF;n d&#x1ECB;ch huy &#x111;&#x1ED9;ng v&#x1ED1;n v&#x1EEB;a ch&#x1EDB;m n&#x1EDF;.</p><p>B&#xEA;n c&#x1EA1;nh thu&#x1EBF; li&#xEA;n bang, c&#xE1;c nh&#xE0; s&#xE1;ng l&#x1EAD;p qu&#x1ED1;c t&#x1EBF; c&#xF2;n ph&#x1EA3;i &#x111;&#x1ED1;i m&#x1EB7;t v&#x1EDB;i m&#x1EA1;ng l&#x1B0;&#x1EDB;i ph&#x1EE9;c t&#x1EA1;p c&#x1EE7;a thu&#x1EBF; b&#xE1;n h&#xE0;ng (sales tax) t&#x1EA1;i c&#x1EA5;p &#x111;&#x1ED9; ti&#x1EC3;u bang. Tr&#xE1;i ng&#x1B0;&#x1EE3;c v&#x1EDB;i c&#xE1;c kho&#x1EA3;n &#x111;&#xF3;ng g&#xF3;p t&#x1EEB; thi&#x1EC7;n, ti&#x1EC1;n quy&#xEA;n g&#xF3;p tr&#xEA;n Kickstarter &#x111;&#x1EC3; &#x111;&#x1ED5;i l&#x1EA5;y ph&#x1EA7;n th&#x1B0;&#x1EDF;ng (&#x111;&#x1EB7;c bi&#x1EC7;t l&#xE0; h&#xE0;ng h&#xF3;a v&#x1EAD;t l&#xFD; ho&#x1EB7;c quy&#x1EC1;n truy c&#x1EAD;p ph&#x1EA7;n m&#x1EC1;m) &#x111;&#x1B0;&#x1EE3;c ph&#xE2;n lo&#x1EA1;i l&#xE0; bi&#xEA;n lai kinh doanh ho&#x1EB7;c doanh thu b&#xE1;n h&#xE0;ng &#x1EE9;ng tr&#x1B0;&#x1EDB;c. N&#x1EBF;u d&#x1EF1; &#xE1;n Kickstarter s&#x1EED; d&#x1EE5;ng c&#xE1;c kho b&#xE3;i ho&#xE0;n t&#x1EA5;t &#x111;&#x1A1;n h&#xE0;ng th&#x1EE9; ba (3PL) &#x111;&#x1EB7;t t&#x1EA1;i c&#xE1;c ti&#x1EC3;u bang nh&#x1B0; Nevada, Ohio hay California &#x111;&#x1EC3; l&#x1B0;u tr&#x1EEF; v&#xE0; ph&#xE2;n ph&#x1ED1;i s&#x1EA3;n ph&#x1EA9;m, c&#xF4;ng ty ngay l&#x1EAD;p t&#x1EE9;c x&#xE1;c l&#x1EAD;p &quot;hi&#x1EC7;n di&#x1EC7;n v&#x1EAD;t l&#xFD;&quot; (physical nexus) t&#x1EA1;i c&#xE1;c ti&#x1EC3;u bang &#x111;&#xF3;, ph&#xE1;t sinh ngh&#x129;a v&#x1EE5; ph&#x1EA3;i thu v&#xE0; n&#x1ED9;p thu&#x1EBF; b&#xE1;n h&#xE0;ng cho m&#x1ECD;i &#x111;&#x1A1;n h&#xE0;ng v&#x1EAD;n chuy&#x1EC3;n &#x111;&#x1EBF;n ng&#x1B0;&#x1EDD;i d&#xE2;n trong bang. H&#x1A1;n th&#x1EBF; n&#x1EEF;a, sau ph&#xE1;n quy&#x1EBF;t l&#x1ECB;ch s&#x1EED; c&#x1EE7;a T&#xF2;a &#xE1;n T&#x1ED1;i cao Hoa K&#x1EF3; trong v&#x1EE5; ki&#x1EC7;n <em>Wayfair</em>, c&#xE1;c ti&#x1EC3;u bang hi&#x1EC7;n c&#xF3; quy&#x1EC1;n &#xE1;p &#x111;&#x1EB7;t ngh&#x129;a v&#x1EE5; thu thu&#x1EBF; d&#x1EF1;a tr&#xEA;n &quot;hi&#x1EC7;n di&#x1EC7;n kinh t&#x1EBF;&quot; (economic nexus), t&#x1EE9;c l&#xE0; ch&#x1EC9; c&#x1EA7;n v&#x1B0;&#x1EE3;t qua m&#x1ED9;t ng&#x1B0;&#x1EE1;ng doanh thu ho&#x1EB7;c s&#x1ED1; l&#x1B0;&#x1EE3;ng giao d&#x1ECB;ch nh&#x1EA5;t &#x111;&#x1ECB;nh v&#xE0;o m&#x1ED9;t ti&#x1EC3;u bang c&#x1EE5; th&#x1EC3;, LLC n&#x1B0;&#x1EDB;c ngo&#xE0;i v&#x1EAB;n ph&#x1EA3;i tu&#xE2;n th&#x1EE7; vi&#x1EC7;c n&#x1ED9;p thu&#x1EBF; d&#xF9; kh&#xF4;ng c&#xF3; b&#x1EA5;t k&#x1EF3; kho b&#xE3;i hay nh&#xE2;n vi&#xEA;n n&#xE0;o t&#x1EA1;i M&#x1EF9;. M&#x1EB7;c d&#xF9; c&#xF4;ng c&#x1EE5; Pledge Manager c&#x1EE7;a Kickstarter c&#xF3; th&#x1EC3; h&#x1ED7; tr&#x1EE3; thu thu&#x1EBF; b&#xE1;n h&#xE0;ng nh&#x1B0; m&#x1ED9;t t&#x1ED5; ch&#x1EE9;c t&#x1EA1;o &#x111;i&#x1EC1;u ki&#x1EC7;n th&#x1ECB; tr&#x1B0;&#x1EDD;ng (marketplace facilitator) cho m&#x1ED9;t s&#x1ED1; khu v&#x1EF1;c, tr&#xE1;ch nhi&#x1EC7;m cu&#x1ED1;i c&#xF9;ng trong vi&#x1EC7;c thi&#x1EBF;t l&#x1EAD;p h&#x1EC7; th&#x1ED1;ng k&#x1EBF; to&#xE1;n t&#xE1;ch b&#x1EA1;ch v&#xE0; b&#xE1;o c&#xE1;o thu&#x1EBF; &#x111;&#x1ECB;nh k&#x1EF3; v&#x1EAB;n &#x111;&#xE8; n&#x1EB7;ng l&#xEA;n vai ph&#xE1;p nh&#xE2;n LLC.</p><p>&#x110;&#x1EC3; duy tr&#xEC; t&#xED;nh h&#x1EE3;p ph&#xE1;p, c&#xE1;c nh&#xE0; s&#xE1;ng l&#x1EAD;p t&#x1EEB; c&#xE1;c qu&#x1ED1;c gia kh&#xF4;ng &#x111;&#x1B0;&#x1EE3;c h&#x1ED7; tr&#x1EE3; ph&#x1EA3;i ch&#x1EE7; &#x111;&#x1ED9;ng xin c&#x1EA5;p M&#xE3; s&#x1ED1; Nh&#x1EAD;n d&#x1EA1;ng Ng&#x1B0;&#x1EDD;i s&#x1EED; d&#x1EE5;ng lao &#x111;&#x1ED9;ng (EIN) th&#xF4;ng qua M&#x1EAB;u SS-4, ghi r&#xF5; m&#x1EE5;c &#x111;&#xED;ch n&#x1ED9;p &#x111;&#x1EC3; tu&#xE2;n th&#x1EE7; hi&#x1EC7;p &#x111;&#x1ECB;nh thu&#x1EBF; ho&#x1EB7;c m&#x1EDF; t&#xE0;i kho&#x1EA3;n ng&#xE2;n h&#xE0;ng th&#x1B0;&#x1A1;ng m&#x1EA1;i, &#x111;&#x1ED3;ng th&#x1EDD;i c&#x1EA9;n tr&#x1ECD;ng &#x111;i&#x1EC1;n c&#xE1;c th&#xF4;ng tin &#x111;&#x1EC3; kh&#xF4;ng v&#xF4; t&#xEC;nh th&#x1EEB;a nh&#x1EAD;n c&#xE1;c ngh&#x129;a v&#x1EE5; n&#x1ED9;p thu&#x1EBF; kh&#xF4;ng c&#x1EA7;n thi&#x1EBF;t. &#x110;&#x1ED1;i v&#x1EDB;i c&#xE1;c th&#x1EE7; t&#x1EE5;c &#x111;&#x1ECB;nh danh c&#xE1; nh&#xE2;n ph&#x1EE9;c t&#x1EA1;p h&#x1A1;n, vi&#x1EC7;c xin c&#x1EA5;p M&#xE3; s&#x1ED1; Nh&#x1EAD;n d&#x1EA1;ng Ng&#x1B0;&#x1EDD;i n&#x1ED9;p thu&#x1EBF; C&#xE1; nh&#xE2;n (ITIN) b&#x1EB1;ng M&#x1EAB;u W-7 &#x111;&#xF2;i h&#x1ECF;i ph&#x1EA3;i g&#x1EED;i h&#x1ED9; chi&#x1EBF;u g&#x1ED1;c ho&#x1EB7;c b&#x1EA3;n sao &#x111;&#x1B0;&#x1EE3;c ch&#x1EE9;ng th&#x1EF1;c h&#x1EE3;p l&#x1EC7; t&#x1EDB;i c&#x1A1; quan thu&#x1EBF; Hoa K&#x1EF3;, m&#x1ED9;t quy tr&#xEC;nh c&#xF3; th&#x1EC3; m&#x1EA5;t h&#xE0;ng th&#xE1;ng &#x111;&#x1EC3; ho&#xE0;n t&#x1EA5;t. H&#x1A1;n n&#x1EEF;a, v&#x1EDB;i &#x110;&#x1EA1;o lu&#x1EAD;t Minh b&#x1EA1;ch Doanh nghi&#x1EC7;p (CTA) c&#xF3; hi&#x1EC7;u l&#x1EF1;c t&#x1EEB; n&#x103;m 2024, c&#xE1;c LLC n&#xE0;y c&#x169;ng b&#x1ECB; b&#x1EAF;t bu&#x1ED9;c ph&#x1EA3;i b&#xE1;o c&#xE1;o Th&#xF4;ng tin Quy&#x1EC1;n s&#x1EDF; h&#x1EEF;u H&#x1B0;&#x1EDF;ng l&#x1EE3;i (BOI) cho M&#x1EA1;ng l&#x1B0;&#x1EDB;i Th&#x1EF1;c thi T&#x1ED9;i ph&#x1EA1;m T&#xE0;i ch&#xED;nh (FinCEN), ch&#x1ED1;ng l&#x1EA1;i c&#xE1;c h&#xE0;nh vi r&#x1EED;a ti&#x1EC1;n &#x1EA9;n danh. S&#x1EF1; th&#x1EA5;t b&#x1EA1;i trong vi&#x1EC7;c tu&#xE2;n th&#x1EE7; c&#xE1;c quy &#x111;&#x1ECB;nh KYC (Nh&#x1EAD;n bi&#x1EBF;t Kh&#xE1;ch h&#xE0;ng) v&#xE0; AML (Ch&#x1ED1;ng R&#x1EED;a ti&#x1EC1;n) n&#xE0;y th&#x1B0;&#x1EDD;ng d&#x1EAB;n &#x111;&#x1EBF;n vi&#x1EC7;c c&#xE1;c n&#x1EC1;n t&#x1EA3;ng x&#x1EED; l&#xFD; thanh to&#xE1;n nh&#x1B0; Stripe ho&#x1EB7;c c&#xE1;c ng&#xE2;n h&#xE0;ng nh&#x1B0; Mercury &#x111;&#xF3;ng b&#x103;ng t&#xE0;i kho&#x1EA3;n kh&#xF4;ng b&#xE1;o tr&#x1B0;&#x1EDB;c, giam gi&#x1EEF; v&#x129;nh vi&#x1EC5;n ngu&#x1ED3;n v&#x1ED1;n Kickstarter v&#x1EEB;a huy &#x111;&#x1ED9;ng &#x111;&#x1B0;&#x1EE3;c.</p><!--kg-card-begin: html--><table data-path-to-node="10" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(240, 244, 249); border: 0px none rgb(128, 128, 128); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 32px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><thead style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(128, 128, 128); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-header-group; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><tr style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(128, 128, 128); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-row; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><strong style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">Y&#xEA;u C&#x1EA7;u Ph&#xE1;p L&#xFD; D&#xE0;nh Cho LLC N&#x1B0;&#x1EDB;c Ngo&#xE0;i Tr&#xEA;n Kickstarter</strong></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><strong style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">M&#xF4; T&#x1EA3; V&#xE0; C&#x1A1; Ch&#x1EBF; Ho&#x1EA1;t &#x110;&#x1ED9;ng</strong></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><strong style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">R&#x1EE7;i Ro &amp; Ch&#x1EBF; T&#xE0;i Vi Ph&#x1EA1;m</strong></td></tr></thead><tbody style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(128, 128, 128); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-row-group; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><tr style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(128, 128, 128); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-row; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="10,1,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><strong data-path-to-node="10,1,0,0" data-index-in-node="0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">&#x110;&#x1ECB;nh Danh Th&#x1EF1;c Th&#x1EC3; (EIN / ITIN)</strong></span></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><p data-path-to-node="10,1,1,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="10,1,1,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">Y&#xEA;u c&#x1EA7;u b&#x1EAF;t bu&#x1ED9;c &#x111;&#x1EC3; m&#x1EDF; t&#xE0;i kho&#x1EA3;n ng&#xE2;n h&#xE0;ng v&#xE0; thi&#x1EBF;t l&#x1EAD;p c&#x1ED5;ng thanh to&#xE1;n Stripe. Xin qua m&#x1EAB;u SS-4 (&#x111;&#x1ED1;i v&#x1EDB;i doanh nghi&#x1EC7;p) ho&#x1EB7;c W-7 (c&#xE1; nh&#xE2;n). </span><span data-path-to-node="10,1,1,0,1" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><response-element class ng-version="0.0.0-PLACEHOLDER" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><source-footnote _nghost-ng-c617374649 class="ng-star-inserted" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><sup _ngcontent-ng-c617374649 class="superscript" data-turn-source-index="7" style="animation: auto ease 0s 1 normal none running none; appearance: none; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; background-color: transparent !important; border: 0px none rgb(68, 71, 70); inset: -10px 2px 10px -2px; clear: none; clip: auto; color: rgb(68, 71, 70); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline-flex; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: -6px; margin-bottom: 0px; margin-left: -6px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(68, 71, 70) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: relative; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important; font-size: 16px !important;"><!----></sup></source-footnote><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----></response-element></span></span></p></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><p data-path-to-node="10,1,2,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="10,1,2,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">Kh&#xF4;ng th&#x1EC3; nh&#x1EAD;n v&#x1ED1;n t&#x1EEB; Kickstarter. B&#x1ECB; t&#x1EEB; ch&#x1ED1;i m&#x1EDF; t&#xE0;i kho&#x1EA3;n t&#x1EA1;i c&#xE1;c ng&#xE2;n h&#xE0;ng &#x1EA3;o n&#x1EBF;u th&#xF4;ng tin kh&#xF4;ng kh&#x1EDB;p (KYC failure). </span><span data-path-to-node="10,1,2,0,1" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><response-element class ng-version="0.0.0-PLACEHOLDER" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><source-footnote _nghost-ng-c617374649 class="ng-star-inserted" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><sup _ngcontent-ng-c617374649 class="superscript" data-turn-source-index="9" style="animation: auto ease 0s 1 normal none running none; appearance: none; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; background-color: transparent !important; border: 0px none rgb(68, 71, 70); inset: -10px 2px 10px -2px; clear: none; clip: auto; color: rgb(68, 71, 70); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline-flex; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: -6px; margin-bottom: 0px; margin-left: -6px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(68, 71, 70) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: relative; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important; font-size: 16px !important;"><!----></sup></source-footnote><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----></response-element></span></span></p></td></tr><tr style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(128, 128, 128); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-row; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="10,2,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><strong data-path-to-node="10,2,0,0" data-index-in-node="0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">B&#xE1;o C&#xE1;o Giao D&#x1ECB;ch Ch&#x1EE7; S&#x1EDF; H&#x1EEF;u (M&#x1EAB;u 5472 &amp; 1120 Pro Forma)</strong></span></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><p data-path-to-node="10,2,1,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="10,2,1,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">Khai b&#xE1;o h&#xE0;ng n&#x103;m m&#x1ECD;i d&#xF2;ng ti&#x1EC1;n ra v&#xE0;o gi&#x1EEF;a LLC t&#x1EA1;i M&#x1EF9; v&#xE0; nh&#xE0; s&#xE1;ng l&#x1EAD;p t&#x1EA1;i qu&#x1ED1;c gia s&#x1EDF; t&#x1EA1;i. </span><span data-path-to-node="10,2,1,0,1" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><response-element class ng-version="0.0.0-PLACEHOLDER" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><source-footnote _nghost-ng-c617374649 class="ng-star-inserted" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><sup _ngcontent-ng-c617374649 class="superscript" data-turn-source-index="7" style="animation: auto ease 0s 1 normal none running none; appearance: none; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; background-color: transparent !important; border: 0px none rgb(68, 71, 70); inset: -10px 2px 10px -2px; clear: none; clip: auto; color: rgb(68, 71, 70); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline-flex; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: -6px; margin-bottom: 0px; margin-left: -6px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(68, 71, 70) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: relative; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important; font-size: 16px !important;"><!----></sup></source-footnote><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----></response-element></span></span></p></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><p data-path-to-node="10,2,2,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="10,2,2,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">Ph&#x1EA1;t t&#x1EF1; &#x111;&#x1ED9;ng 25.000 USD t&#x1EEB; IRS cho m&#x1ED7;i m&#x1EAB;u b&#xE1;o c&#xE1;o n&#x1ED9;p tr&#x1EC5; ho&#x1EB7;c thi&#x1EBF;u s&#xF3;t. </span><span data-path-to-node="10,2,2,0,1" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><response-element class ng-version="0.0.0-PLACEHOLDER" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><source-footnote _nghost-ng-c617374649 class="ng-star-inserted" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><sup _ngcontent-ng-c617374649 class="superscript" data-turn-source-index="7" style="animation: auto ease 0s 1 normal none running none; appearance: none; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; background-color: transparent !important; border: 0px none rgb(68, 71, 70); inset: -10px 2px 10px -2px; clear: none; clip: auto; color: rgb(68, 71, 70); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline-flex; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: -6px; margin-bottom: 0px; margin-left: -6px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(68, 71, 70) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: relative; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important; font-size: 16px !important;"><!----></sup></source-footnote><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----></response-element></span></span></p></td></tr><tr style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(128, 128, 128); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-row; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="10,3,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><strong data-path-to-node="10,3,0,0" data-index-in-node="0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">Ngh&#x129;a V&#x1EE5; Thu&#x1EBF; B&#xE1;n H&#xE0;ng (Sales Tax Nexus)</strong></span></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><p data-path-to-node="10,3,1,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="10,3,1,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">Thi&#x1EBF;t l&#x1EAD;p khi l&#x1B0;u kho h&#xE0;ng h&#xF3;a t&#x1EA1;i M&#x1EF9; (Physical Nexus) ho&#x1EB7;c b&#xE1;n v&#x1B0;&#x1EE3;t ng&#x1B0;&#x1EE1;ng doanh thu t&#x1EA1;i m&#x1ED9;t ti&#x1EC3;u bang (Economic Nexus). </span><span data-path-to-node="10,3,1,0,1" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><response-element class ng-version="0.0.0-PLACEHOLDER" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><source-footnote _nghost-ng-c617374649 class="ng-star-inserted" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><sup _ngcontent-ng-c617374649 class="superscript" data-turn-source-index="7" style="animation: auto ease 0s 1 normal none running none; appearance: none; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; background-color: transparent !important; border: 0px none rgb(68, 71, 70); inset: -10px 2px 10px -2px; clear: none; clip: auto; color: rgb(68, 71, 70); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline-flex; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: -6px; margin-bottom: 0px; margin-left: -6px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(68, 71, 70) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: relative; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important; font-size: 16px !important;"><!----></sup></source-footnote><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----></response-element></span></span></p></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><p data-path-to-node="10,3,2,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="10,3,2,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">B&#x1ECB; truy thu thu&#x1EBF; c&#x1ED9;ng th&#xEA;m l&#xE3;i su&#x1EA5;t ph&#x1EA1;t; b&#x1ECB; c&#x1EA5;m ho&#x1EA1;t &#x111;&#x1ED9;ng kinh doanh t&#x1EA1;i ti&#x1EC3;u bang vi ph&#x1EA1;m. </span><span data-path-to-node="10,3,2,0,1" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><response-element class ng-version="0.0.0-PLACEHOLDER" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><source-footnote _nghost-ng-c617374649 class="ng-star-inserted" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><sup _ngcontent-ng-c617374649 class="superscript" data-turn-source-index="7" style="animation: auto ease 0s 1 normal none running none; appearance: none; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; background-color: transparent !important; border: 0px none rgb(68, 71, 70); inset: -10px 2px 10px -2px; clear: none; clip: auto; color: rgb(68, 71, 70); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline-flex; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: -6px; margin-bottom: 0px; margin-left: -6px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(68, 71, 70) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: relative; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important; font-size: 16px !important;"><!----></sup></source-footnote><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----></response-element></span></span></p></td></tr><tr style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(128, 128, 128); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-row; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="10,4,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><strong data-path-to-node="10,4,0,0" data-index-in-node="0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">B&#xE1;o C&#xE1;o Minh B&#x1EA1;ch T&#xE0;i Ch&#xED;nh (BOI theo CTA)</strong></span></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><p data-path-to-node="10,4,1,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="10,4,1,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">Cung c&#x1EA5;p th&#xF4;ng tin danh t&#xED;nh th&#x1EF1;c s&#x1EF1; c&#x1EE7;a c&#xE1;c ch&#x1EE7; s&#x1EDF; h&#x1EEF;u h&#x1B0;&#x1EDF;ng l&#x1EE3;i cho c&#x1A1; quan FinCEN nh&#x1EB1;m ph&#xF2;ng ch&#x1ED1;ng r&#x1EED;a ti&#x1EC1;n. </span><span data-path-to-node="10,4,1,0,1" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><response-element class ng-version="0.0.0-PLACEHOLDER" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><source-footnote _nghost-ng-c617374649 class="ng-star-inserted" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><sup _ngcontent-ng-c617374649 class="superscript" data-turn-source-index="7" style="animation: auto ease 0s 1 normal none running none; appearance: none; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; background-color: transparent !important; border: 0px none rgb(68, 71, 70); inset: -10px 2px 10px -2px; clear: none; clip: auto; color: rgb(68, 71, 70); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline-flex; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: -6px; margin-bottom: 0px; margin-left: -6px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(68, 71, 70) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: relative; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important; font-size: 16px !important;"><!----></sup></source-footnote><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----></response-element></span></span></p></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><p data-path-to-node="10,4,2,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="10,4,2,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">Ph&#x1EA1;t ti&#x1EC1;n h&#xE0;nh ch&#xED;nh l&#x169;y ti&#x1EBF;n theo ng&#xE0;y; &#x111;&#x1ED1;i m&#x1EB7;t v&#x1EDB;i c&#xE1;c c&#xE1;o bu&#x1ED9;c h&#xEC;nh s&#x1EF1; n&#x1EBF;u c&#x1ED1; t&#xEC;nh che gi&#x1EA5;u. </span><span data-path-to-node="10,4,2,0,1" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><response-element class ng-version="0.0.0-PLACEHOLDER" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><source-footnote _nghost-ng-c617374649 class="ng-star-inserted" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><sup _ngcontent-ng-c617374649 class="superscript" data-turn-source-index="7" style="animation: auto ease 0s 1 normal none running none; appearance: none; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; background-color: transparent !important; border: 0px none rgb(68, 71, 70); inset: -10px 2px 10px -2px; clear: none; clip: auto; color: rgb(68, 71, 70); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline-flex; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: -6px; margin-bottom: 0px; margin-left: -6px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(68, 71, 70) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: relative; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important; font-size: 16px !important;"><!----></sup></source-footnote><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----></response-element></span></span></p></td></tr></tbody></table><!--kg-card-end: html--><h3 id="khoa-h%E1%BB%8Dc-x%C3%A2y-d%E1%BB%B1ng-c%E1%BB%99ng-%C4%91%E1%BB%93ng-ti%E1%BB%81n-kh%E1%BB%9Fi-ch%E1%BA%A1y-pre-launch">Khoa H&#x1ECD;c X&#xE2;y D&#x1EF1;ng C&#x1ED9;ng &#x110;&#x1ED3;ng Ti&#x1EC1;n Kh&#x1EDF;i Ch&#x1EA1;y (Pre-launch)</h3><p>S&#x1EF1; ng&#x1ED9; nh&#x1EAD;n nguy hi&#x1EC3;m nh&#x1EA5;t trong l&#x129;nh v&#x1EF1;c g&#x1ECD;i v&#x1ED1;n c&#x1ED9;ng &#x111;&#x1ED3;ng l&#xE0; ni&#x1EC1;m tin &quot;h&#x1EEF;u x&#x1EA1; t&#x1EF1; nhi&#xEA;n h&#x1B0;&#x1A1;ng&quot; &#x2014; &#x1EA3;o t&#x1B0;&#x1EDF;ng r&#x1EB1;ng ch&#x1EC9; c&#x1EA7;n t&#x1EA1;o ra m&#x1ED9;t chi&#x1EBF;n d&#x1ECB;ch v&#x1EDB;i s&#x1EA3;n ph&#x1EA9;m xu&#x1EA5;t s&#x1EAF;c, thu&#x1EAD;t to&#xE1;n s&#x1EBD; t&#x1EF1; &#x111;&#x1ED9;ng ph&#xE2;n ph&#x1ED1;i n&#xF3; &#x111;&#x1EBF;n h&#xE0;ng tri&#x1EC7;u ng&#x1B0;&#x1EDD;i d&#xF9;ng. Th&#x1EF1;c t&#x1EBF; kh&#x1EAF;c nghi&#x1EC7;t cho th&#x1EA5;y, nh&#x1EEF;ng chi&#x1EBF;n d&#x1ECB;ch kh&#x1EDF;i ch&#x1EA1;y t&#x1EEB; con s&#x1ED1; kh&#xF4;ng, kh&#xF4;ng c&#xF3; l&#x1B0;&#x1EE3;ng kh&#xE1;n gi&#x1EA3; m&#x1ED3;i (seed audience), g&#x1EA7;n nh&#x1B0; ch&#x1EAF;c ch&#x1EAF;n s&#x1EBD; th&#x1EA5;t b&#x1EA1;i trong vi&#x1EC7;c t&#x1EA1;o ra l&#x1EF1;c k&#xE9;o ban &#x111;&#x1EA7;u. D&#x1EEF; li&#x1EC7;u n&#x1ED9;i b&#x1ED9; t&#x1EEB; Kickstarter ch&#x1EC9; ra m&#x1ED9;t t&#x1EF7; l&#x1EC7; chuy&#x1EC3;n &#x111;&#x1ED5;i ch&#xEA;nh l&#x1EC7;ch r&#xF5; r&#x1EC7;t: nh&#x1EEF;ng c&#xE1; nh&#xE2;n theo d&#xF5;i d&#x1EF1; &#xE1;n th&#xF4;ng qua trang ti&#x1EC1;n kh&#x1EDF;i ch&#x1EA1;y (pre-launch page) tr&#x1B0;&#x1EDB;c khi d&#x1EF1; &#xE1;n ch&#xED;nh th&#x1EE9;c m&#x1EDF; b&#xE1;n c&#xF3; t&#x1EF7; l&#x1EC7; chuy&#x1EC3;n &#x111;&#x1ED5;i th&#xE0;nh ng&#x1B0;&#x1EDD;i &#x1EE7;ng h&#x1ED9; t&#xE0;i ch&#xED;nh l&#xEA;n t&#x1EDB;i 32%, cao g&#x1EA7;n g&#x1EA5;p &#x111;&#xF4;i so v&#x1EDB;i m&#x1EE9;c 17% c&#x1EE7;a nh&#x1EEF;ng ng&#x1B0;&#x1EDD;i d&#xF9;ng ch&#x1EC9; ph&#xE1;t hi&#x1EC7;n ra d&#x1EF1; &#xE1;n sau khi n&#xF3; &#x111;&#xE3; &#x111;i v&#xE0;o ho&#x1EA1;t &#x111;&#x1ED9;ng.</p><p>V&#xEC; v&#x1EAD;y, giai &#x111;o&#x1EA1;n ti&#x1EC1;n kh&#x1EDF;i ch&#x1EA1;y, th&#x1B0;&#x1EDD;ng &#x111;&#x1B0;&#x1EE3;c ti&#x1EBF;n h&#xE0;nh t&#x1EEB; 6 &#x111;&#x1EBF;n 9 th&#xE1;ng tr&#x1B0;&#x1EDB;c ng&#xE0;y ph&#xE1;t h&#xE0;nh ch&#xED;nh th&#x1EE9;c, l&#xE0; x&#x1B0;&#x1A1;ng s&#x1ED1;ng c&#x1EE7;a m&#x1ECD;i n&#x1ED7; l&#x1EF1;c g&#x1ECD;i v&#x1ED1;n th&#xE0;nh c&#xF4;ng. Qu&#xE1; tr&#xEC;nh n&#xE0;y b&#x1EAF;t &#x111;&#x1EA7;u b&#x1EB1;ng vi&#x1EC7;c x&#xE2;y d&#x1EF1;ng m&#x1ED9;t trang &#x111;&#xED;ch (landing page) t&#x1ED1;i &#x1B0;u h&#xF3;a chuy&#x1EC3;n &#x111;&#x1ED5;i, ho&#x1EA1;t &#x111;&#x1ED9;ng nh&#x1B0; m&#x1ED9;t h&#x1EC7; th&#x1ED1;ng thu th&#x1EAD;p danh s&#xE1;ch email ngo&#x1EA1;i vi (off-platform lead capture). Kh&#xE1;c v&#x1EDB;i trang chi&#x1EBF;n d&#x1ECB;ch ch&#xED;nh th&#x1EE9;c ch&#x1EE9;a &#x111;&#x1EF1;ng th&#xF4;ng s&#x1ED1; k&#x1EF9; thu&#x1EAD;t chi ti&#x1EBF;t, trang ti&#x1EC1;n kh&#x1EDF;i ch&#x1EA1;y c&#x1EA7;n &#x111;&#x1B0;&#x1EE3;c thi&#x1EBF;t k&#x1EBF; d&#x1B0;&#x1EDB;i d&#x1EA1;ng m&#x1ED9;t &quot;&#x111;o&#x1EA1;n gi&#x1EDB;i thi&#x1EC7;u phim&quot; (movie trailer), b&#xE1;m s&#xE1;t nguy&#xEA;n t&#x1EAF;c cung c&#x1EA5;p gi&#xE1; tr&#x1ECB; c&#x1ED1;t l&#xF5;i nh&#x1B0;ng kh&#xF4;ng l&#xE0;m kh&#xE1;n gi&#x1EA3; cho&#xE1;ng ng&#x1EE3;p.</p><p>C&#xE1;c ph&#x1EA7;n t&#x1EED; b&#x1EAF;t bu&#x1ED9;c c&#x1EA5;u th&#xE0;nh m&#x1ED9;t trang &#x111;&#xED;ch ti&#x1EC1;n kh&#x1EDF;i ch&#x1EA1;y chuy&#x1EC3;n &#x111;&#x1ED5;i cao bao g&#x1ED3;m: m&#x1ED9;t ti&#xEA;u &#x111;&#x1EC1; m&#x1EA1;nh m&#x1EBD; thu h&#xFA;t s&#x1EF1; t&#xF2; m&#xF2; ngay l&#x1EAD;p t&#x1EE9;c; c&#xE1;c y&#x1EBF;u t&#x1ED1; tr&#x1EF1;c quan nh&#x1B0; &#x1EA3;nh ch&#x1EE5;p s&#x1EA3;n ph&#x1EA9;m th&#x1EF1;c t&#x1EBF;, &#x111;&#x1ED3; h&#x1ECD;a &#x111;&#x1ED9;ng (GIF) th&#x1EC3; hi&#x1EC7;n c&#x1A1; ch&#x1EBF; ho&#x1EA1;t &#x111;&#x1ED9;ng, ho&#x1EB7;c m&#x1ED9;t video ng&#x1EAF;n l&#xE0;m n&#x1ED5;i b&#x1EAD;t v&#x1EA5;n &#x111;&#x1EC1; m&#xE0; s&#x1EA3;n ph&#x1EA9;m gi&#x1EA3;i quy&#x1EBF;t; v&#xE0; m&#x1ED9;t Tuy&#xEA;n b&#x1ED1; Gi&#xE1; tr&#x1ECB; (Value Proposition) r&#xF5; r&#xE0;ng. Tuy nhi&#xEA;n, y&#x1EBF;u t&#x1ED1; quan tr&#x1ECD;ng nh&#x1EA5;t l&#xE0; L&#x1EDD;i k&#xEA;u g&#x1ECD;i h&#xE0;nh &#x111;&#x1ED9;ng (CTA) &#x111;&#x1B0;&#x1EE3;c thi&#x1EBF;t k&#x1EBF; k&#x1EBF;t h&#x1EE3;p v&#x1EDB;i nguy&#xEA;n l&#xFD; khan hi&#x1EBF;m v&#xE0; &#x111;&#x1ED9;c quy&#x1EC1;n, ch&#x1EB3;ng h&#x1EA1;n nh&#x1B0; khuy&#x1EBF;n kh&#xED;ch ng&#x1B0;&#x1EDD;i d&#xF9;ng &#x111;&#x1EC3; l&#x1EA1;i email &#x111;&#x1EC3; &quot;M&#x1EDF; kh&#xF3;a m&#x1EE9;c gi&#xE1; Early Bird gi&#x1EDB;i h&#x1EA1;n&quot; ho&#x1EB7;c &quot;&#x110;&#x1EA3;m b&#x1EA3;o v&#x1ECB; tr&#xED; &#x1B0;u ti&#xEA;n khi ra m&#x1EAF;t&quot;. Vi&#x1EC7;c c&#xF4;ng b&#x1ED1; r&#xF5; r&#xE0;ng ng&#xE0;y v&#xE0; gi&#x1EDD; kh&#x1EDF;i ch&#x1EA1;y c&#x1EE5; th&#x1EC3; (v&#xED; d&#x1EE5;: &quot;Ch&#xED;nh th&#x1EE9;c m&#x1EDF; b&#xE1;n v&#xE0;o 10:00 s&#xE1;ng EST ng&#xE0;y 5 th&#xE1;ng 11&quot;) tr&#xEA;n trang &#x111;&#xED;ch c&#x169;ng k&#xED;ch ho&#x1EA1;t t&#xE2;m l&#xFD; ch&#x1EDD; &#x111;&#x1EE3;i v&#xE0; t&#x1EA1;o ra s&#x1EF1; kh&#x1EA9;n c&#x1EA5;p.</p><p>S&#x1EE9;c m&#x1EA1;nh c&#x1EE7;a chi&#x1EBF;n l&#x1B0;&#x1EE3;c ti&#x1EC1;n kh&#x1EDF;i ch&#x1EA1;y &#x111;&#x1B0;&#x1EE3;c minh h&#x1ECD;a r&#xF5; n&#xE9;t qua tr&#x1B0;&#x1EDD;ng h&#x1EE3;p nghi&#xEA;n c&#x1EE9;u c&#x1EE7;a <em>Code4Startup</em>, m&#x1ED9;t d&#x1EF1; &#xE1;n g&#x1ECD;i v&#x1ED1;n cho n&#x1EC1;n t&#x1EA3;ng h&#x1ECD;c l&#x1EAD;p tr&#xEC;nh do nh&#xE0; s&#xE1;ng l&#x1EAD;p ng&#x1B0;&#x1EDD;i Vi&#x1EC7;t Leo Trieu th&#x1EF1;c hi&#x1EC7;n. D&#xF9; ch&#x1EC9; &#x111;&#x1EB7;t m&#x1EE5;c ti&#xEA;u khi&#xEA;m t&#x1ED1;n l&#xE0; 2.000 USD, Code4Startup &#x111;&#xE3; g&#x1ECD;i &#x111;&#x1B0;&#x1EE3;c 32.358 USD trong v&#xF2;ng 30 ng&#xE0;y (&#x111;&#x1EA1;t 1618% m&#x1EE5;c ti&#xEA;u) th&#xF4;ng qua c&#xE1;c k&#x1EF9; thu&#x1EAD;t hack t&#x103;ng tr&#x1B0;&#x1EDF;ng (growth hacking) tinh vi. C&#xE1;ch ti&#x1EBF;p c&#x1EAD;n c&#x1EE7;a d&#x1EF1; &#xE1;n n&#xE0;y b&#x1EAF;t &#x111;&#x1EA7;u tr&#x1B0;&#x1EDB;c 1,5 th&#xE1;ng b&#x1EB1;ng vi&#x1EC7;c ch&#x1EA1;y th&#x1EED; nghi&#x1EC7;m A/B li&#xEA;n t&#x1EE5;c c&#xE1;c trang &#x111;&#xED;ch &#x111;&#x1EC3; t&#xEC;m ra th&#xF4;ng &#x111;i&#x1EC7;p c&#xF3; t&#x1EF7; l&#x1EC7; chuy&#x1EC3;n &#x111;&#x1ED5;i cao nh&#x1EA5;t, k&#x1EBF;t h&#x1EE3;p v&#x1EDB;i vi&#x1EC7;c xu&#x1EA5;t b&#x1EA3;n n&#x1ED9;i dung d&#xE0;y &#x111;&#x1EB7;c tr&#xEA;n c&#xE1;c blog v&#xE0; m&#x1EA1;ng x&#xE3; h&#x1ED9;i. &#x110;i&#x1EC3;m b&#xF9;ng n&#x1ED5; c&#x1EE7;a chi&#x1EBF;n d&#x1ECB;ch n&#x1EB1;m &#x1EDF; thu&#x1EAD;t to&#xE1;n &quot;24-Hour Hook&quot;. &#x110;&#xFA;ng 24 gi&#x1EDD; tr&#x1B0;&#x1EDB;c khi Kickstarter m&#x1EDF; c&#x1EED;a, m&#x1ED9;t email kh&#x1EA9;n c&#x1EA5;p &#x111;&#x1B0;&#x1EE3;c g&#x1EED;i &#x111;&#x1EBF;n to&#xE0;n b&#x1ED9; danh s&#xE1;ch ch&#x1EDD;, th&#xF4;ng b&#xE1;o v&#x1EC1; m&#x1ED9;t g&#xF3;i &#x1B0;u &#x111;&#xE3;i c&#x1EF1;c k&#x1EF3; &#x111;&#x1EB7;c bi&#x1EC7;t ch&#x1EC9; d&#xE0;nh ri&#xEA;ng cho 50 ng&#x1B0;&#x1EDD;i d&#xF9;ng &#x111;&#x1EA7;u ti&#xEA;n. Chi&#x1EBF;n thu&#x1EAD;t n&#xE0;y t&#x1EA1;o ra hi&#x1EC7;u &#x1EE9;ng &#x111;&#xE1;m &#x111;&#xF4;ng &#x1ED3; &#x1EA1;t; ch&#x1EC9; trong 20 ph&#xFA;t &#x111;&#x1EA7;u ti&#xEA;n, d&#x1EF1; &#xE1;n &#x111;&#xE3; &#x111;&#x1EA1;t 70% m&#x1EE5;c ti&#xEA;u t&#xE0;i ch&#xED;nh, v&#xE0; k&#x1EBF;t th&#xFA;c ng&#xE0;y &#x111;&#x1EA7;u ti&#xEA;n &#x1EDF; m&#x1EE9;c 277%. S&#x1EF1; gia t&#x103;ng l&#x1B0;u l&#x1B0;&#x1EE3;ng truy c&#x1EAD;p v&#x1EDB;i t&#x1ED1;c &#x111;&#x1ED9; &#xE1;nh s&#xE1;ng n&#xE0;y &#x111;&#xE3; k&#xED;ch ho&#x1EA1;t thu&#x1EAD;t to&#xE1;n c&#x1EE7;a Kickstarter, &#x111;&#x1B0;a Code4Startup l&#xEA;n trang ch&#x1EE7; c&#x1EE7;a danh s&#xE1;ch &quot;D&#x1EF1; &#xE1;n Ph&#x1ED5; bi&#x1EBF;n&quot; (Popular Projects), t&#x1EEB; &#x111;&#xF3; thu h&#xFA;t th&#xEA;m h&#xE0;ng ngh&#xEC;n l&#x1B0;&#x1EE3;t truy c&#x1EAD;p h&#x1EEF;u c&#x1A1; m&#xE0; kh&#xF4;ng t&#x1ED1;n chi ph&#xED; qu&#x1EA3;ng c&#xE1;o.</p><p>T&#x1B0;&#x1A1;ng t&#x1EF1;, d&#x1EF1; &#xE1;n tr&#xF2; ch&#x1A1;i <em>Dididodo defense</em> c&#x1EE7;a 9Fury Studio, &#x111;&#x1B0;&#x1EE3;c ghi nh&#x1EAD;n l&#xE0; d&#x1EF1; &#xE1;n game Vi&#x1EC7;t Nam &#x111;&#x1EA7;u ti&#xEA;n huy &#x111;&#x1ED9;ng v&#x1ED1;n th&#xE0;nh c&#xF4;ng tr&#xEA;n n&#x1EC1;n t&#x1EA3;ng n&#xE0;y, c&#x169;ng nh&#x1EA5;n m&#x1EA1;nh t&#x1EA7;m quan tr&#x1ECD;ng c&#x1EE7;a vi&#x1EC7;c hi&#x1EC3;u r&#xF5; gi&#x1EDB;i h&#x1EA1;n c&#x1EE7;a m&#x1ED9;t studio nh&#x1ECF;. B&#x1EB1;ng c&#xE1;ch &#x111;&#x1EB7;t m&#x1ED9;t m&#x1EE5;c ti&#xEA;u t&#xE0;i ch&#xED;nh c&#x1EF1;c th&#x1EA5;p (150 USD), d&#x1EF1; &#xE1;n gi&#x1EA3;m thi&#x1EC3;u r&#xE0;o c&#x1EA3;n t&#xE2;m l&#xFD; c&#x1EE7;a ng&#x1B0;&#x1EDD;i &#x1EE7;ng h&#x1ED9; v&#xE0; d&#x1EC5; d&#xE0;ng v&#x1B0;&#x1EE3;t m&#x1EE9;c k&#x1EF3; v&#x1ECD;ng, cu&#x1ED1;i c&#xF9;ng huy &#x111;&#x1ED9;ng &#x111;&#x1B0;&#x1EE3;c g&#x1EA7;n 2.000 USD. S&#x1EF1; khi&#xEA;m t&#x1ED1;n c&#xF3; t&#xED;nh to&#xE1;n trong vi&#x1EC7;c thi&#x1EBF;t l&#x1EAD;p m&#x1EE5;c ti&#xEA;u ban &#x111;&#x1EA7;u ch&#xED;nh l&#xE0; b&#xED; quy&#x1EBF;t &#x111;&#x1EC3; khai th&#xE1;c thu&#x1EAD;t to&#xE1;n x&#x1EBF;p h&#x1EA1;ng c&#x1EE7;a Kickstarter, v&#x1ED1;n &#x1B0;u ti&#xEA;n &quot;t&#x1ED1;c &#x111;&#x1ED9; ho&#xE0;n th&#xE0;nh m&#x1EE5;c ti&#xEA;u&quot; (funding velocity) cao h&#x1A1;n l&#xE0; t&#x1ED5;ng s&#x1ED1; ti&#x1EC1;n tuy&#x1EC7;t &#x111;&#x1ED1;i huy &#x111;&#x1ED9;ng &#x111;&#x1B0;&#x1EE3;c trong nh&#x1EEF;ng ng&#xE0;y &#x111;&#x1EA7;u.</p><h3 id="khung-c%E1%BA%A5u-tr%C3%BAc-k%E1%BB%83-chuy%E1%BB%87n-b%E1%BA%B1ng-video-v%C3%A0-ki%E1%BA%BFn-tr%C3%BAc-ph%E1%BA%A7n-th%C6%B0%E1%BB%9Fng">Khung C&#x1EA5;u Tr&#xFA;c K&#x1EC3; Chuy&#x1EC7;n B&#x1EB1;ng Video v&#xE0; Ki&#x1EBF;n Tr&#xFA;c Ph&#x1EA7;n Th&#x1B0;&#x1EDF;ng</h3><p>N&#x1EBF;u trang ti&#x1EC1;n kh&#x1EDF;i ch&#x1EA1;y l&#xE0; m&#x1ED3;i nh&#x1EED;, th&#xEC; trang chi&#x1EBF;n d&#x1ECB;ch ch&#xED;nh th&#x1EE9;c, &#x111;&#x1EB7;c bi&#x1EC7;t l&#xE0; video gi&#x1EDB;i thi&#x1EC7;u, ch&#xED;nh l&#xE0; l&#x1B0;&#x1EE1;i c&#xE2;u. Th&#x1ED1;ng k&#xEA; cho th&#x1EA5;y ph&#x1EA7;n l&#x1EDB;n c&#xE1;c chi&#x1EBF;n d&#x1ECB;ch thu v&#x1EC1; h&#xE0;ng tri&#x1EC7;u USD nh&#x1B0; Pebble Time (h&#x1A1;n 20 tri&#x1EC7;u USD), Coolest Cooler (13,2 tri&#x1EC7;u USD), hay Fidget Cube (6,4 tri&#x1EC7;u USD) &#x111;&#x1EC1;u s&#x1EDF; h&#x1EEF;u nh&#x1EEF;ng video c&#xF3; kh&#x1EA3; n&#x103;ng lan truy&#x1EC1;n m&#x1EA1;nh m&#x1EBD;. M&#x1ED9;t video Kickstarter kh&#xF4;ng &#x111;&#x1A1;n thu&#x1EA7;n l&#xE0; m&#x1ED9;t &#x111;o&#x1EA1;n qu&#x1EA3;ng c&#xE1;o th&#x1B0;&#x1A1;ng m&#x1EA1;i; n&#xF3; ph&#x1EA3;i l&#xE0; m&#x1ED9;t c&#xF4;ng c&#x1EE5; k&#x1EC3; chuy&#x1EC7;n k&#x1EBF;t n&#x1ED1;i c&#x1EA3;m x&#xFA;c gi&#x1EEF;a t&#x1EA7;m nh&#xEC;n c&#x1EE7;a nh&#xE0; s&#xE1;ng t&#x1EA1;o v&#xE0; khao kh&#xE1;t c&#x1EE7;a ng&#x1B0;&#x1EDD;i &#x1EE7;ng h&#x1ED9;.</p><p>Khung k&#x1ECB;ch b&#x1EA3;n chuy&#x1EC3;n &#x111;&#x1ED5;i cao d&#xE0;nh cho m&#x1ED9;t video Kickstarter &#x111;&#x1B0;&#x1EE3;c c&#x1EA5;u tr&#xFA;c ch&#x1EB7;t ch&#x1EBD; qua n&#x103;m giai &#x111;o&#x1EA1;n thi&#x1EBF;t y&#x1EBF;u :</p><ol><li><strong>L&#x1B0;&#x1EE1;i c&#xE2;u m&#x1EDF; &#x111;&#x1EA7;u (The Hook):</strong> Trong 7 &#x111;&#x1EBF;n 10 gi&#xE2;y &#x111;&#x1EA7;u ti&#xEA;n, video ph&#x1EA3;i l&#x1EAD;p t&#x1EE9;c thu h&#xFA;t s&#x1EF1; ch&#xFA; &#xFD; b&#x1EB1;ng c&#xE1;ch xo&#xE1;y s&#xE2;u v&#xE0;o m&#x1ED9;t v&#x1EA5;n &#x111;&#x1EC1; th&#x1EF1;c t&#x1EBF;, g&#xE2;y th&#x1EA5;t v&#x1ECD;ng m&#xE0; &#x111;&#x1ED1;i t&#x1B0;&#x1EE3;ng m&#x1EE5;c ti&#xEA;u &#x111;ang g&#x1EB7;p ph&#x1EA3;i, ho&#x1EB7;c s&#x1EED; d&#x1EE5;ng s&#x1EF1; h&#xE0;i h&#x1B0;&#x1EDB;c v&#xE0; h&#xEC;nh &#x1EA3;nh k&#xED;ch th&#xED;ch th&#x1ECB; gi&#xE1;c m&#x1EA1;nh. Vi&#x1EC7;c th&#x1EA5;t b&#x1EA1;i trong vi&#x1EC7;c gi&#x1EEF; ch&#xE2;n kh&#xE1;n gi&#x1EA3; &#x1EDF; giai &#x111;o&#x1EA1;n n&#xE0;y &#x111;&#x1ED3;ng ngh&#x129;a v&#x1EDB;i vi&#x1EC7;c m&#x1EA5;t &#x111;i kh&#xE1;ch h&#xE0;ng.</li><li><strong>L&#x1EDD;i ch&#xE0;o h&#xE0;ng s&#xFA;c t&#xED;ch (The Elevator Pitch):</strong> Ngay sau khi tr&#xEC;nh b&#xE0;y v&#x1EA5;n &#x111;&#x1EC1;, gi&#x1EA3;i ph&#xE1;p ph&#x1EA3;i &#x111;&#x1B0;&#x1EE3;c gi&#x1EDB;i thi&#x1EC7;u m&#x1ED9;t c&#xE1;ch g&#xE3;y g&#x1ECD;n trong kho&#x1EA3;ng 15 gi&#xE2;y. Tr&#x1ECD;ng t&#xE2;m &#x1EDF; &#x111;&#xE2;y kh&#xF4;ng ph&#x1EA3;i l&#xE0; nh&#x1ED3;i nh&#xE9;t th&#xF4;ng s&#x1ED1; k&#x1EF9; thu&#x1EAD;t, m&#xE0; l&#xE0; kh&#x1EB3;ng &#x111;&#x1ECB;nh gi&#xE1; tr&#x1ECB; c&#x1ED1;t l&#xF5;i c&#x1EE7;a s&#x1EA3;n ph&#x1EA9;m.</li><li><strong>Tr&#xEC;nh di&#x1EC5;n T&#xED;nh n&#x103;ng v&#xE0; L&#x1EE3;i &#xED;ch (Features &amp; Benefits):</strong> Giai &#x111;o&#x1EA1;n n&#xE0;y k&#x1EBF;t n&#x1ED1;i tr&#x1EF1;c ti&#x1EBF;p c&#xE1;c &#x111;&#x1EB7;c &#x111;i&#x1EC3;m thi&#x1EBF;t k&#x1EBF; c&#x1EE7;a s&#x1EA3;n ph&#x1EA9;m v&#x1EDB;i nh&#x1EEF;ng l&#x1EE3;i &#xED;ch th&#x1EF1;c ti&#x1EC5;n. Vi&#x1EC7;c tr&#xEC;nh di&#x1EC5;n s&#x1EA3;n ph&#x1EA9;m &#x111;ang ho&#x1EA1;t &#x111;&#x1ED9;ng trong th&#x1EBF; gi&#x1EDB;i th&#x1EF1;c, th&#xF4;ng qua c&#xE1;c nguy&#xEA;n m&#x1EAB;u (prototypes) thay v&#xEC; ch&#x1EC9; l&#xE0; c&#xE1;c b&#x1EA3;n v&#x1EBD; &#x111;&#x1ED3; h&#x1ECD;a m&#xE1;y t&#xED;nh (render), &#x111;&#xF3;ng vai tr&#xF2; s&#x1ED1;ng c&#xF2;n trong vi&#x1EC7;c x&#xE2;y d&#x1EF1;ng ni&#x1EC1;m tin ph&#xE1;p l&#xFD; v&#xE0; t&#xE2;m l&#xFD;.</li><li><strong>Tuy&#xEA;n b&#x1ED1; T&#xF3;m t&#x1EAF;t Kh&#x1EAF;c s&#xE2;u (Memorable Product Summary):</strong> Li&#xEA;n k&#x1EBF;t to&#xE0;n b&#x1ED9; c&#xE1;c t&#xED;nh n&#x103;ng l&#x1EA1;i th&#xE0;nh m&#x1ED9;t b&#x1EA3;n s&#x1EAF;c th&#x1B0;&#x1A1;ng hi&#x1EC7;u nh&#x1EA5;t qu&#xE1;n, t&#x1EA1;o ra m&#x1ED9;t c&#xE2;u kh&#x1EA9;u hi&#x1EC7;u d&#x1EC5; nh&#x1EDB; &#x111;&#x1EC3; ng&#x1B0;&#x1EDD;i xem c&#xF3; th&#x1EC3; s&#x1EED; d&#x1EE5;ng khi chia s&#x1EBB; d&#x1EF1; &#xE1;n v&#x1EDB;i b&#x1EA1;n b&#xE8; c&#x1EE7;a h&#x1ECD;.</li><li><strong>L&#x1EDD;i k&#xEA;u g&#x1ECD;i h&#xE0;nh &#x111;&#x1ED9;ng tr&#x1EF1;c ti&#x1EBF;p (Clear Call-to-Action):</strong> K&#x1EBF;t th&#xFA;c video b&#x1EB1;ng m&#x1ED9;t ch&#x1EC9; th&#x1ECB; r&#xF5; r&#xE0;ng, kh&#xF4;ng v&#xF2;ng vo, v&#xED; d&#x1EE5;: &quot;H&#xE3;y &#x1EE7;ng h&#x1ED9; chi&#x1EBF;n d&#x1ECB;ch c&#x1EE7;a ch&#xFA;ng t&#xF4;i ngay h&#xF4;m nay v&#xE0; tr&#x1EDF; th&#xE0;nh ng&#x1B0;&#x1EDD;i &#x111;&#x1EA7;u ti&#xEA;n s&#x1EDF; h&#x1EEF;u&quot;.</li></ol><p>V&#x1B0;&#x1EE3;t ra ngo&#xE0;i h&#xEC;nh &#x1EA3;nh tr&#x1EF1;c quan, vi&#x1EC7;c x&#xE2;y d&#x1EF1;ng c&#x1EA5;u tr&#xFA;c ph&#x1EA7;n th&#x1B0;&#x1EDF;ng (reward tiers) quy&#x1EBF;t &#x111;&#x1ECB;nh gi&#xE1; tr&#x1ECB; v&#xF2;ng &#x111;&#x1EDD;i c&#x1EE7;a chi&#x1EBF;n d&#x1ECB;ch. M&#x1ED9;t chi&#x1EBF;n l&#x1B0;&#x1EE3;c c&#x1EA5;u tr&#xFA;c ph&#x1EA7;n th&#x1B0;&#x1EDF;ng &#x111;&#x1B0;&#x1EE3;c t&#x1ED1;i &#x1B0;u h&#xF3;a c&#x1EA7;n tu&#xE2;n th&#x1EE7; nguy&#xEA;n t&#x1EAF;c gi&#x1EDB;i h&#x1EA1;n s&#x1EF1; l&#x1EF1;a ch&#x1ECD;n, t&#x1ED1;t nh&#x1EA5;t l&#xE0; cung c&#x1EA5;p t&#x1EEB; 3 &#x111;&#x1EBF;n 5 c&#x1EA5;p &#x111;&#x1ED9; ph&#x1EA7;n th&#x1B0;&#x1EDF;ng ch&#xED;nh &#x111;&#x1EC3; tr&#xE1;nh l&#xE0;m ng&#x1B0;&#x1EDD;i d&#xF9;ng b&#x1ECB; qu&#xE1; t&#x1EA3;i th&#xF4;ng tin. Nguy&#xEA;n t&#x1EAF;c c&#x1ED1;t l&#xF5;i l&#xE0; thi&#x1EBF;t l&#x1EAD;p m&#x1ED9;t m&#x1EE9;c gi&#xE1; &quot;m&#x1ECF; neo&quot; (anchor price) cho s&#x1EA3;n ph&#x1EA9;m c&#x1A1; b&#x1EA3;n, sau &#x111;&#xF3; t&#x1EA1;o ra m&#x1ED9;t phi&#xEA;n b&#x1EA3;n cao c&#x1EA5;p (premium tier) v&#x1EDB;i c&#xE1;c gi&#xE1; tr&#x1ECB; b&#x1ED5; sung &#x111;&#x1ED9;c quy&#x1EC1;n c&#xF3; chi ph&#xED; s&#x1EA3;n xu&#x1EA5;t th&#x1EA5;p nh&#x1B0;ng l&#x1EA1;i mang gi&#xE1; tr&#x1ECB; c&#x1EA3;m nh&#x1EAD;n cao &#x111;&#x1ED1;i v&#x1EDB;i ng&#x1B0;&#x1EDD;i d&#xF9;ng.</p><p>M&#x1ED9;t trong nh&#x1EEF;ng ph&#xE1;t hi&#x1EC7;n t&#xE2;m l&#xFD; h&#x1ECD;c quan tr&#x1ECD;ng nh&#x1EA5;t v&#x1EC1; Kickstarter l&#xE0; s&#x1EE9;c m&#x1EA1;nh c&#x1EE7;a ph&#x1EA7;n th&#x1B0;&#x1EDF;ng 1 USD. Thay v&#xEC; b&#x1ECF; qua nh&#x1EEF;ng kh&#xE1;ch h&#xE0;ng c&#xF3; ng&#xE2;n s&#xE1;ch h&#x1EB9;p, m&#x1ED9;t ph&#x1EA7;n th&#x1B0;&#x1EDF;ng 1 USD cung c&#x1EA5;p &quot;m&#x1EE9;c gi&#xE1; b&#x1B0;&#x1EDB;c qua khe c&#x1EED;a&quot; l&#xFD; t&#x1B0;&#x1EDF;ng. Vi&#x1EC7;c thi&#x1EBF;t l&#x1EAD;p c&#x1EA5;p &#x111;&#x1ED9; n&#xE0;y t&#x1EA1;o ra hai t&#xE1;c &#x111;&#x1ED9;ng mang t&#xED;nh h&#x1EC7; th&#x1ED1;ng. Th&#x1EE9; nh&#x1EA5;t, n&#xF3; t&#xED;ch h&#x1EE3;p nh&#x1EEF;ng ng&#x1B0;&#x1EDD;i ch&#x1EC9; quan t&#xE2;m s&#x1A1; b&#x1ED9; v&#xE0;o lu&#x1ED3;ng giao ti&#x1EBF;p n&#x1ED9;i b&#x1ED9; c&#x1EE7;a chi&#x1EBF;n d&#x1ECB;ch, cho ph&#xE9;p h&#x1ECD; nh&#x1EAD;n c&#xE1;c b&#x1EA3;n c&#x1EAD;p nh&#x1EAD;t qua email v&#xE0; c&#xF3; quy&#x1EC1;n b&#xEC;nh lu&#x1EAD;n tr&#xEA;n trang d&#x1EF1; &#xE1;n, t&#x1EEB; &#x111;&#xF3; nh&#xE0; s&#xE1;ng l&#x1EAD;p c&#xF3; c&#x1A1; h&#x1ED9;i ch&#x103;m s&#xF3;c v&#xE0; chuy&#x1EC3;n &#x111;&#x1ED5;i h&#x1ECD; l&#xEA;n c&#xE1;c g&#xF3;i cao h&#x1A1;n trong nh&#x1EEF;ng gi&#x1EDD; cu&#x1ED1;i c&#xF9;ng c&#x1EE7;a chi&#x1EBF;n d&#x1ECB;ch (th&#x1B0;&#x1EDD;ng th&#xF4;ng qua m&#x1ED9;t email nh&#x1EAF;c nh&#x1EDF; 60 gi&#x1EDD;). Th&#x1EE9; hai, thu&#x1EAD;t to&#xE1;n x&#xE3; h&#x1ED9;i c&#x1EE7;a Kickstarter t&#x1EF1; &#x111;&#x1ED9;ng g&#x1EED;i th&#xF4;ng b&#xE1;o &#x111;&#x1EBF;n danh s&#xE1;ch b&#x1EA1;n b&#xE8; c&#x1EE7;a ng&#x1B0;&#x1EDD;i &#x1EE7;ng h&#x1ED9; m&#x1ED7;i khi h&#x1ECD; th&#x1EF1;c hi&#x1EC7;n b&#x1EA5;t k&#x1EF3; cam k&#x1EBF;t n&#xE0;o. Do &#x111;&#xF3;, m&#x1ED9;t l&#x1B0;&#x1EE3;ng l&#x1EDB;n ng&#x1B0;&#x1EDD;i &#x1EE7;ng h&#x1ED9; 1 USD s&#x1EBD; t&#x1EA1;o ra m&#x1ED9;t hi&#x1EC7;u &#x1EE9;ng g&#x1EE3;n s&#xF3;ng (ripple effect) kh&#x1ED5;ng l&#x1ED3;, qu&#x1EA3;ng b&#xE1; d&#x1EF1; &#xE1;n &#x111;&#x1EBF;n h&#xE0;ng ch&#x1EE5;c ngh&#xEC;n kh&#xE1;n gi&#x1EA3; m&#x1EDB;i ho&#xE0;n to&#xE0;n mi&#x1EC5;n ph&#xED;.</p><p>Xung quanh chi&#x1EBF;n l&#x1B0;&#x1EE3;c cung c&#x1EA5;p c&#xE1;c &#x111;&#x1EB7;c quy&#x1EC1;n mua s&#x1EDB;m (Early Bird), c&#xE1;c chuy&#xEA;n gia thi&#x1EBF;t k&#x1EBF; d&#x1EF1; &#xE1;n c&#x1EA3;nh b&#xE1;o v&#x1EC1; con dao hai l&#x1B0;&#x1EE1;i c&#x1EE7;a m&#xF4; h&#xEC;nh n&#xE0;y. Vi&#x1EC7;c thi&#x1EBF;t l&#x1EAD;p m&#x1ED9;t l&#x1B0;&#x1EE3;ng gi&#x1EDB;i h&#x1EA1;n c&#xE1;c g&#xF3;i Early Bird gi&#xE1; r&#x1EBB; c&#xF3; th&#x1EC3; t&#x1EA1;o ra &#x111;&#x1EE3;t b&#x1A1;m v&#x1ED1;n m&#x1EA1;nh m&#x1EBD; trong 24 gi&#x1EDD; &#x111;&#x1EA7;u, nh&#x1B0;ng n&#xF3; th&#x1B0;&#x1EDD;ng g&#xE2;y ra s&#x1EF1; ph&#x1EAB;n n&#x1ED9; trong c&#x1ED9;ng &#x111;&#x1ED3;ng nh&#x1EEF;ng ng&#x1B0;&#x1EDD;i &#x111;&#x1EBF;n sau, nh&#x1EEF;ng ng&#x1B0;&#x1EDD;i c&#x1EA3;m th&#x1EA5;y b&#x1ECB; tr&#x1EEB;ng ph&#x1EA1;t ch&#x1EC9; v&#xEC; h&#x1ECD; s&#x1ED1;ng &#x1EDF; m&#x1ED9;t m&#xFA;i gi&#x1EDD; kh&#xE1;c ho&#x1EB7;c kh&#xF4;ng truy c&#x1EAD;p internet v&#xE0;o &#x111;&#xFA;ng th&#x1EDD;i &#x111;i&#x1EC3;m. H&#x1EAD;u qu&#x1EA3; l&#xE0;, c&#xE1;c chi&#x1EBF;n d&#x1ECB;ch ph&#x1EE5; thu&#x1ED9;c qu&#xE1; nhi&#x1EC1;u v&#xE0;o gi&#x1EDB;i h&#x1EA1;n s&#x1ED1; l&#x1B0;&#x1EE3;ng Early Bird th&#x1B0;&#x1EDD;ng ch&#x1EE9;ng ki&#x1EBF;n t&#x1EF7; l&#x1EC7; h&#x1EE7;y cam k&#x1EBF;t (bailout rate) cao v&#xE0; &#x111;&#x1ED9;ng l&#x1B0;&#x1EE3;ng gi&#x1EA3;m s&#xFA;t nghi&#xEA;m tr&#x1ECD;ng &#x1EDF; giai &#x111;o&#x1EA1;n gi&#x1EEF;a. &#x110;&#x1EC3; kh&#x1EAF;c ph&#x1EE5;c, ph&#x1B0;&#x1A1;ng ph&#xE1;p ti&#x1EBF;p c&#x1EAD;n &#x1B0;u vi&#x1EC7;t h&#x1A1;n l&#xE0; &#xE1;p d&#x1EE5;ng m&#x1EE9;c gi&#xE1; n&#x1EC1;n t&#x1EA3;ng c&#xF4;ng b&#x1EB1;ng cho t&#x1EA5;t c&#x1EA3; m&#x1ECD;i ng&#x1B0;&#x1EDD;i ngay t&#x1EEB; &#x111;&#x1EA7;u, ho&#x1EB7;c ch&#x1EC9; s&#x1EED; d&#x1EE5;ng Early Bird d&#x1EF1;a tr&#xEA;n gi&#x1EDB;i h&#x1EA1;n th&#x1EDD;i gian m&#x1EDF; (v&#xED; d&#x1EE5;: m&#x1EDF; cho t&#x1EA5;t c&#x1EA3; m&#x1ECD;i ng&#x1B0;&#x1EDD;i trong 48 gi&#x1EDD; &#x111;&#x1EA7;u ti&#xEA;n), k&#x1EBF;t h&#x1EE3;p v&#x1EDB;i c&#xE1;c m&#x1EE5;c ti&#xEA;u m&#x1EDF; r&#x1ED9;ng (stretch goals) &#x111;&#x1EC3; duy tr&#xEC; c&#x1EA3;m gi&#xE1;c kh&#x1EA9;n c&#x1EA5;p.</p><h3 id="h%C3%ACnh-th%C3%A1i-th%E1%BA%A5t-b%E1%BA%A1i-ph%C3%A2n-t%C3%ADch-r%E1%BB%A7i-ro-h%E1%BA%ADu-g%E1%BB%8Di-v%E1%BB%91n">H&#xEC;nh Th&#xE1;i Th&#x1EA5;t B&#x1EA1;i: Ph&#xE2;n T&#xED;ch R&#x1EE7;i Ro H&#x1EAD;u G&#x1ECD;i V&#x1ED1;n</h3><p>&#x110;&#x1EA1;t &#x111;&#x1B0;&#x1EE3;c m&#x1EE5;c ti&#xEA;u t&#xE0;i tr&#x1EE3; ch&#x1EC9; l&#xE0; s&#x1EF1; kh&#x1EDF;i &#x111;&#x1EA7;u; th&#x1EA3;m h&#x1ECD;a th&#x1EF1;c s&#x1EF1; th&#x1B0;&#x1EDD;ng x&#x1EA3;y ra trong giai &#x111;o&#x1EA1;n s&#x1EA3;n xu&#x1EA5;t v&#xE0; ho&#xE0;n t&#x1EA5;t &#x111;&#x1A1;n h&#xE0;ng. M&#x1ED9;t chi&#x1EBF;n d&#x1ECB;ch &#x111;&#x1B0;&#x1EE3;c xem l&#xE0; th&#xE0;nh c&#xF4;ng r&#x1EF1;c r&#x1EE1; tr&#xEA;n b&#x1EC1; m&#x1EB7;t nh&#x1B0;ng l&#x1EA1;i s&#x1EE5;p &#x111;&#x1ED5; &#x1EDF; kh&#xE2;u h&#x1EAD;u c&#x1EA7;n s&#x1EBD; h&#x1EE7;y ho&#x1EA1;i v&#x129;nh vi&#x1EC5;n uy t&#xED;n c&#x1EE7;a nh&#xE0; s&#xE1;ng l&#x1EAD;p. D&#x1EF1; &#xE1;n <em>Coolest Cooler</em> l&#xE0; m&#x1ED9;t v&#xED; d&#x1EE5; &#x111;au x&#xF3;t v&#xE0; n&#x1ED5;i ti&#x1EBF;ng nh&#x1EA5;t trong l&#x1ECB;ch s&#x1EED; n&#x1EC1;n t&#x1EA3;ng. V&#x1EDB;i &#xFD; t&#x1B0;&#x1EDF;ng m&#x1ED9;t chi&#x1EBF;c th&#xF9;ng &#x111;&#xE1; t&#xED;ch h&#x1EE3;p m&#xE1;y xay sinh t&#x1ED1;, loa Bluetooth v&#xE0; c&#x1ED5;ng s&#x1EA1;c USB, chi&#x1EBF;n d&#x1ECB;ch &#x111;&#xE3; t&#x1EA1;o ra m&#x1ED9;t c&#x1A1;n s&#x1ED1;t truy&#x1EC1;n th&#xF4;ng, thu v&#x1EC1; con s&#x1ED1; k&#x1EF7; l&#x1EE5;c h&#x1A1;n 13,2 tri&#x1EC7;u USD t&#x1EEB; h&#x1A1;n 62.000 ng&#x1B0;&#x1EDD;i &#x1EE7;ng h&#x1ED9; v&#xE0;o n&#x103;m 2014. Tuy nhi&#xEA;n, do &#x111;&#x1ECB;nh gi&#xE1; s&#x1EA3;n ph&#x1EA9;m qu&#xE1; th&#x1EA5;p so v&#x1EDB;i chi ph&#xED; linh ki&#x1EC7;n th&#x1EF1;c t&#x1EBF;, c&#x1ED9;ng th&#xEA;m s&#x1EF1; thi&#x1EBF;u kinh nghi&#x1EC7;m trong vi&#x1EC7;c qu&#x1EA3;n l&#xFD; chu&#x1ED7;i cung &#x1EE9;ng qu&#x1ED1;c t&#x1EBF; v&#xE0; thi&#x1EBF;t k&#x1EBF; h&#x1EC7; th&#x1ED1;ng s&#x1EA3;n xu&#x1EA5;t h&#xE0;ng lo&#x1EA1;t, c&#xF4;ng ty &#x111;&#xE3; nhanh ch&#xF3;ng &#x111;&#x1ED1;t s&#x1EA1;ch v&#x1ED1;n. Nhu c&#x1EA7;u s&#x1EA3;n xu&#x1EA5;t v&#x1B0;&#x1EE3;t xa kh&#x1EA3; n&#x103;ng &#x111;&#xE1;p &#x1EE9;ng, d&#x1EAB;n &#x111;&#x1EBF;n vi&#x1EC7;c h&#x1ECD; ph&#x1EA3;i tuy&#x1EC7;t v&#x1ECD;ng y&#xEA;u c&#x1EA7;u th&#xEA;m v&#x1ED1;n t&#x1EEB; nh&#x1EEF;ng ng&#x1B0;&#x1EDD;i &#x111;&#xE3; quy&#xEA;n g&#xF3;p, cu&#x1ED1;i c&#xF9;ng n&#x1ED9;p &#x111;&#x1A1;n ph&#xE1; s&#x1EA3;n v&#xE0; &#x111;&#x1EC3; l&#x1EA1;i h&#xE0;ng ch&#x1EE5;c ngh&#xEC;n ng&#x1B0;&#x1EDD;i &#x1EE7;ng h&#x1ED9; trong s&#x1EF1; gi&#x1EAD;n d&#x1EEF; v&#xEC; kh&#xF4;ng bao gi&#x1EDD; nh&#x1EAD;n &#x111;&#x1B0;&#x1EE3;c s&#x1EA3;n ph&#x1EA9;m.</p><p>S&#x1EF1; s&#x1EE5;p &#x111;&#x1ED5; c&#x1EE7;a Coolest Cooler v&#xE0; v&#xF4; s&#x1ED1; d&#x1EF1; &#xE1;n kh&#xE1;c nh&#x1EA5;n m&#x1EA1;nh c&#xE1;c sai l&#x1EA7;m c&#x1ED1;t l&#xF5;i m&#xE0; c&#xE1;c nh&#xE0; s&#xE1;ng l&#x1EAD;p th&#x1B0;&#x1EDD;ng m&#x1EAF;c ph&#x1EA3;i :</p><ul><li><strong>Thi&#x1EBF;u s&#x1EF1; ph&#xF9; h&#x1EE3;p v&#x1EDB;i th&#x1ECB; tr&#x1B0;&#x1EDD;ng (No Market Fit):</strong> Cho d&#xF9; chi&#x1EBF;n l&#x1B0;&#x1EE3;c ti&#x1EBF;p th&#x1ECB; c&#xF3; tinh vi &#x111;&#x1EBF;n &#x111;&#xE2;u, n&#x1EBF;u th&#x1ECB; tr&#x1B0;&#x1EDD;ng kh&#xF4;ng c&#xF3; nhu c&#x1EA7;u th&#x1EF1;c s&#x1EF1; v&#x1EC1; s&#x1EA3;n ph&#x1EA9;m, chi&#x1EBF;n d&#x1ECB;ch s&#x1EBD; th&#x1EA5;t b&#x1EA1;i. Vi&#x1EC7;c b&#x1ECF; qua c&#xE1;c v&#xF2;ng th&#x1EED; nghi&#x1EC7;m m&#xF9; (blind playtesting) v&#xE0; thu th&#x1EAD;p ph&#x1EA3;n h&#x1ED3;i kh&#xE1;ch quan khi&#x1EBF;n c&#xE1;c nh&#xE0; s&#xE1;ng l&#x1EAD;p r&#x1A1;i v&#xE0;o hi&#x1EC7;u &#x1EE9;ng &quot;k&#xED;nh m&#xE0;u h&#x1ED3;ng&quot;, &#x111;&#xE1;nh gi&#xE1; qu&#xE1; cao gi&#xE1; tr&#x1ECB; s&#xE1;ng t&#x1EA1;o c&#x1EE7;a b&#x1EA3;n th&#xE2;n.</li><li><strong>Chi&#x1EBF;n l&#x1B0;&#x1EE3;c &#x110;&#x1ECB;nh gi&#xE1; L&#x1ED7; h&#x1ED5;ng:</strong> C&#xE1;c nh&#xE0; s&#xE1;ng l&#x1EAD;p th&#x1B0;&#x1EDD;ng qu&#xEA;n t&#xED;nh to&#xE1;n chi ph&#xED; v&#x1EAD;n chuy&#x1EC3;n qu&#x1ED1;c t&#x1EBF; &#x111;ang ng&#xE0;y c&#xE0;ng bi&#x1EBF;n &#x111;&#x1ED9;ng, thu&#x1EBF; quan, chi ph&#xED; kho b&#xE3;i ch&#x1ECD;n v&#xE0; &#x111;&#xF3;ng g&#xF3;i (pick and pack), c&#x169;ng nh&#x1B0; kho&#x1EA3;n ph&#xED; b&#x1EAF;t bu&#x1ED9;c 5% c&#x1EE7;a Kickstarter v&#xE0; t&#x1EEB; 3-5% ph&#xED; x&#x1EED; l&#xFD; th&#x1EBB; t&#xED;n d&#x1EE5;ng. S&#x1EF1; ch&#xEA;nh l&#x1EC7;ch n&#xE0;y &#x103;n m&#xF2;n bi&#xEA;n l&#x1EE3;i nhu&#x1EAD;n, bi&#x1EBF;n m&#x1ED9;t d&#x1EF1; &#xE1;n v&#x1B0;&#x1EE3;t m&#x1EE5;c ti&#xEA;u th&#xE0;nh m&#x1ED9;t g&#xE1;nh n&#x1EB7;ng n&#x1EE3; n&#x1EA7;n.</li><li><strong>S&#x1EF1; ph&#x1EE9;c t&#x1EA1;p h&#xF3;a qu&#xE1; m&#x1EE9;c:</strong> Vi&#x1EC7;c cung c&#x1EA5;p qu&#xE1; nhi&#x1EC1;u c&#x1EA5;p &#x111;&#x1ED9; ph&#x1EA7;n th&#x1B0;&#x1EDF;ng, v&#xF4; s&#x1ED1; ti&#x1EC7;n &#xED;ch b&#x1ED5; sung (add-ons) v&#xE0; c&#xE1;c m&#x1EE5;c ti&#xEA;u m&#x1EDF; r&#x1ED9;ng (stretch goals) phi th&#x1EF1;c t&#x1EBF; khi&#x1EBF;n chi ph&#xED; s&#x1EA3;n xu&#x1EA5;t t&#x103;ng theo c&#x1EA5;p s&#x1ED1; nh&#xE2;n, ph&#xE1; v&#x1EE1; c&#x1EA5;u tr&#xFA;c chu&#x1ED7;i cung &#x1EE9;ng.</li><li><strong>Tr&#x1ED1;ng r&#x1ED7;ng trong giao ti&#x1EBF;p:</strong> S&#x1EF1; im l&#x1EB7;ng c&#x1EE7;a nh&#xE0; s&#xE1;ng l&#x1EAD;p sau khi nh&#x1EAD;n ti&#x1EC1;n l&#xE0; y&#x1EBF;u t&#x1ED1; t&#xE0;n ph&#xE1; ni&#x1EC1;m tin nhanh nh&#x1EA5;t. C&#xE1;c d&#x1EF1; &#xE1;n th&#xE0;nh c&#xF4;ng lu&#xF4;n duy tr&#xEC; m&#x1ED9;t t&#x1EA7;n su&#x1EA5;t c&#x1EAD;p nh&#x1EAD;t minh b&#x1EA1;ch, chia s&#x1EBB; ch&#xE2;n th&#x1EF1;c v&#x1EC1; nh&#x1EEF;ng kh&#xF3; kh&#x103;n trong s&#x1EA3;n xu&#x1EA5;t, s&#x1EF1; ch&#x1EAD;m tr&#x1EC5; c&#x1EE7;a nh&#xE0; m&#xE1;y, thay v&#xEC; che gi&#x1EA5;u s&#x1EF1; th&#x1EAD;t &#x111;&#x1EC3; b&#x1EA3;o v&#x1EC7; h&#xEC;nh &#x1EA3;nh.</li></ul><hr><h2 id="ph%E1%BA%A7n-ii-ngh%E1%BB%8Bch-l%C3%BD-th%C6%B0%C6%A1ng-m%E1%BA%A1i-h%C3%B3a-ph%E1%BA%A7n-m%E1%BB%81m-m%C3%A3-ngu%E1%BB%93n-m%E1%BB%9F-oss">Ph&#x1EA7;n II: Ngh&#x1ECB;ch L&#xFD; Th&#x1B0;&#x1A1;ng M&#x1EA1;i H&#xF3;a Ph&#x1EA7;n M&#x1EC1;m M&#xE3; Ngu&#x1ED3;n M&#x1EDF; (OSS)</h2><p>Chuy&#x1EC3;n &#x111;&#x1ED5;i t&#x1EEB; kh&#xF4;ng gian s&#x1EA3;n ph&#x1EA9;m v&#x1EAD;t l&#xFD; sang l&#xE3;nh &#x111;&#x1ECB;a ph&#x1EA7;n m&#x1EC1;m m&#xE3; ngu&#x1ED3;n m&#x1EDF; (OSS) &#x111;&#x1ED3;ng ngh&#x129;a v&#x1EDB;i vi&#x1EC7;c &#x111;&#x1ED1;i m&#x1EB7;t v&#x1EDB;i m&#x1ED9;t m&#xF4; h&#xEC;nh t&#xE0;i ch&#xED;nh mang t&#xED;nh ngh&#x1ECB;ch l&#xFD;: L&#xE0;m th&#x1EBF; n&#xE0;o &#x111;&#x1EC3; t&#x1EA1;o ra m&#x1ED9;t lu&#x1ED3;ng doanh thu hi&#x1EC7;u qu&#x1EA3; v&#xE0; c&#xF3; th&#x1EC3; m&#x1EDF; r&#x1ED9;ng t&#x1EEB; m&#x1ED9;t h&#x1EC7; th&#x1ED1;ng m&#xE0; t&#xE0;i s&#x1EA3;n c&#x1ED1;t l&#xF5;i c&#x1EE7;a n&#xF3; &#x2014; d&#xF2;ng m&#xE3; ph&#x1EA7;n m&#x1EC1;m &#x2014; &#x111;&#x1B0;&#x1EE3;c cung c&#x1EA5;p mi&#x1EC5;n ph&#xED; cho to&#xE0;n th&#x1EBF; gi&#x1EDB;i?</p><p>M&#xE3; ngu&#x1ED3;n m&#x1EDF; kh&#xF4;ng c&#xF2;n l&#xE0; s&#xE2;n ch&#x1A1;i c&#x1EE7;a nh&#x1EEF;ng tin t&#x1EB7;c &#x111;am m&#xEA; l&#xE0;m vi&#x1EC7;c t&#x1EF1; nguy&#x1EC7;n v&#xE0;o cu&#x1ED1;i tu&#x1EA7;n. N&#xF3; &#x111;&#xE3; tr&#x1EDF; th&#xE0;nh x&#x1B0;&#x1A1;ng s&#x1ED1;ng c&#x1EE7;a c&#x1A1; s&#x1EDF; h&#x1EA1; t&#x1EA7;ng c&#xF4;ng ngh&#x1EC7; to&#xE0;n c&#x1EA7;u, cung c&#x1EA5;p s&#x1EE9;c m&#x1EA1;nh cho m&#x1ECD;i th&#x1EE9; t&#x1EEB; d&#x1ECB;ch v&#x1EE5; &#x111;&#xE1;m m&#xE2;y, tr&#xED; tu&#x1EC7; nh&#xE2;n t&#x1EA1;o, &#x111;&#x1EBF;n c&#xE1;c h&#x1EC7; th&#x1ED1;ng t&#xE0;i ch&#xED;nh ph&#x1EE9;c t&#x1EA1;p. Tuy nhi&#xEA;n, m&#x1EB7;c d&#xF9; t&#x1EA1;o ra h&#xE0;ng ngh&#xEC;n t&#x1EF7; &#x111;&#xF4; la gi&#xE1; tr&#x1ECB; th&#x1EB7;ng d&#x1B0; cho c&#xE1;c t&#x1EAD;p &#x111;o&#xE0;n c&#xF4;ng ngh&#x1EC7;, vi&#x1EC7;c thu th&#x1EAD;p l&#x1EA1;i m&#x1ED9;t ph&#x1EA7;n nh&#x1ECF; gi&#xE1; tr&#x1ECB; &#x111;&#xF3; &#x111;&#x1EC3; duy tr&#xEC; s&#x1EF1; ph&#xE1;t tri&#x1EC3;n b&#x1EC1;n v&#x1EEF;ng c&#x1EE7;a ch&#xED;nh c&#xE1;c d&#x1EF1; &#xE1;n OSS l&#x1EA1;i l&#xE0; m&#x1ED9;t b&#xE0;i to&#xE1;n h&#xF3;c b&#xFA;a. C&#xE1;c m&#xF4; h&#xEC;nh c&#x1EA5;p ph&#xE9;p d&#x1EC5; d&#xE3;i truy&#x1EC1;n th&#x1ED1;ng khi&#x1EBF;n c&#xE1;c nh&#xE0; s&#xE1;ng l&#x1EAD;p li&#xEA;n t&#x1EE5;c b&#x1ECB; ch&#x1EA3;y m&#xE1;u ch&#x1EA5;t x&#xE1;m v&#xE0; ki&#x1EC7;t qu&#x1EC7; t&#xE0;i ch&#xED;nh. S&#x1EF1; ki&#x1EC7;t s&#x1EE9;c (burnout) c&#x1EE7;a c&#xE1;c nh&#xE0; duy tr&#xEC; (maintainers) &#x111;ang tr&#x1EDF; th&#xE0;nh m&#x1ED9;t cu&#x1ED9;c kh&#x1EE7;ng ho&#x1EA3;ng mang t&#xED;nh h&#x1EC7; th&#x1ED1;ng.</p><p>&#x110;&#x1EC3; s&#x1ED1;ng s&#xF3;t v&#xE0; ph&#xE1;t tri&#x1EC3;n, c&#xE1;c d&#x1EF1; &#xE1;n OSS hi&#x1EC7;n &#x111;&#x1EA1;i bu&#x1ED9;c ph&#x1EA3;i t&#x1EEB; b&#x1ECF; s&#x1EF1; ng&#xE2;y th&#x1A1; phi l&#x1EE3;i nhu&#x1EAD;n &#x111;&#x1EC3; &#xE1;p d&#x1EE5;ng c&#xE1;c m&#xF4; h&#xEC;nh kinh doanh v&#xE0; c&#x1EA5;p ph&#xE9;p chi&#x1EBF;n l&#x1B0;&#x1EE3;c, thi&#x1EBF;t l&#x1EAD;p m&#x1ED9;t ranh gi&#x1EDB;i r&#xF5; r&#xE0;ng gi&#x1EEF;a gi&#xE1; tr&#x1ECB; c&#x1ED9;ng &#x111;&#x1ED3;ng v&#xE0; gi&#xE1; tr&#x1ECB; doanh nghi&#x1EC7;p.</p><h3 id="c%C3%A1c-ph%C3%A2n-t%E1%BA%A7ng-m%C3%B4-h%C3%ACnh-kinh-doanh-m%C3%A3-ngu%E1%BB%93n-m%E1%BB%9F">C&#xE1;c Ph&#xE2;n T&#x1EA7;ng M&#xF4; H&#xEC;nh Kinh Doanh M&#xE3; Ngu&#x1ED3;n M&#x1EDF;</h3><p>Th&#x1B0;&#x1A1;ng m&#x1EA1;i h&#xF3;a OSS kh&#xF4;ng ph&#x1EA3;i l&#xE0; m&#x1ED9;t gi&#x1EA3;i ph&#xE1;p &#x111;&#x1A1;n l&#x1EBB;, m&#xE0; l&#xE0; m&#x1ED9;t ph&#x1ED5; r&#x1ED9;ng c&#xE1;c chi&#x1EBF;n l&#x1B0;&#x1EE3;c &#x111;&#x1B0;&#x1EE3;c l&#x1EF1;a ch&#x1ECD;n d&#x1EF1;a tr&#xEA;n m&#x1EE9;c &#x111;&#x1ED9; ph&#x1EE9;c t&#x1EA1;p c&#x1EE7;a c&#x1A1; s&#x1EDF; h&#x1EA1; t&#x1EA7;ng v&#xE0; &#x111;&#x1ED1;i t&#x1B0;&#x1EE3;ng kh&#xE1;ch h&#xE0;ng m&#x1EE5;c ti&#xEA;u. D&#x1B0;&#x1EDB;i &#x111;&#xE2;y l&#xE0; ki&#x1EBF;n tr&#xFA;c c&#x1EE7;a c&#xE1;c m&#xF4; h&#xEC;nh kinh doanh c&#x1ED1;t l&#xF5;i :</p><!--kg-card-begin: html--><table data-path-to-node="35" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(240, 244, 249); border: 0px none rgb(128, 128, 128); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 32px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><thead style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(128, 128, 128); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-header-group; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><tr style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(128, 128, 128); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-row; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><strong style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">M&#xF4; H&#xEC;nh Th&#x1B0;&#x1A1;ng M&#x1EA1;i H&#xF3;a OSS</strong></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><strong style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">Nguy&#xEA;n L&#xFD; Ho&#x1EA1;t &#x110;&#x1ED9;ng &amp; C&#x1A1; Ch&#x1EBF; Thi&#x1EBF;t L&#x1EAD;p</strong></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><strong style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">&#x110;i&#x1EC3;m M&#x1EA1;nh &amp; L&#x1EE3;i Th&#x1EBF; C&#x1EA1;nh Tranh</strong></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><strong style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">R&#x1EE7;i Ro &amp; Th&#xE1;ch Th&#x1EE9;c K&#x1EF9; Thu&#x1EAD;t</strong></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><strong style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">Case Study N&#x1ED5;i B&#x1EAD;t</strong></td></tr></thead><tbody style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(128, 128, 128); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-row-group; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><tr style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(128, 128, 128); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-row; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="35,1,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><strong data-path-to-node="35,1,0,0" data-index-in-node="0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">C&#x1ED1;t L&#xF5;i M&#x1EDF; (Open Core)</strong></span></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><p data-path-to-node="35,1,1,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="35,1,1,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">C&#xF4;ng ty ph&#xE1;t tri&#x1EC3;n song song hai phi&#xEA;n b&#x1EA3;n. M&#xE3; l&#xF5;i c&#x1EE7;a ph&#x1EA7;n m&#x1EC1;m &#x111;&#x1B0;&#x1EE3;c m&#x1EDF; ho&#xE0;n to&#xE0;n v&#x1EDB;i c&#xE1;c gi&#x1EA5;y ph&#xE9;p d&#x1EC5; d&#xE3;i (MIT, Apache). Tuy nhi&#xEA;n, c&#xE1;c t&#xED;nh n&#x103;ng h&#x1B0;&#x1EDB;ng t&#x1EDB;i qu&#x1EA3;n tr&#x1ECB; quy m&#xF4; l&#x1EDB;n, b&#x1EA3;o m&#x1EAD;t n&#xE2;ng cao (nh&#x1B0; t&#xED;ch h&#x1EE3;p SSO, tu&#xE2;n th&#x1EE7; d&#x1EEF; li&#x1EC7;u) b&#x1ECB; kh&#xF3;a trong m&#x1ED9;t phi&#xEA;n b&#x1EA3;n Th&#x1B0;&#x1A1;ng m&#x1EA1;i (Enterprise Edition) &#x111;&#x1ED9;c quy&#x1EC1;n. </span><span data-path-to-node="35,1,1,0,1" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><response-element class ng-version="0.0.0-PLACEHOLDER" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><source-footnote _nghost-ng-c617374649 class="ng-star-inserted" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><sup _ngcontent-ng-c617374649 class="superscript" data-turn-source-index="35" style="animation: auto ease 0s 1 normal none running none; appearance: none; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; background-color: transparent !important; border: 0px none rgb(68, 71, 70); inset: -10px 2px 10px -2px; clear: none; clip: auto; color: rgb(68, 71, 70); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline-flex; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: -6px; margin-bottom: 0px; margin-left: -6px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(68, 71, 70) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: relative; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important; font-size: 16px !important;"><!----></sup></source-footnote><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----></response-element></span></span></p></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><p data-path-to-node="35,1,2,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="35,1,2,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">T&#x1ED1;i &#x1B0;u h&#xF3;a ph&#x1EC5;u kh&#xE1;ch h&#xE0;ng. Phi&#xEA;n b&#x1EA3;n mi&#x1EC5;n ph&#xED; &#x111;&#xF3;ng vai tr&#xF2; nh&#x1B0; m&#x1ED9;t c&#xF4;ng c&#x1EE5; ti&#x1EBF;p th&#x1ECB; (lead generation) lan truy&#x1EC1;n m&#x1EA1;nh m&#x1EBD;, trong khi c&#xE1;c doanh nghi&#x1EC7;p l&#x1EDB;n s&#x1EB5;n s&#xE0;ng tr&#x1EA3; ph&#xED; cao cho t&#xED;nh n&#x103;ng qu&#x1EA3;n tr&#x1ECB;. </span><span data-path-to-node="35,1,2,0,1" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><response-element class ng-version="0.0.0-PLACEHOLDER" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><source-footnote _nghost-ng-c617374649 class="ng-star-inserted" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><sup _ngcontent-ng-c617374649 class="superscript" data-turn-source-index="35" style="animation: auto ease 0s 1 normal none running none; appearance: none; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; background-color: transparent !important; border: 0px none rgb(68, 71, 70); inset: -10px 2px 10px -2px; clear: none; clip: auto; color: rgb(68, 71, 70); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline-flex; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: -6px; margin-bottom: 0px; margin-left: -6px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(68, 71, 70) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: relative; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important; font-size: 16px !important;"><!----></sup></source-footnote><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----></response-element></span></span></p></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><p data-path-to-node="35,1,3,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="35,1,3,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">&#xC1;p l&#x1EF1;c v&#x1EAD;n h&#xE0;nh hai c&#x1A1; s&#x1EDF; m&#xE3; (codebase) ri&#xEA;ng bi&#x1EC7;t. Th&#x1B0;&#x1EDD;ng xuy&#xEA;n &#x111;&#x1ED1;i m&#x1EB7;t v&#x1EDB;i s&#x1EF1; ch&#x1EC9; tr&#xED;ch t&#x1EEB; c&#x1ED9;ng &#x111;&#x1ED3;ng v&#x1EC1; vi&#x1EC7;c c&#x1ED1; t&#xEC;nh l&#xE0;m suy y&#x1EBF;u phi&#xEA;n b&#x1EA3;n mi&#x1EC5;n ph&#xED; &#x111;&#x1EC3; &#xE9;p bu&#x1ED9;c n&#xE2;ng c&#x1EA5;p (crippleware). </span><span data-path-to-node="35,1,3,0,1" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><response-element class ng-version="0.0.0-PLACEHOLDER" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><source-footnote _nghost-ng-c617374649 class="ng-star-inserted" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><sup _ngcontent-ng-c617374649 class="superscript" data-turn-source-index="35" style="animation: auto ease 0s 1 normal none running none; appearance: none; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; background-color: transparent !important; border: 0px none rgb(68, 71, 70); inset: -10px 2px 10px -2px; clear: none; clip: auto; color: rgb(68, 71, 70); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline-flex; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: -6px; margin-bottom: 0px; margin-left: -6px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(68, 71, 70) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: relative; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important; font-size: 16px !important;"><!----></sup></source-footnote><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----></response-element></span></span></p></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><p data-path-to-node="35,1,4,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="35,1,4,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">GitLab, Elastic, Confluent (Apache Kafka). </span><span data-path-to-node="35,1,4,0,1" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><response-element class ng-version="0.0.0-PLACEHOLDER" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><source-footnote _nghost-ng-c617374649 class="ng-star-inserted" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><sup _ngcontent-ng-c617374649 class="superscript" data-turn-source-index="35" style="animation: auto ease 0s 1 normal none running none; appearance: none; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; background-color: transparent !important; border: 0px none rgb(68, 71, 70); inset: -10px 2px 10px -2px; clear: none; clip: auto; color: rgb(68, 71, 70); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline-flex; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: -6px; margin-bottom: 0px; margin-left: -6px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(68, 71, 70) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: relative; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important; font-size: 16px !important;"><!----></sup></source-footnote><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----></response-element></span></span></p></td></tr><tr style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(128, 128, 128); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-row; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="35,2,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><strong data-path-to-node="35,2,0,0" data-index-in-node="0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">C&#x1EA5;p Ph&#xE9;p K&#xE9;p (Dual Licensing)</strong></span></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><p data-path-to-node="35,2,1,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="35,2,1,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">Ph&#xE2;n ph&#x1ED1;i c&#xF9;ng m&#x1ED9;t ph&#x1EA7;n m&#x1EC1;m, kh&#xF4;ng gi&#x1EDB;i h&#x1EA1;n t&#xED;nh n&#x103;ng, d&#x1B0;&#x1EDB;i hai khu&#xF4;n kh&#x1ED5; ph&#xE1;p l&#xFD; song song: m&#x1ED9;t gi&#x1EA5;y ph&#xE9;p Ngu&#x1ED3;n m&#x1EDF; Copyleft nghi&#xEA;m ng&#x1EB7;t (nh&#x1B0; GPL ho&#x1EB7;c AGPL) v&#xE0; m&#x1ED9;t Gi&#x1EA5;y ph&#xE9;p Th&#x1B0;&#x1A1;ng m&#x1EA1;i ti&#xEA;u chu&#x1EA9;n. </span><span data-path-to-node="35,2,1,0,1" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><response-element class ng-version="0.0.0-PLACEHOLDER" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><source-footnote _nghost-ng-c617374649 class="ng-star-inserted" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><sup _ngcontent-ng-c617374649 class="superscript" data-turn-source-index="37" style="animation: auto ease 0s 1 normal none running none; appearance: none; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; background-color: transparent !important; border: 0px none rgb(68, 71, 70); inset: -10px 2px 10px -2px; clear: none; clip: auto; color: rgb(68, 71, 70); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline-flex; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: -6px; margin-bottom: 0px; margin-left: -6px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(68, 71, 70) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: relative; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important; font-size: 16px !important;"><!----></sup></source-footnote><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----></response-element></span></span></p></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><p data-path-to-node="35,2,2,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="35,2,2,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">S&#x1EED; d&#x1EE5;ng s&#x1EE9;c m&#x1EA1;nh ph&#xE1;p l&#xFD; l&#xE0;m &#x111;&#xF2;n b&#x1EA9;y. &#xC9;p bu&#x1ED9;c c&#xE1;c doanh nghi&#x1EC7;p (v&#x1ED1;n kh&#xF4;ng mu&#x1ED1;n m&#xE3; ngu&#x1ED3;n ph&#x1EA7;n m&#x1EC1;m c&#x1EE7;a m&#xEC;nh b&#x1ECB; c&#xF4;ng khai theo y&#xEA;u c&#x1EA7;u c&#x1EE7;a GPL/AGPL) ph&#x1EA3;i &#x111;&#xE0;m ph&#xE1;n mua gi&#x1EA5;y ph&#xE9;p th&#x1B0;&#x1A1;ng m&#x1EA1;i &#x111;&#x1EC3; s&#x1EED; d&#x1EE5;ng m&#xE3; m&#x1ED9;t c&#xE1;ch ri&#xEA;ng t&#x1B0;. </span><span data-path-to-node="35,2,2,0,1" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><response-element class ng-version="0.0.0-PLACEHOLDER" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><source-footnote _nghost-ng-c617374649 class="ng-star-inserted" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><sup _ngcontent-ng-c617374649 class="superscript" data-turn-source-index="37" style="animation: auto ease 0s 1 normal none running none; appearance: none; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; background-color: transparent !important; border: 0px none rgb(68, 71, 70); inset: -10px 2px 10px -2px; clear: none; clip: auto; color: rgb(68, 71, 70); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline-flex; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: -6px; margin-bottom: 0px; margin-left: -6px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(68, 71, 70) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: relative; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important; font-size: 16px !important;"><!----></sup></source-footnote><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----></response-element></span></span></p></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><p data-path-to-node="35,2,3,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="35,2,3,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">&#x110;&#xF2;i h&#x1ECF;i nh&#xE0; s&#xE1;ng l&#x1EAD;p ph&#x1EA3;i s&#x1EDF; h&#x1EEF;u 100% b&#x1EA3;n quy&#x1EC1;n m&#xE3; ngu&#x1ED3;n. Ph&#x1EA3;i y&#xEA;u c&#x1EA7;u c&#xE1;c c&#x1ED9;ng t&#xE1;c vi&#xEA;n b&#xEA;n ngo&#xE0;i k&#xFD; Th&#x1ECF;a thu&#x1EAD;n Chuy&#x1EC3;n nh&#x1B0;&#x1EE3;ng B&#x1EA3;n quy&#x1EC1;n (CLA), g&#xE2;y c&#x1EA3;n tr&#x1EDF; &#x111;&#xF3;ng g&#xF3;p t&#x1EEB; c&#x1ED9;ng &#x111;&#x1ED3;ng. </span><span data-path-to-node="35,2,3,0,1" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><response-element class ng-version="0.0.0-PLACEHOLDER" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><source-footnote _nghost-ng-c617374649 class="ng-star-inserted" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><sup _ngcontent-ng-c617374649 class="superscript" data-turn-source-index="38" style="animation: auto ease 0s 1 normal none running none; appearance: none; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; background-color: transparent !important; border: 0px none rgb(68, 71, 70); inset: -10px 2px 10px -2px; clear: none; clip: auto; color: rgb(68, 71, 70); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline-flex; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: -6px; margin-bottom: 0px; margin-left: -6px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(68, 71, 70) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: relative; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important; font-size: 16px !important;"><!----></sup></source-footnote><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----></response-element></span></span></p></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><p data-path-to-node="35,2,4,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="35,2,4,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">MySQL, Qt, Red Hat. </span><span data-path-to-node="35,2,4,0,1" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><response-element class ng-version="0.0.0-PLACEHOLDER" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><source-footnote _nghost-ng-c617374649 class="ng-star-inserted" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><sup _ngcontent-ng-c617374649 class="superscript" data-turn-source-index="35" style="animation: auto ease 0s 1 normal none running none; appearance: none; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; background-color: transparent !important; border: 0px none rgb(68, 71, 70); inset: -10px 2px 10px -2px; clear: none; clip: auto; color: rgb(68, 71, 70); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline-flex; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: -6px; margin-bottom: 0px; margin-left: -6px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(68, 71, 70) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: relative; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important; font-size: 16px !important;"><!----></sup></source-footnote><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----></response-element></span></span></p></td></tr><tr style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(128, 128, 128); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-row; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="35,3,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><strong data-path-to-node="35,3,0,0" data-index-in-node="0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">L&#x1B0;u Tr&#x1EEF; &#x110;&#xE1;m M&#xE2;y (SaaS Hosting)</strong></span></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><p data-path-to-node="35,3,1,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="35,3,1,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">Ph&#x1EA7;n m&#x1EC1;m c&#x1ED1;t l&#xF5;i mi&#x1EC5;n ph&#xED; v&#xE0; kh&#xF4;ng b&#x1ECB; kh&#xF3;a t&#xED;nh n&#x103;ng. Tuy nhi&#xEA;n, thay v&#xEC; y&#xEA;u c&#x1EA7;u kh&#xE1;ch h&#xE0;ng t&#x1EF1; tri&#x1EC3;n khai v&#xE0; b&#x1EA3;o tr&#xEC; tr&#xEA;n m&#xE1;y ch&#x1EE7; c&#x1EE7;a h&#x1ECD;, c&#xF4;ng ty cung c&#x1EA5;p d&#x1ECB;ch v&#x1EE5; qu&#x1EA3;n l&#xFD; h&#x1EA1; t&#x1EA7;ng &#x111;&#xE1;m m&#xE2;y to&#xE0;n di&#x1EC7;n, thu ph&#xED; theo m&#xF4; h&#xEC;nh thu&#xEA; bao (subscription) ho&#x1EB7;c l&#x1B0;u l&#x1B0;&#x1EE3;ng s&#x1EED; d&#x1EE5;ng (usage-based). </span><span data-path-to-node="35,3,1,0,1" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><response-element class ng-version="0.0.0-PLACEHOLDER" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><source-footnote _nghost-ng-c617374649 class="ng-star-inserted" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><sup _ngcontent-ng-c617374649 class="superscript" data-turn-source-index="35" style="animation: auto ease 0s 1 normal none running none; appearance: none; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; background-color: transparent !important; border: 0px none rgb(68, 71, 70); inset: -10px 2px 10px -2px; clear: none; clip: auto; color: rgb(68, 71, 70); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline-flex; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: -6px; margin-bottom: 0px; margin-left: -6px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(68, 71, 70) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: relative; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important; font-size: 16px !important;"><!----></sup></source-footnote><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----></response-element></span></span></p></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><p data-path-to-node="35,3,2,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="35,3,2,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">T&#x1EA1;o ra d&#xF2;ng doanh thu &#x111;&#x1ECB;nh k&#x1EF3; &#x111;&#x1ECB;nh gi&#xE1; cao (MRR). Thu h&#xFA;t c&#xE1;c doanh nghi&#x1EC7;p mu&#x1ED1;n gi&#x1EA3;m t&#x1EA3;i g&#xE1;nh n&#x1EB7;ng cho &#x111;&#x1ED9;i ng&#x169; DevOps. C&#xF4;ng ty gi&#x1EEF; to&#xE0;n quy&#x1EC1;n ki&#x1EC3;m so&#xE1;t m&#xF4;i tr&#x1B0;&#x1EDD;ng n&#xE2;ng c&#x1EA5;p. </span><span data-path-to-node="35,3,2,0,1" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><response-element class ng-version="0.0.0-PLACEHOLDER" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><source-footnote _nghost-ng-c617374649 class="ng-star-inserted" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><sup _ngcontent-ng-c617374649 class="superscript" data-turn-source-index="35" style="animation: auto ease 0s 1 normal none running none; appearance: none; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; background-color: transparent !important; border: 0px none rgb(68, 71, 70); inset: -10px 2px 10px -2px; clear: none; clip: auto; color: rgb(68, 71, 70); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline-flex; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: -6px; margin-bottom: 0px; margin-left: -6px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(68, 71, 70) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: relative; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important; font-size: 16px !important;"><!----></sup></source-footnote><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----></response-element></span></span></p></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><p data-path-to-node="35,3,3,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="35,3,3,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">&#x110;&#xF2;i h&#x1ECF;i chi ph&#xED; &#x111;&#x1EA7;u t&#x1B0; h&#x1EA1; t&#x1EA7;ng kh&#x1ED5;ng l&#x1ED3; v&#xE0; &#x111;&#x1ED9;i ng&#x169; K&#x1EF9; s&#x1B0; &#x110;&#x1ED9; tin c&#x1EAD;y (SRE) t&#xFA;c tr&#x1EF1;c 24/7. Ph&#x1EA3;i &#x111;&#x1ED1;i m&#x1EB7;t v&#x1EDB;i c&#x1EA1;nh tranh tr&#x1EF1;c ti&#x1EBF;p t&#x1EEB; c&#xE1;c Hyperscaler nh&#x1B0; AWS hay Google Cloud. </span><span data-path-to-node="35,3,3,0,1" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><response-element class ng-version="0.0.0-PLACEHOLDER" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><source-footnote _nghost-ng-c617374649 class="ng-star-inserted" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><sup _ngcontent-ng-c617374649 class="superscript" data-turn-source-index="35" style="animation: auto ease 0s 1 normal none running none; appearance: none; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; background-color: transparent !important; border: 0px none rgb(68, 71, 70); inset: -10px 2px 10px -2px; clear: none; clip: auto; color: rgb(68, 71, 70); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline-flex; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: -6px; margin-bottom: 0px; margin-left: -6px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(68, 71, 70) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: relative; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important; font-size: 16px !important;"><!----></sup></source-footnote><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----></response-element></span></span></p></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><p data-path-to-node="35,3,4,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="35,3,4,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">Vercel (&#x111;&#x1EE9;ng sau Next.js), WordPress.com. </span><span data-path-to-node="35,3,4,0,1" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><response-element class ng-version="0.0.0-PLACEHOLDER" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><source-footnote _nghost-ng-c617374649 class="ng-star-inserted" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><sup _ngcontent-ng-c617374649 class="superscript" data-turn-source-index="35" style="animation: auto ease 0s 1 normal none running none; appearance: none; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; background-color: transparent !important; border: 0px none rgb(68, 71, 70); inset: -10px 2px 10px -2px; clear: none; clip: auto; color: rgb(68, 71, 70); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline-flex; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: -6px; margin-bottom: 0px; margin-left: -6px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(68, 71, 70) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: relative; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important; font-size: 16px !important;"><!----></sup></source-footnote><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----></response-element></span></span></p></td></tr><tr style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(128, 128, 128); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-row; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="35,4,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><strong data-path-to-node="35,4,0,0" data-index-in-node="0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">D&#x1ECB;ch V&#x1EE5; &amp; H&#x1ED7; Tr&#x1EE3; Chuy&#xEA;n Nghi&#x1EC7;p (Professional Services/Support)</strong></span></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><p data-path-to-node="35,4,1,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="35,4,1,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">Ph&#x1EA7;n m&#x1EC1;m m&#xE3; ngu&#x1ED3;n m&#x1EDF; ho&#xE0;n to&#xE0;n mi&#x1EC5;n ph&#xED;. Doanh thu &#x111;&#x1B0;&#x1EE3;c t&#x1EA1;o ra th&#xF4;ng qua vi&#x1EC7;c cung c&#x1EA5;p c&#xE1;c h&#x1EE3;p &#x111;&#x1ED3;ng b&#x1EA3;o tr&#xEC;, &#x111;&#xE0;o t&#x1EA1;o nh&#xE2;n s&#x1EF1;, ch&#x1EE9;ng nh&#x1EAD;n b&#x1EA3;o m&#x1EAD;t, v&#xE0; cam k&#x1EBF;t m&#x1EE9;c &#x111;&#x1ED9; d&#x1ECB;ch v&#x1EE5; (SLA) kh&#x1EAF;c ph&#x1EE5;c s&#x1EF1; c&#x1ED1; trong v&#xF2;ng v&#xE0;i gi&#x1EDD;. </span><span data-path-to-node="35,4,1,0,1" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><response-element class ng-version="0.0.0-PLACEHOLDER" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><source-footnote _nghost-ng-c617374649 class="ng-star-inserted" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><sup _ngcontent-ng-c617374649 class="superscript" data-turn-source-index="35" style="animation: auto ease 0s 1 normal none running none; appearance: none; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; background-color: transparent !important; border: 0px none rgb(68, 71, 70); inset: -10px 2px 10px -2px; clear: none; clip: auto; color: rgb(68, 71, 70); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline-flex; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: -6px; margin-bottom: 0px; margin-left: -6px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(68, 71, 70) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: relative; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important; font-size: 16px !important;"><!----></sup></source-footnote><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----></response-element></span></span></p></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><p data-path-to-node="35,4,2,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="35,4,2,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">Gi&#x1EA3;m thi&#x1EC3;u ma s&#xE1;t &#xE1;p d&#x1EE5;ng &#x111;&#x1EBF;n m&#x1EE9;c t&#x1ED1;i &#x111;a do kh&#xF4;ng c&#xF3; r&#xE0;o c&#x1EA3;n chi ph&#xED; ph&#x1EA7;n m&#x1EC1;m. R&#x1EA5;t ph&#xF9; h&#x1EE3;p v&#x1EDB;i c&#xE1;c c&#xF4;ng c&#x1EE5; h&#x1EA1; t&#x1EA7;ng m&#x1EA1;ng ph&#x1EE9;c t&#x1EA1;p m&#xE0; doanh nghi&#x1EC7;p s&#x1EE3; g&#x1EB7;p r&#x1EE7;i ro ng&#x1EEB;ng ho&#x1EA1;t &#x111;&#x1ED9;ng (downtime). </span><span data-path-to-node="35,4,2,0,1" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><response-element class ng-version="0.0.0-PLACEHOLDER" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><source-footnote _nghost-ng-c617374649 class="ng-star-inserted" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><sup _ngcontent-ng-c617374649 class="superscript" data-turn-source-index="35" style="animation: auto ease 0s 1 normal none running none; appearance: none; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; background-color: transparent !important; border: 0px none rgb(68, 71, 70); inset: -10px 2px 10px -2px; clear: none; clip: auto; color: rgb(68, 71, 70); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline-flex; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: -6px; margin-bottom: 0px; margin-left: -6px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(68, 71, 70) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: relative; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important; font-size: 16px !important;"><!----></sup></source-footnote><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----></response-element></span></span></p></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><p data-path-to-node="35,4,3,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="35,4,3,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">M&#xF4; h&#xEC;nh n&#xE0;y c&#xF3; kh&#x1EA3; n&#x103;ng m&#x1EDF; r&#x1ED9;ng (scalability) c&#x1EF1;c th&#x1EA5;p do ph&#x1EE5; thu&#x1ED9;c tuy&#x1EBF;n t&#xED;nh v&#xE0;o quy m&#xF4; &#x111;&#x1ED9;i ng&#x169; chuy&#xEA;n gia con ng&#x1B0;&#x1EDD;i. Bi&#xEA;n l&#x1EE3;i nhu&#x1EAD;n th&#x1EA5;p h&#x1A1;n nhi&#x1EC1;u so v&#x1EDB;i vi&#x1EC7;c b&#xE1;n gi&#x1EA5;y ph&#xE9;p ph&#x1EA7;n m&#x1EC1;m thu&#x1EA7;n t&#xFA;y. </span><span data-path-to-node="35,4,3,0,1" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><response-element class ng-version="0.0.0-PLACEHOLDER" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><source-footnote _nghost-ng-c617374649 class="ng-star-inserted" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><sup _ngcontent-ng-c617374649 class="superscript" data-turn-source-index="35" style="animation: auto ease 0s 1 normal none running none; appearance: none; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; background-color: transparent !important; border: 0px none rgb(68, 71, 70); inset: -10px 2px 10px -2px; clear: none; clip: auto; color: rgb(68, 71, 70); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline-flex; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: -6px; margin-bottom: 0px; margin-left: -6px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(68, 71, 70) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: relative; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important; font-size: 16px !important;"><!----></sup></source-footnote><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----></response-element></span></span></p></td><td style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(248, 250, 253); border: 1px solid; inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: table-cell; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 8px 12px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><p data-path-to-node="35,4,4,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: block; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span data-path-to-node="35,4,4,0,0" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;">Red Hat Enterprise Linux (tr&#x1B0;&#x1EDB;c &#x111;&#xE2;y). </span><span data-path-to-node="35,4,4,0,1" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><span style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><response-element class ng-version="0.0.0-PLACEHOLDER" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><source-footnote _nghost-ng-c617374649 class="ng-star-inserted" style="animation: auto ease 0s 1 normal none running none; appearance: none; background: none 0% 0% / auto repeat scroll padding-box border-box rgb(255, 255, 255); border: 0px none rgb(31, 31, 31); inset: auto; clear: none; clip: auto; color: rgb(31, 31, 31); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(31, 31, 31) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: static; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important;"><sup _ngcontent-ng-c617374649 class="superscript" data-turn-source-index="36" style="animation: auto ease 0s 1 normal none running none; appearance: none; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box; background-color: transparent !important; border: 0px none rgb(68, 71, 70); inset: -10px 2px 10px -2px; clear: none; clip: auto; color: rgb(68, 71, 70); columns: auto; contain: none; container: none; content: normal; cursor: auto; cx: 0px; cy: 0px; d: none; direction: ltr; display: inline-flex; fill: rgb(0, 0, 0); filter: none; flex: 0 1 auto; float: none; gap: normal; hyphens: manual; interactivity: auto; isolation: auto; margin-top: 0px !important; margin-right: -6px; margin-bottom: 0px; margin-left: -6px; marker: none; mask: none; offset: normal; opacity: 1; order: 0; orphans: 2; outline: rgb(68, 71, 70) none 0px; overlay: none; padding: 0px; page: auto; perspective: none; position: relative; quotes: auto; r: 0px; resize: none; rotate: none; rx: auto; ry: auto; scale: none; speak: normal; stroke: none; transform: none; transition: all; translate: none; visibility: visible; widows: 2; x: 0px; y: 0px; zoom: 1; font-family: &quot;Google Sans Text&quot;, sans-serif !important; line-height: 1.15 !important; font-size: 16px !important;"><!----></sup></source-footnote><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----><!----></response-element></span></span></p></td></tr></tbody></table><!--kg-card-end: html--><h3 id="cu%E1%BB%99c-c%C3%A1ch-m%E1%BA%A1ng-ti%E1%BA%BFp-c%E1%BA%ADn-th%E1%BB%8B-tr%C6%B0%E1%BB%9Dng-developer-plg-product-led-growth">Cu&#x1ED9;c C&#xE1;ch M&#x1EA1;ng Ti&#x1EBF;p C&#x1EAD;n Th&#x1ECB; Tr&#x1B0;&#x1EDD;ng: Developer PLG (Product-Led Growth)</h3><p>&#x110;&#x1EC3; hi&#x1EC7;n th&#x1EF1;c h&#xF3;a doanh thu t&#x1EEB; c&#xE1;c m&#xF4; h&#xEC;nh nh&#x1B0; SaaS Hosting ho&#x1EB7;c Open Core, c&#xE1;c c&#xF4;ng ty OSS kh&#xF4;ng th&#x1EC3; d&#x1EF1;a v&#xE0;o l&#x1EF1;c l&#x1B0;&#x1EE3;ng b&#xE1;n h&#xE0;ng B2B truy&#x1EC1;n th&#x1ED1;ng g&#x1ECD;i &#x111;i&#x1EC7;n l&#x1EA1;nh (cold calling) &#x111;&#x1EBF;n c&#xE1;c Gi&#xE1;m &#x111;&#x1ED1;c C&#xF4;ng ngh&#x1EC7; (CTO). Thay v&#xE0;o &#x111;&#xF3;, m&#x1ED9;t ph&#x1B0;&#x1A1;ng ph&#xE1;p Ti&#x1EBF;p c&#x1EAD;n Th&#x1ECB; tr&#x1B0;&#x1EDD;ng (GTM) m&#x1EDB;i &#x111;&#xE3; ra &#x111;&#x1EDD;i: <strong>T&#x103;ng tr&#x1B0;&#x1EDF;ng D&#x1EAB;n d&#x1EAF;t b&#x1EDF;i S&#x1EA3;n ph&#x1EA9;m D&#xE0;nh cho Nh&#xE0; ph&#xE1;t tri&#x1EC3;n (Developer PLG)</strong>.</p><p>Trong m&#xF4; h&#xEC;nh n&#xE0;y, h&#x1EA1;t gi&#x1ED1;ng b&#xE1;n h&#xE0;ng &#x111;&#x1B0;&#x1EE3;c gieo r&#x1EAF;c tr&#x1EF1;c ti&#x1EBF;p v&#xE0;o tay c&#xE1;c l&#x1EAD;p tr&#xEC;nh vi&#xEA;n c&#x1EA5;p th&#x1EA5;p th&#xF4;ng qua phi&#xEA;n b&#x1EA3;n mi&#x1EC5;n ph&#xED;. Tuy nhi&#xEA;n, h&#x1EC7; th&#x1ED1;ng ph&#xE2;n t&#xED;ch UI truy&#x1EC1;n th&#x1ED1;ng (nh&#x1B0; &#x111;&#x1EBF;m s&#x1ED1; l&#x1B0;&#x1EE3;t nh&#x1EA5;p chu&#x1ED9;t tr&#xEA;n trang web) l&#xE0; v&#xF4; d&#x1EE5;ng &#x111;&#x1ED1;i v&#x1EDB;i c&#xE1;c c&#xF4;ng c&#x1EE5; d&#xE0;nh cho nh&#xE0; ph&#xE1;t tri&#x1EC3;n. Chi&#x1EBF;n l&#x1B0;&#x1EE3;c Developer PLG y&#xEA;u c&#x1EA7;u c&#xE1;c c&#xF4;ng ty theo d&#xF5;i m&#x1ED9;t m&#x1EA1;ng l&#x1B0;&#x1EDB;i t&#xED;n hi&#x1EC7;u &#xFD; &#x111;&#x1ECB;nh mua h&#xE0;ng (intent signals) tinh vi tr&#xEA;n to&#xE0;n b&#x1ED9; kh&#xF4;ng gian b&#x1EC1; m&#x1EB7;t l&#xE0;m vi&#x1EC7;c c&#x1EE7;a l&#x1EAD;p tr&#xEC;nh vi&#xEA;n (developer surface area). H&#x1EC7; th&#x1ED1;ng n&#xE0;y s&#x1EBD; &#x111;o l&#x1B0;&#x1EDD;ng s&#x1ED1; l&#x1B0;&#x1EE3;ng l&#x1EC7;nh &#x111;&#x1B0;&#x1EE3;c th&#x1EF1;c thi trong Giao di&#x1EC7;n d&#xF2;ng l&#x1EC7;nh (CLI), t&#x1EA7;n su&#x1EA5;t k&#xE9;o &#x1EA3;nh Docker (Docker pulls), m&#x1EE9;c &#x111;&#x1ED9; s&#x1EED; d&#x1EE5;ng m&#xF4;i tr&#x1B0;&#x1EDD;ng h&#x1ED9;p c&#xE1;t API (API sandboxes), l&#x1B0;u l&#x1B0;&#x1EE3;ng t&#x1EA3;i c&#xE1;c g&#xF3;i ph&#x1EA7;n m&#x1EC1;m (npm, pip), c&#x169;ng nh&#x1B0; s&#x1EF1; t&#x1B0;&#x1A1;ng t&#xE1;c v&#x1EDB;i c&#xE1;c t&#xE0;i li&#x1EC7;u h&#x1B0;&#x1EDB;ng d&#x1EAB;n tr&#xEA;n GitHub (s&#x1ED1; sao, l&#x1B0;&#x1EE3;t r&#x1EBD; nh&#xE1;nh d&#x1EF1; &#xE1;n) v&#xE0; c&#xE1;c n&#x1EC1;n t&#x1EA3;ng c&#x1ED9;ng &#x111;&#x1ED3;ng nh&#x1B0; Stack Overflow, Reddit, Discord.</p><p>S&#x1EED; d&#x1EE5;ng c&#xE1;c c&#xF4;ng c&#x1EE5; phi &#x1EA9;n danh (deanonymization) t&#xED;n hi&#x1EC7;u, &#x111;&#x1ED9;i ng&#x169; b&#xE1;n h&#xE0;ng c&#xF3; th&#x1EC3; theo d&#xF5;i xem m&#x1ED9;t nh&#xF3;m l&#x1EAD;p tr&#xEC;nh vi&#xEA;n t&#x1EA1;i m&#x1ED9;t t&#x1EAD;p &#x111;o&#xE0;n l&#x1EDB;n &#x111;ang th&#x1EED; nghi&#x1EC7;m ph&#x1EA7;n m&#x1EC1;m ngu&#x1ED3;n m&#x1EDF; c&#x1EE7;a h&#x1ECD; &#x111;&#x1EBF;n giai &#x111;o&#x1EA1;n n&#xE0;o. Khi h&#x1EC7; th&#x1ED1;ng ph&#xE1;t hi&#x1EC7;n c&#xE1;c l&#x1EAD;p tr&#xEC;nh vi&#xEA;n b&#x1EAF;t &#x111;&#x1EA7;u tra c&#x1EE9;u t&#xE0;i li&#x1EC7;u v&#x1EC1; &quot;t&#xED;ch h&#x1EE3;p b&#x1EA3;o m&#x1EAD;t doanh nghi&#x1EC7;p&quot; ho&#x1EB7;c &quot;m&#x1EDF; r&#x1ED9;ng c&#x1EE5;m m&#xE1;y ch&#x1EE7;&quot; &#x2014; nh&#x1EEF;ng t&#xED;nh n&#x103;ng ch&#x1EC9; c&#xF3; trong b&#x1EA3;n tr&#x1EA3; ph&#xED; &#x2014; nh&#xE2;n vi&#xEA;n kinh doanh s&#x1EBD; can thi&#x1EC7;p v&#xE0;o &#x111;&#xFA;ng th&#x1EDD;i &#x111;i&#x1EC3;m v&#x1EDB;i c&#xE1;c gi&#x1EA3;i ph&#xE1;p h&#x1ED7; tr&#x1EE3; chuy&#xEA;n s&#xE2;u, bi&#x1EBF;n m&#x1ED9;t d&#x1EF1; &#xE1;n th&#x1EED; nghi&#x1EC7;m th&#xE0;nh m&#x1ED9;t h&#x1EE3;p &#x111;&#x1ED3;ng c&#x1EA5;p ph&#xE9;p tr&#x1ECB; gi&#xE1; h&#xE0;ng tr&#x103;m ngh&#xEC;n USD. C&#xE1;c c&#xF4;ng ty nh&#x1B0; Unstructured.io hay Memgraph &#x111;&#xE3; t&#x103;ng g&#x1EA5;p &#x111;&#xF4;i l&#x1B0;&#x1EE3;ng cu&#x1ED9;c h&#x1ECD;p b&#xE1;n h&#xE0;ng ch&#x1ED1;t &#x111;&#x1B0;&#x1EE3;c nh&#x1EDD; v&#xE0;o vi&#x1EC7;c s&#x1EED; d&#x1EE5;ng d&#x1EEF; li&#x1EC7;u t&#xED;n hi&#x1EC7;u &#xFD; &#x111;&#x1ECB;nh s&#xE2;u s&#x1EAF;c n&#xE0;y. Confluent, c&#xF4;ng ty &#x111;&#x1EE9;ng sau Apache Kafka, &#x111;&#xE3; x&#xE2;y d&#x1EF1;ng m&#x1ED9;t &#x111;&#x1EBF; ch&#x1EBF; th&#x1B0;&#x1A1;ng m&#x1EA1;i tr&#x1ECB; gi&#xE1; h&#xE0;ng t&#x1EF7; USD th&#xF4;ng qua vi&#x1EC7;c theo d&#xF5;i c&#xE1;c t&#xED;n hi&#x1EC7;u li&#xEA;n quan &#x111;&#x1EBF;n k&#x1EF9; n&#x103;ng Kafka tr&#xEA;n LinkedIn v&#xE0; c&#xE1;c h&#x1B0;&#x1EDB;ng d&#x1EAB;n k&#x1EF9; thu&#x1EAD;t, sau &#x111;&#xF3; cung c&#x1EA5;p phi&#xEA;n b&#x1EA3;n qu&#x1EA3;n l&#xFD; &#x111;&#xE1;m m&#xE2;y lo&#x1EA1;i b&#x1ECF; g&#xE1;nh n&#x1EB7;ng v&#x1EAD;n h&#xE0;nh h&#x1EA1; t&#x1EA7;ng cho doanh nghi&#x1EC7;p.</p><h3 id="kh%E1%BB%A7ng-ho%E1%BA%A3ng-c%E1%BA%A5p-ph%C3%A9p-v%C3%A0-s%E1%BB%B1-n%E1%BB%95i-d%E1%BA%ADy-c%E1%BB%A7a-c%E1%BB%99ng-%C4%91%E1%BB%93ng-c%C3%A2u-chuy%E1%BB%87n-c%E1%BB%A7a-redis-hashicorp-v%C3%A0-elastic">Kh&#x1EE7;ng Ho&#x1EA3;ng C&#x1EA5;p Ph&#xE9;p v&#xE0; S&#x1EF1; N&#x1ED5;i D&#x1EAD;y C&#x1EE7;a C&#x1ED9;ng &#x110;&#x1ED3;ng: C&#xE2;u Chuy&#x1EC7;n C&#x1EE7;a Redis, HashiCorp v&#xE0; Elastic</h3><p>Trong k&#x1EF7; nguy&#xEA;n &#x111;i&#x1EC7;n to&#xE1;n &#x111;&#xE1;m m&#xE2;y hi&#x1EC7;n t&#x1EA1;i, phong tr&#xE0;o m&#xE3; ngu&#x1ED3;n m&#x1EDF; &#x111;ang tr&#x1EA3;i qua m&#x1ED9;t s&#x1EF1; chuy&#x1EC3;n d&#x1ECB;ch m&#xF4; h&#xEC;nh t&#xE0;n kh&#x1ED1;c (paradigm shift). S&#x1EF1; m&#xE2;u thu&#x1EAB;n c&#x1ED1;t l&#xF5;i kh&#xF4;ng c&#xF2;n n&#x1EB1;m gi&#x1EEF;a &quot;M&#xE3; ngu&#x1ED3;n m&#x1EDF;&quot; v&#xE0; &quot;Ph&#x1EA7;n m&#x1EC1;m &#x111;&#xF3;ng&quot;, m&#xE0; &#x111;&#xE3; chuy&#x1EC3;n th&#xE0;nh cu&#x1ED9;c chi&#x1EBF;n s&#x1ED1;ng c&#xF2;n gi&#x1EEF;a &quot;C&#xE1;c nh&#xE0; ph&#xE1;t tri&#x1EC3;n h&#x1EC7; sinh th&#xE1;i OSS&quot; v&#xE0; &quot;C&#xE1;c nh&#xE0; cung c&#x1EA5;p D&#x1ECB;ch v&#x1EE5; &#x110;&#xE1;m m&#xE2;y (Hyperscalers)&quot; nh&#x1B0; Amazon Web Services (AWS), Google Cloud, v&#xE0; Microsoft Azure.</p><p>C&#x1A1; ch&#x1EBF; b&#xF3;c l&#x1ED9;t n&#xE0;y di&#x1EC5;n ra theo m&#x1ED9;t khu&#xF4;n m&#x1EAB;u r&#xF5; r&#xE0;ng: C&#xE1;c c&#xF4;ng ty ph&#xE1;t tri&#x1EC3;n OSS (nh&#x1B0; Elastic, Redis, MongoDB) b&#x1ECF; ra h&#xE0;ng ch&#x1EE5;c tri&#x1EC7;u &#x111;&#xF4; la v&#xE0; nhi&#x1EC1;u n&#x103;m nghi&#xEA;n c&#x1EE9;u &#x111;&#x1EC3; x&#xE2;y d&#x1EF1;ng c&#xE1;c n&#x1EC1;n t&#x1EA3;ng c&#x1A1; s&#x1EDF; d&#x1EEF; li&#x1EC7;u v&#xE0; c&#x1A1; s&#x1EDF; h&#x1EA1; t&#x1EA7;ng &#x1B0;u vi&#x1EC7;t. Khi c&#xE1;c ph&#x1EA7;n m&#x1EC1;m n&#xE0;y tr&#x1EDF; n&#xEA;n ph&#x1ED5; bi&#x1EBF;n, c&#xE1;c g&#xE3; kh&#x1ED5;ng l&#x1ED3; &#x111;&#xE1;m m&#xE2;y s&#x1EBD; l&#x1EA5;y tr&#x1EF1;c ti&#x1EBF;p m&#xE3; ngu&#x1ED3;n m&#x1EDF; &#x111;&#xF3;, b&#x1ECD;c ch&#xFA;ng v&#xE0;o m&#x1ED9;t giao di&#x1EC7;n d&#x1ECB;ch v&#x1EE5; &#x111;&#xE1;m m&#xE2;y c&#xF3; th&#x1EC3; qu&#x1EA3;n l&#xFD; &#x111;&#x1B0;&#x1EE3;c, v&#xE0; b&#xE1;n l&#x1EA1;i cho kh&#xE1;ch h&#xE0;ng doanh nghi&#x1EC7;p thu v&#x1EC1; h&#xE0;ng t&#x1EF7; &#x111;&#xF4; la. Trong khi &#x111;&#xF3;, c&#xE1;c g&#xE3; kh&#x1ED5;ng l&#x1ED3; n&#xE0;y h&#x1EA7;u nh&#x1B0; kh&#xF4;ng &#x111;&#xF3;ng g&#xF3;p m&#xE3; ngu&#x1ED3;n ng&#x1B0;&#x1EE3;c l&#x1EA1;i cho d&#x1EF1; &#xE1;n g&#x1ED1;c, c&#x169;ng kh&#xF4;ng chia s&#x1EBB; b&#x1EA5;t k&#x1EF3; doanh thu n&#xE0;o cho &#x111;&#x1ED9;i ng&#x169; ph&#xE1;t tri&#x1EC3;n ban &#x111;&#x1EA7;u, c&#x1EAF;t &#x111;&#x1EE9;t c&#x1A1; h&#x1ED9;i sinh l&#x1EDD;i c&#x1EE7;a ch&#xED;nh t&#xE1;c gi&#x1EA3; ph&#x1EA7;n m&#x1EC1;m.</p><p>&#x110;&#x1ED1;i m&#x1EB7;t v&#x1EDB;i m&#x1ED1;i &#x111;e d&#x1ECD;a sinh t&#x1EED; n&#xE0;y, m&#x1ED9;t l&#xE0;n s&#xF3;ng c&#xE1;c c&#xF4;ng ty c&#xF4;ng ngh&#x1EC7; l&#x1EDB;n &#x111;&#xE3; quy&#x1EBF;t &#x111;&#x1ECB;nh thay &#x111;&#x1ED5;i h&#x1EC7; th&#x1ED1;ng c&#x1EA5;p ph&#xE9;p, t&#x1EA1;o ra nh&#x1EEF;ng c&#x1A1;n ch&#x1EA5;n &#x111;&#x1ED9;ng v&#xE0; l&#xE0;n s&#xF3;ng t&#x1EA9;y chay d&#x1EEF; d&#x1ED9;i t&#x1EEB; c&#x1ED9;ng &#x111;&#x1ED3;ng :</p><ul><li><strong>Cu&#x1ED9;c &#x110;&#x1EA1;i Ph&#xE2;n Li c&#x1EE7;a HashiCorp (Terraform):</strong> N&#x103;m 2023, HashiCorp, c&#xF4;ng ty &#x111;&#x1EE9;ng sau c&#xF4;ng c&#x1EE5; qu&#x1EA3;n l&#xFD; c&#x1A1; s&#x1EDF; h&#x1EA1; t&#x1EA7;ng d&#x1B0;&#x1EDB;i d&#x1EA1;ng m&#xE3; (IaC) ph&#x1ED5; bi&#x1EBF;n nh&#x1EA5;t th&#x1EBF; gi&#x1EDB;i l&#xE0; Terraform, &#x111;&#xE3; t&#x1EEB; b&#x1ECF; Gi&#x1EA5;y ph&#xE9;p C&#xF4;ng c&#x1ED9;ng Mozilla (MPL 2.0) &#x111;&#x1EC3; chuy&#x1EC3;n sang Gi&#x1EA5;y ph&#xE9;p Ngu&#x1ED3;n Doanh nghi&#x1EC7;p (Business Source License - BSL 1.1). BSL kh&#xF4;ng ph&#x1EA3;i l&#xE0; m&#x1ED9;t gi&#x1EA5;y ph&#xE9;p m&#xE3; ngu&#x1ED3;n m&#x1EDF; &#x111;&#x1B0;&#x1EE3;c T&#x1ED5; ch&#x1EE9;c S&#xE1;ng ki&#x1EBF;n Ngu&#x1ED3;n M&#x1EDF; (OSI) c&#xF4;ng nh&#x1EAD;n. N&#xF3; v&#x1EAB;n cho ph&#xE9;p xem m&#xE3; ngu&#x1ED3;n (source-available), nh&#x1B0;ng nghi&#xEA;m c&#x1EA5;m b&#x1EA5;t k&#x1EF3; t&#x1ED5; ch&#x1EE9;c n&#xE0;o s&#x1EED; d&#x1EE5;ng m&#xE3; n&#xE0;y &#x111;&#x1EC3; t&#x1EA1;o ra m&#x1ED9;t &quot;d&#x1ECB;ch v&#x1EE5; c&#x1EA1;nh tranh&quot; tr&#x1EF1;c ti&#x1EBF;p v&#x1EDB;i HashiCorp. C&#x1ED9;ng &#x111;&#x1ED3;ng DevOps c&#x1EA3;m th&#x1EA5;y b&#x1ECB; ph&#x1EA3;n b&#x1ED9;i s&#xE2;u s&#x1EAF;c, g&#x1ECD;i &#x111;&#xE2;y l&#xE0; m&#x1ED9;t c&#xFA; l&#x1EEB;a ngo&#x1EA1;n m&#x1EE5;c (rug pull). Ngay l&#x1EAD;p t&#x1EE9;c, m&#x1ED9;t li&#xEA;n minh c&#xE1;c nh&#xE0; cung c&#x1EA5;p d&#x1ECB;ch v&#x1EE5; v&#xE0; nh&#xE0; ph&#xE1;t tri&#x1EC3;n &#x111;&#xE3; h&#x1EE3;p l&#x1EF1;c r&#x1EBD; nh&#xE1;nh (fork) c&#x1A1; s&#x1EDF; m&#xE3; cu&#x1ED1;i c&#xF9;ng c&#x1EE7;a Terraform d&#x1B0;&#x1EDB;i d&#x1EA1;ng m&#xE3; ngu&#x1ED3;n m&#x1EDF; &#x111;&#x1EC3; t&#x1EA1;o ra <strong>OpenTofu</strong>, m&#x1ED9;t d&#x1EF1; &#xE1;n ho&#xE0;n to&#xE0;n thu&#x1ED9;c s&#x1EDF; h&#x1EEF;u c&#x1EE7;a c&#x1ED9;ng &#x111;&#x1ED3;ng v&#xE0; &#x111;&#x1B0;&#x1EE3;c qu&#x1EA3;n tr&#x1ECB; b&#x1EDF;i Linux Foundation, l&#xE0;m ph&#xE2;n m&#x1EA3;nh nghi&#xEA;m tr&#x1ECD;ng h&#x1EC7; sinh th&#xE1;i c&#x1A1; s&#x1EDF; h&#x1EA1; t&#x1EA7;ng.</li><li><strong>Tr&#x1B0;&#x1EDD;ng H&#x1EE3;p c&#x1EE7;a Redis v&#xE0; MongoDB:</strong> Redis Labs v&#xE0; MongoDB c&#x169;ng &#x111;i theo con &#x111;&#x1B0;&#x1EDD;ng t&#x1B0;&#x1A1;ng t&#x1EF1;. MongoDB &#x111;&#xE3; &#x111;i ti&#xEA;n phong trong vi&#x1EC7;c t&#x1EA1;o ra Gi&#x1EA5;y ph&#xE9;p C&#xF4;ng c&#x1ED9;ng Ph&#xED;a M&#xE1;y ch&#x1EE7; (Server Side Public License - SSPL), y&#xEA;u c&#x1EA7;u b&#x1EA5;t k&#x1EF3; ai cung c&#x1EA5;p ph&#x1EA7;n m&#x1EC1;m d&#x1B0;&#x1EDB;i d&#x1EA1;ng d&#x1ECB;ch v&#x1EE5; (SaaS) ph&#x1EA3;i m&#x1EDF; m&#xE3; ngu&#x1ED3;n to&#xE0;n b&#x1ED9; h&#x1EC7; th&#x1ED1;ng qu&#x1EA3;n l&#xFD; c&#x1A1; s&#x1EDF; h&#x1EA1; t&#x1EA7;ng c&#x1EE7;a h&#x1ECD; &#x2014; m&#x1ED9;t &#x111;i&#x1EC1;u kho&#x1EA3;n mang t&#xED;nh &quot;thu&#x1ED1;c &#x111;&#x1ED9;c&quot; ng&#x103;n c&#x1EA3;n AWS b&#xE1;n d&#x1ECB;ch v&#x1EE5; MongoDB. Redis, sau nhi&#x1EC1;u l&#x1EA7;n &#x111;i&#x1EC1;u ch&#x1EC9;nh, c&#x169;ng chuy&#x1EC3;n t&#x1EEB; c&#xE1;c gi&#x1EA5;y ph&#xE9;p BSD d&#x1EC5; d&#xE3;i sang c&#xE1;c gi&#x1EA5;y ph&#xE9;p th&#x1B0;&#x1A1;ng m&#x1EA1;i k&#xE9;p c&#x1EA5;m c&#x1EA1;nh tranh &#x111;&#xE1;m m&#xE2;y. H&#x1EAD;u qu&#x1EA3; &#x111;&#x1ED1;i v&#x1EDB;i Redis l&#xE0; th&#x1EA3;m kh&#x1ED1;c v&#x1EC1; m&#x1EB7;t c&#x1ED9;ng &#x111;&#x1ED3;ng: d&#x1EF1; &#xE1;n &#x111;&#xE3; &#x111;&#xE1;nh m&#x1EA5;t ph&#x1EA7;n l&#x1EDB;n l&#x1EF1;c l&#x1B0;&#x1EE3;ng &#x111;&#xF3;ng g&#xF3;p b&#xEA;n ngo&#xE0;i, d&#x1EAB;n &#x111;&#x1EBF;n s&#x1EF1; ra &#x111;&#x1EDD;i c&#x1EE7;a d&#x1EF1; &#xE1;n fork <strong>Valkey</strong>. Valkey, nh&#x1EDD; s&#x1EF1; h&#x1ED7; tr&#x1EE3; c&#x1EE7;a Linux Foundation, &#x111;&#xE3; thu h&#xFA;t g&#x1EA7;n 20.000 sao tr&#xEA;n GitHub ch&#x1EC9; trong n&#x103;m &#x111;&#x1EA7;u ti&#xEA;n v&#xE0; &#x111;&#x1B0;&#x1EE3;c nhi&#x1EC1;u t&#x1ED5; ch&#x1EE9;c l&#x1EDB;n chuy&#x1EC3;n h&#x1B0;&#x1EDB;ng sang s&#x1EED; d&#x1EE5;ng v&#xEC; l&#xFD; do gi&#x1EA3;m chi ph&#xED; v&#xE0; &#x111;&#x1ED9;c l&#x1EAD;p kh&#x1ECF;i quy&#x1EC1;n ki&#x1EC3;m so&#xE1;t c&#x1EE7;a m&#x1ED9;t c&#xF4;ng ty duy nh&#x1EA5;t.</li><li><strong>B&#xE0;i H&#x1ECD;c Quay Xe c&#x1EE7;a Elastic:</strong> Trong khi HashiCorp v&#xE0; Redis ki&#xEA;n &#x111;&#x1ECB;nh v&#x1EDB;i vi&#x1EC7;c &#x111;&#xF3;ng m&#xE3; ngu&#x1ED3;n, Elastic (&#x111;&#x1EE9;ng sau Elasticsearch) cung c&#x1EA5;p m&#x1ED9;t g&#xF3;c nh&#xEC;n kh&#xE1;c. Ban &#x111;&#x1EA7;u, &#x111;&#x1EC3; ch&#x1ED1;ng l&#x1EA1;i vi&#x1EC7;c AWS sao ch&#xE9;p d&#x1ECB;ch v&#x1EE5; c&#x1EE7;a m&#xEC;nh (th&#x1EE9; &#x111;&#xE3; bu&#x1ED9;c AWS ph&#x1EA3;i t&#x1EA1;o ra d&#x1EF1; &#xE1;n OpenSearch), Elastic &#x111;&#xE3; chuy&#x1EC3;n sang s&#x1EED; d&#x1EE5;ng gi&#x1EA5;y ph&#xE9;p SSPL v&#xE0; Elastic License &#x111;&#x1ED9;c quy&#x1EC1;n v&#xE0;o n&#x103;m 2021. Tuy nhi&#xEA;n, sau 4 n&#x103;m ch&#x1EE9;ng ki&#x1EBF;n &#x111;&#x1ED9;ng l&#x1EF1;c t&#x103;ng tr&#x1B0;&#x1EDF;ng c&#x1ED9;ng &#x111;&#x1ED3;ng b&#x1ECB; suy gi&#x1EA3;m, v&#xE0;o n&#x103;m 2024, c&#xF4;ng ty &#x111;&#xE3; quy&#x1EBF;t &#x111;&#x1ECB;nh &#x111;&#x1B0;a ph&#x1EA7;n m&#x1EC1;m tr&#x1EDF; l&#x1EA1;i th&#xE0;nh m&#xE3; ngu&#x1ED3;n m&#x1EDF; ch&#xED;nh th&#x1EE9;c d&#x1B0;&#x1EDB;i s&#x1EF1; b&#x1EA3;o v&#x1EC7; c&#x1EE7;a gi&#x1EA5;y ph&#xE9;p AGPL. Nh&#xE0; s&#xE1;ng l&#x1EAD;p Elastic nh&#x1EAD;n ra r&#x1EB1;ng, d&#xF9; c&#xE1;c gi&#x1EA5;y ph&#xE9;p th&#x1B0;&#x1A1;ng m&#x1EA1;i c&#xF3; th&#x1EC3; b&#x1EA3;o v&#x1EC7; doanh thu ng&#x1EAF;n h&#x1EA1;n, nh&#x1B0;ng vi&#x1EC7;c t&#x1B0;&#x1EDB;c b&#x1ECF; danh x&#x1B0;ng &quot;M&#xE3; ngu&#x1ED3;n m&#x1EDF;&quot; &#x111;&#x1ED3;ng ngh&#x129;a v&#x1EDB;i vi&#x1EC7;c m&#x1EA5;t &#x111;i s&#x1EE9;c m&#x1EA1;nh ph&#xE2;n ph&#x1ED1;i mi&#x1EC5;n ph&#xED;, tinh th&#x1EA7;n h&#x1EE3;p t&#xE1;c v&#xE0; s&#x1EF1; tin t&#x1B0;&#x1EDF;ng t&#x1EF1; nhi&#xEA;n (goodwill) c&#x1EE7;a h&#xE0;ng tri&#x1EC7;u nh&#xE0; ph&#xE1;t tri&#x1EC3;n tr&#xEA;n to&#xE0;n th&#x1EBF; gi&#x1EDB;i.</li></ul><p>S&#x1EF1; c&#x103;ng th&#x1EB3;ng n&#xE0;y l&#xE0;m n&#x1ED5;i b&#x1EAD;t m&#x1ED9;t kh&#xE1;i ni&#x1EC7;m c&#x1ED1;t l&#xF5;i: s&#x1EF1; kh&#xE1;c bi&#x1EC7;t gi&#x1EEF;a <strong>M&#xE3; Ngu&#x1ED3;n M&#x1EDF; (Open Source)</strong> v&#xE0; <strong>Qu&#x1EA3;n Tr&#x1ECB; M&#x1EDF; (Open Governance)</strong>. M&#x1ED9;t d&#x1EF1; &#xE1;n c&#xF3; th&#x1EC3; c&#xF3; m&#xE3; ngu&#x1ED3;n m&#x1EDF; ho&#xE0;n to&#xE0;n (nh&#x1B0; MySQL d&#x1B0;&#x1EDB;i s&#x1EF1; ki&#x1EC3;m so&#xE1;t c&#x1EE7;a Oracle), nh&#x1B0;ng n&#x1EBF;u h&#x1EC7; th&#x1ED1;ng qu&#x1EA3;n tr&#x1ECB; b&#x1ECB; &#x111;&#xF3;ng l&#x1EA1;i &#x2014; n&#x1A1;i ch&#x1EC9; m&#x1ED9;t t&#x1EAD;p &#x111;o&#xE0;n duy nh&#x1EA5;t &#x111;&#x1B0;&#x1EE3;c ph&#xE9;p quy&#x1EBF;t &#x111;&#x1ECB;nh l&#x1ED9; tr&#xEC;nh c&#x1EAD;p nh&#x1EAD;t v&#xE0; t&#x1EEB; ch&#x1ED1;i m&#x1ECD;i m&#xE3; &#x111;&#xF3;ng g&#xF3;p t&#x1EEB; b&#xEA;n ngo&#xE0;i &#x2014; d&#x1EF1; &#xE1;n &#x111;&#xF3; s&#x1EBD; m&#x1EA5;t &#x111;i linh h&#x1ED3;n m&#xE3; ngu&#x1ED3;n m&#x1EDF;. Qu&#x1EA3;n tr&#x1ECB; m&#x1EDF; (&#x111;i&#x1EC3;n h&#xEC;nh nh&#x1B0; c&#xE1;c d&#x1EF1; &#xE1;n thu&#x1ED9;c Apache Software Foundation hay Linux Foundation) &#x111;&#x1EA3;m b&#x1EA3;o t&#xED;nh &#x111;a d&#x1EA1;ng trong &#x111;&#x1ED9;i ng&#x169; l&#xE3;nh &#x111;&#x1EA1;o, ng&#x103;n c&#x1EA3;n b&#x1EA5;t k&#x1EF3; t&#x1EAD;p &#x111;o&#xE0;n n&#xE0;o thao t&#xFA;ng d&#x1EF1; &#xE1;n, t&#x1EEB; &#x111;&#xF3; b&#x1EA3;o v&#x1EC7; quy&#x1EC1;n l&#x1EE3;i d&#xE0;i h&#x1EA1;n c&#x1EE7;a ng&#x1B0;&#x1EDD;i d&#xF9;ng doanh nghi&#x1EC7;p kh&#x1ECF;i r&#x1EE7;i ro c&#xF4;ng ty s&#xE1;ng l&#x1EAD;p thay &#x111;&#x1ED5;i lu&#x1EAD;t ch&#x1A1;i.</p><h3 id="%C4%91a-d%E1%BA%A1ng-h%C3%B3a-h%E1%BB%87-sinh-th%C3%A1i-n%E1%BB%81n-t%E1%BA%A3ng-ti%E1%BB%81n-th%C6%B0%E1%BB%9Fng-t%C3%A0i-tr%E1%BB%A3-phi-t%E1%BA%ADp-trung-v%C3%A0-m%C3%A3-h%C3%B3a-blockchain">&#x110;a D&#x1EA1;ng H&#xF3;a H&#x1EC7; Sinh Th&#xE1;i: N&#x1EC1;n T&#x1EA3;ng Ti&#x1EC1;n Th&#x1B0;&#x1EDF;ng, T&#xE0;i Tr&#x1EE3; Phi T&#x1EAD;p Trung v&#xE0; M&#xE3; H&#xF3;a Blockchain</h3><p>&#x110;&#x1ED1;i v&#x1EDB;i c&#xE1;c d&#x1EF1; &#xE1;n OSS &#x1EDF; quy m&#xF4; c&#xE1; nh&#xE2;n, c&#xE1;c th&#x1B0; vi&#x1EC7;n ti&#x1EC7;n &#xED;ch nh&#x1ECF;, ho&#x1EB7;c c&#xE1;c d&#x1EF1; &#xE1;n ch&#x1B0;a th&#x1EC3; &#xE1;p d&#x1EE5;ng m&#xF4; h&#xEC;nh B2B kh&#x1ED5;ng l&#x1ED3;, m&#x1ED9;t h&#x1EC7; sinh th&#xE1;i c&#xE1;c n&#x1EC1;n t&#x1EA3;ng t&#xE0;i tr&#x1EE3; vi m&#xF4; v&#xE0; qu&#x1EA3;n l&#xFD; qu&#x1EF9; &#x111;&#xE3; xu&#x1EA5;t hi&#x1EC7;n, thay th&#x1EBF; ho&#xE0;n to&#xE0;n t&#x1B0; duy &quot;n&#xFA;t quy&#xEA;n g&#xF3;p PayPal&quot; truy&#x1EC1;n th&#x1ED1;ng v&#x1ED1;n thi&#x1EBF;u t&#xED;nh h&#x1EC7; th&#x1ED1;ng.</p><p>S&#x1EF1; d&#x1ECB;ch chuy&#x1EC3;n c&#x1EE7;a d&#xF2;ng v&#x1ED1;n h&#x1B0;&#x1EDB;ng t&#x1EDB;i vi&#x1EC7;c minh b&#x1EA1;ch h&#xF3;a v&#xE0; t&#x1EF1; &#x111;&#x1ED9;ng h&#xF3;a:</p><ol><li><strong>H&#x1EC7; Th&#x1ED1;ng &#x110;&#x1EB7;t Ti&#x1EC1;n Th&#x1B0;&#x1EDF;ng Th&#x1EBF; H&#x1EC7; M&#x1EDB;i (Bounty Platforms):</strong> Tr&#x1B0;&#x1EDB;c &#x111;&#xE2;y, c&#xE1;c nh&#xE0; ph&#xE1;t tri&#x1EC3;n s&#x1EED; d&#x1EE5;ng n&#x1EC1;n t&#x1EA3;ng nh&#x1B0; Bountysource &#x111;&#x1EC3; k&#xEA;u g&#x1ECD;i ph&#x1EA7;n th&#x1B0;&#x1EDF;ng gi&#x1EA3;i quy&#x1EBF;t c&#xE1;c l&#x1ED7;i (bugs) c&#x1EE5; th&#x1EC3;. Tuy nhi&#xEA;n, do nh&#x1EEF;ng thay &#x111;&#x1ED5;i g&#xE2;y tranh c&#xE3;i v&#x1EC1; &#x111;i&#x1EC1;u kho&#x1EA3;n d&#x1ECB;ch v&#x1EE5; v&#xE0; v&#x1EA5;n &#x111;&#x1EC1; giam gi&#x1EEF; qu&#x1EF9;, Bountysource &#x111;&#xE3; b&#x1ECB; c&#x1ED9;ng &#x111;&#x1ED3;ng t&#x1EA9;y chay v&#xE0; coi l&#xE0; r&#x1EE7;i ro cao. &#x110;&#x1EE9;ng l&#xEA;n thay th&#x1EBF; l&#xE0; c&#xE1;c n&#x1EC1;n t&#x1EA3;ng t&#xE0;i tr&#x1EE3; th&#x1EBF; h&#x1EC7; m&#x1EDB;i nh&#x1B0; <strong>Polar.sh</strong> v&#xE0; <strong>Algora</strong>. &#x110;&#x1EB7;c bi&#x1EC7;t, Polar.sh ho&#x1EA1;t &#x111;&#x1ED9;ng nh&#x1B0; m&#x1ED9;t &#x110;&#x1A1;n v&#x1ECB; X&#x1EED; l&#xFD; Th&#x1B0;&#x1A1;ng m&#x1EA1;i (Merchant of Record), t&#xED;ch h&#x1EE3;p s&#xE2;u v&#xE0;o GitHub. N&#xF3; t&#x1EF1; &#x111;&#x1ED9;ng x&#x1EED; l&#xFD; m&#x1ECD;i r&#x1EAF;c r&#x1ED1;i li&#xEA;n quan &#x111;&#x1EBF;n vi&#x1EC7;c thu thu&#x1EBF; v&#xE0; VAT to&#xE0;n c&#x1EA7;u, cho ph&#xE9;p nh&#x1EEF;ng ng&#x1B0;&#x1EDD;i theo d&#xF5;i d&#x1EF1; &#xE1;n &#x111;&#xF3;ng g&#xF3;p ti&#x1EC1;n th&#x1B0;&#x1EDF;ng v&#xE0;o c&#xE1;c y&#xEA;u c&#x1EA7;u t&#xED;nh n&#x103;ng (feature requests) c&#x1EE5; th&#x1EC3;, v&#xE0; ti&#x1EC1;n s&#x1EBD; &#x111;&#x1B0;&#x1EE3;c gi&#x1EA3;i ng&#xE2;n tr&#x1EF1;c ti&#x1EBF;p cho l&#x1EAD;p tr&#xEC;nh vi&#xEA;n x&#x1EED; l&#xFD; th&#xE0;nh c&#xF4;ng t&#xED;nh n&#x103;ng &#x111;&#xF3;, t&#x1EA1;o ra &#x111;&#x1ED9;ng l&#x1EF1;c kinh t&#x1EBF; t&#x1EE9;c th&#xEC;.</li><li><strong>T&#xE0;i Tr&#x1EE3; Phi T&#x1EAD;p Trung v&#xE0; Minh B&#x1EA1;ch (Fiscal Sponsorship):</strong> N&#x1EC1;n t&#x1EA3;ng <strong>Open Collective</strong> mang &#x111;&#x1EBF;n m&#x1ED9;t kh&#xE1;i ni&#x1EC7;m &#x111;&#x1ED9;t ph&#xE1;: T&#xE0;i tr&#x1EE3; T&#xE0;i ch&#xED;nh. Thay v&#xEC; ph&#x1EA3;i th&#xE0;nh l&#x1EAD;p m&#x1ED9;t c&#xF4;ng ty ph&#xE1;p l&#xFD; ph&#x1EE9;c t&#x1EA1;p, c&#xE1;c t&#x1EAD;p th&#x1EC3; nh&#xE0; ph&#xE1;t tri&#x1EC3;n c&#xF3; th&#x1EC3; ho&#x1EA1;t &#x111;&#x1ED9;ng d&#x1B0;&#x1EDB;i s&#x1EF1; b&#x1EA3;o tr&#x1EE3; c&#x1EE7;a m&#x1ED9;t t&#x1ED5; ch&#x1EE9;c phi l&#x1EE3;i nhu&#x1EAD;n 501(c)(6). &#x110;i&#x1EC3;m m&#x1EA1;nh tuy&#x1EC7;t &#x111;&#x1ED1;i c&#x1EE7;a Open Collective l&#xE0; s&#x1EF1; minh b&#x1EA1;ch t&#xE0;i ch&#xED;nh to&#xE0;n di&#x1EC7;n (Fully Transparent); to&#xE0;n b&#x1ED9; c&#x1ED9;ng &#x111;&#x1ED3;ng c&#xF3; th&#x1EC3; gi&#xE1;m s&#xE1;t theo th&#x1EDD;i gian th&#x1EF1;c d&#xF2;ng ti&#x1EC1;n quy&#xEA;n g&#xF3;p &#x111;&#x1EBF;n t&#x1EEB; &#x111;&#xE2;u v&#xE0; nh&#x1EEF;ng kho&#x1EA3;n chi ti&#xEA;u n&#xE0;o (nh&#x1B0; ti&#x1EC1;n thu&#xEA; m&#xE1;y ch&#x1EE7;, chi tr&#x1EA3; cho ng&#x1B0;&#x1EDD;i &#x111;&#xF3;ng g&#xF3;p) &#x111;&#xE3; &#x111;&#x1B0;&#x1EE3;c gi&#x1EA3;i ng&#xE2;n. Trong khi &#x111;&#xF3;, <strong>GitHub Sponsors</strong> t&#x1EAD;n d&#x1EE5;ng v&#x1ECB; th&#x1EBF; n&#x1EC1;n t&#x1EA3;ng trung t&#xE2;m c&#x1EE7;a m&#xEC;nh, cho ph&#xE9;p c&#xE1;c l&#x1EAD;p tr&#xEC;nh vi&#xEA;n nh&#x1EAD;n &#x111;&#x1B0;&#x1EE3;c t&#xE0;i tr&#x1EE3; &#x111;&#x1ECB;nh k&#x1EF3; t&#x1EEB; c&#xE1;c ng&#x1B0;&#x1EDD;i d&#xF9;ng kho l&#x1B0;u tr&#x1EEF; (repository) c&#x1EE7;a h&#x1ECD; v&#x1EDB;i m&#x1EE9;c ph&#xED; hoa h&#x1ED3;ng b&#x1EB1;ng 0 (zero fees), &#x111;&#x1B0;a n&#xFA;t t&#xE0;i tr&#x1EE3; v&#xE0;o th&#x1EB3;ng quy tr&#xEC;nh l&#xE0;m vi&#x1EC7;c h&#xE0;ng ng&#xE0;y c&#x1EE7;a k&#x1EF9; s&#x1B0;.</li><li><strong>T&#x1B0;&#x1A1;ng Lai M&#xE3; H&#xF3;a Gi&#x1EA5;y Ph&#xE9;p (License Tokenization):</strong> M&#x1ED9;t trong nh&#x1EEF;ng xu h&#x1B0;&#x1EDB;ng mang t&#xED;nh c&#xE1;ch m&#x1EA1;ng nh&#x1EA5;t n&#x103;m 2025 l&#xE0; vi&#x1EC7;c k&#x1EBF;t h&#x1EE3;p h&#x1EE3;p &#x111;&#x1ED3;ng th&#xF4;ng minh blockchain v&#xE0;o c&#x1EA5;p ph&#xE9;p ph&#x1EA7;n m&#x1EC1;m th&#xF4;ng qua c&#xE1;c n&#x1EC1;n t&#x1EA3;ng nh&#x1B0; license-token.com. M&#xF4; h&#xEC;nh n&#xE0;y chuy&#x1EC3;n &#x111;&#x1ED5;i c&#xE1;c gi&#x1EA5;y ph&#xE9;p ph&#x1EA7;n m&#x1EC1;m v&#x1EAD;t l&#xFD; th&#xE0;nh c&#xE1;c m&#xE3; th&#xF4;ng b&#xE1;o k&#x1EF9; thu&#x1EAD;t s&#x1ED1; (tokens), t&#x1EA1;o ra s&#x1EF1; minh b&#x1EA1;ch tuy&#x1EC7;t &#x111;&#x1ED1;i v&#xE0; d&#x1EA5;u v&#x1EBF;t ki&#x1EC3;m to&#xE1;n (audit trails) kh&#xF4;ng th&#x1EC3; gi&#x1EA3; m&#x1EA1;o. Vi&#x1EC7;c token h&#xF3;a cho ph&#xE9;p tri&#x1EC3;n khai c&#x1A1; ch&#x1EBF; c&#x1EA5;p ph&#xE9;p vi m&#xF4; (micro-licensing) linh ho&#x1EA1;t, ph&#xE2;n ph&#x1ED1;i tr&#x1EF1;c ti&#x1EBF;p doanh thu m&#x1ED9;t c&#xE1;ch t&#x1EF1; &#x111;&#x1ED9;ng cho t&#x1EEB;ng c&#xE1; nh&#xE2;n &#x111;&#xF3;ng g&#xF3;p m&#xE3; ngu&#x1ED3;n d&#x1EF1;a tr&#xEA;n t&#x1EF7; l&#x1EC7; c&#xF4;ng s&#x1EE9;c c&#x1EE7;a h&#x1ECD;, m&#x1EDF; ra kh&#x1EA3; n&#x103;ng thi&#x1EBF;t l&#x1EAD;p qu&#x1EA3;n tr&#x1ECB; t&#x1ED5; ch&#x1EE9;c t&#x1EF1; tr&#x1ECB; phi t&#x1EAD;p trung (DAO) cho c&#xE1;c d&#x1EF1; &#xE1;n ngu&#x1ED3;n m&#x1EDF; trong t&#x1B0;&#x1A1;ng lai.</li></ol><h3 id="%C4%91i%E1%BB%83m-giao-thoa-khi-ph%E1%BA%A7n-m%E1%BB%81m-m%C3%A3-ngu%E1%BB%93n-m%E1%BB%9F-t%E1%BA%ADn-d%E1%BB%A5ng-s%E1%BB%A9c-m%E1%BA%A1nh-c%E1%BB%A7a-kickstarter">&#x110;i&#x1EC3;m Giao Thoa: Khi Ph&#x1EA7;n M&#x1EC1;m M&#xE3; Ngu&#x1ED3;n M&#x1EDF; T&#x1EAD;n D&#x1EE5;ng S&#x1EE9;c M&#x1EA1;nh C&#x1EE7;a Kickstarter</h3><p>M&#x1ED9;t c&#xE1;ch ti&#x1EBF;p c&#x1EAD;n v&#xF4; c&#xF9;ng &#x111;&#x1ED9;c &#x111;&#xE1;o &#x111;&#x1EC3; th&#x1B0;&#x1A1;ng m&#x1EA1;i h&#xF3;a OSS l&#xE0; k&#x1EBF;t h&#x1EE3;p b&#x1EA3;n ch&#x1EA5;t d&#xE2;n ch&#x1EE7; c&#x1EE7;a m&#xE3; ngu&#x1ED3;n m&#x1EDF; v&#x1EDB;i t&#xED;nh kh&#x1EA9;n c&#x1EA5;p c&#x1EE7;a vi&#x1EC7;c g&#xE2;y qu&#x1EF9; tr&#xEA;n Kickstarter. B&#x1EDF;i v&#xEC; OSS v&#x1ED1;n d&#x129; kh&#xF4;ng c&#xF3; r&#xE0;o c&#x1EA3;n t&#xED;nh ph&#xED; &#x111;&#x1EC3; t&#x1EA3;i xu&#x1ED1;ng, c&#xE2;u h&#x1ECF;i &#x111;&#x1EB7;t ra l&#xE0;: T&#x1EA1;i sao ng&#x1B0;&#x1EDD;i d&#xF9;ng ph&#x1EA3;i b&#x1ECF; ti&#x1EC1;n t&#xFA;i ra t&#xE0;i tr&#x1EE3; cho m&#x1ED9;t th&#x1EE9; m&#xE0; cu&#x1ED1;i c&#xF9;ng h&#x1ECD; c&#xF3; th&#x1EC3; s&#x1EED; d&#x1EE5;ng mi&#x1EC5;n ph&#xED;?</p><p>Ch&#xEC;a kh&#xF3;a n&#x1EB1;m &#x1EDF; vi&#x1EC7;c b&#xE1;n &quot;Nhi&#x1EC7;m v&#x1EE5; chung&quot; (Mission-driven) v&#xE0; &quot;S&#x1EF1; ti&#x1EC7;n l&#x1EE3;i/&#x110;&#x1EB7;c quy&#x1EC1;n&quot; thay v&#xEC; b&#xE1;n m&#xE3; ngu&#x1ED3;n. Tr&#x1B0;&#x1EDD;ng h&#x1EE3;p nghi&#xEA;n c&#x1EE9;u kinh &#x111;i&#x1EC3;n cho s&#x1EF1; th&#xE0;nh c&#xF4;ng n&#xE0;y l&#xE0; <strong>Godot Engine</strong>, m&#x1ED9;t ph&#x1EA7;n m&#x1EC1;m l&#x1EAD;p tr&#xEC;nh game 2D v&#xE0; 3D &#x111;ang &#x111;e d&#x1ECD;a tr&#x1EF1;c ti&#x1EBF;p s&#x1EF1; th&#x1ED1;ng tr&#x1ECB; c&#x1EE7;a Unity. D&#xF9; to&#xE0;n b&#x1ED9; m&#xE3; ngu&#x1ED3;n c&#x1EE7;a Godot &#x111;&#x1B0;&#x1EE3;c ph&#xE1;t h&#xE0;nh d&#x1B0;&#x1EDB;i gi&#x1EA5;y ph&#xE9;p MIT (ho&#xE0;n to&#xE0;n mi&#x1EC5;n ph&#xED; v&#xE0; kh&#xF4;ng h&#x1EA1;n ch&#x1EBF; th&#x1B0;&#x1A1;ng m&#x1EA1;i), nh&#xF3;m ph&#xE1;t tri&#x1EC3;n &#x111;&#xE3; s&#x1EED; d&#x1EE5;ng Kickstarter m&#x1ED9;t c&#xE1;ch chi&#x1EBF;n l&#x1B0;&#x1EE3;c &#x111;&#x1EC3; g&#xE2;y qu&#x1EF9;. Thay v&#xEC; quy&#xEA;n g&#xF3;p &#x111;&#x1A1;n thu&#x1EA7;n, h&#x1ECD; b&#xE1;n c&#xE1;c ph&#x1EA7;n th&#x1B0;&#x1EDF;ng gi&#xE1; tr&#x1ECB; cao nh&#x1B0;:</p><ul><li>C&#xE1;c kh&#xF3;a h&#x1ECD;c &#x111;&#xE0;o t&#x1EA1;o l&#x1EAD;p tr&#xEC;nh &#x111;&#x1ED9;c quy&#x1EC1;n (nh&#x1B0; d&#x1EF1; &#xE1;n GDQuest) gi&#xFA;p ng&#x1B0;&#x1EDD;i d&#xF9;ng nhanh ch&#xF3;ng l&#xE0;m ch&#x1EE7; b&#x1ED9; m&#xE1;y.</li><li>B&#xE1;n h&#xE0;ng h&#xF3;a v&#x1EAD;t l&#xFD; (Widget Frosting) &#xE1;o thun, t&#xE0;i li&#x1EC7;u in &#x1EA5;n cao c&#x1EA5;p, ho&#x1EB7;c s&#xE1;ch ngh&#x1EC7; thu&#x1EAD;t (artbooks).</li><li>Cung c&#x1EA5;p g&#xF3;i t&#xE0;i tr&#x1EE3; c&#x1EA5;p doanh nghi&#x1EC7;p, cho ph&#xE9;p c&#xE1;c studio game l&#x1EDB;n &#x111;&#x1B0;a logo c&#x1EE7;a h&#x1ECD; v&#xE0;o ph&#x1EA7;n gi&#x1EDB;i thi&#x1EC7;u c&#x1EE7;a h&#x1EC7; th&#x1ED1;ng, gia t&#x103;ng uy t&#xED;n c&#x1EE7;a ch&#xED;nh doanh nghi&#x1EC7;p &#x111;&#xF3; trong c&#x1ED9;ng &#x111;&#x1ED3;ng ph&#xE1;t tri&#x1EC3;n game.</li><li>&#x110;&#x1EB7;c quy&#x1EC1;n b&#x1ECF; phi&#x1EBF;u ho&#x1EB7;c quy&#x1EC1;n &#x111;&#x1B0;&#x1EE3;c tham gia s&#x1EDB;m v&#xE0;o qu&#xE1; tr&#xEC;nh ph&#xE1;t tri&#x1EC3;n c&#xE1;c b&#x1EA3;n Alpha/Beta c&#x1EE7;a c&#xE1;c t&#xED;nh n&#x103;ng m&#x1EDB;i tr&#x1B0;&#x1EDB;c khi ch&#xFA;ng &#x111;&#x1B0;&#x1EE3;c xu&#x1EA5;t b&#x1EA3;n c&#xF4;ng khai.</li></ul><p>T&#x1B0;&#x1A1;ng t&#x1EF1;, d&#x1EF1; &#xE1;n n&#x1EC1;n t&#x1EA3;ng m&#x1EA1;ng x&#xE3; h&#x1ED9;i b&#x1EA3;o m&#x1EAD;t <strong>Diaspora</strong> &#x111;&#xE3; huy &#x111;&#x1ED9;ng &#x111;&#x1B0;&#x1EE3;c h&#x1A1;n 200.000 USD tr&#xEA;n Kickstarter d&#x1EF1;a v&#xE0;o s&#x1EE9;c m&#x1EA1;nh c&#x1EE7;a m&#x1ED9;t th&#xF4;ng &#x111;i&#x1EC7;p &#xFD; th&#x1EE9;c h&#x1EC7; v&#x1EC1; quy&#x1EC1;n ki&#x1EC3;m so&#xE1;t d&#x1EEF; li&#x1EC7;u c&#xE1; nh&#xE2;n, &#x111;&#xE1;nh tr&#xFA;ng t&#xE2;m l&#xFD; lo ng&#x1EA1;i v&#x1EC1; s&#x1EF1; &#x111;&#x1ED9;c quy&#x1EC1;n c&#x1EE7;a Facebook. Nh&#x1EEF;ng chi&#x1EBF;n d&#x1ECB;ch n&#xE0;y ch&#x1EE9;ng minh r&#x1EB1;ng, &#x111;&#x1ED1;i v&#x1EDB;i ph&#x1EA7;n m&#x1EC1;m, kh&#xE1;ch h&#xE0;ng s&#x1EB5;n s&#xE0;ng &#x111;&#xF3;ng vai tr&#xF2; nh&#x1B0; c&#xE1;c &quot;nh&#xE0; &#x111;&#x1EA7;u t&#x1B0; m&#x1ED3;i&quot; (seed investors) tr&#xEA;n Kickstarter khi h&#x1ECD; tin t&#x1B0;&#x1EDF;ng s&#xE2;u s&#x1EAF;c v&#xE0;o m&#x1ED9;t h&#x1EC7; th&#x1ED1;ng ph&#xE1;t tri&#x1EC3;n &#x1B0;u vi&#x1EC7;t, ch&#x1ED1;ng l&#x1EA1;i s&#x1EF1; ki&#x1EC1;m t&#x1ECF;a c&#x1EE7;a c&#xE1;c t&#x1EAD;p &#x111;o&#xE0;n c&#xF4;ng ngh&#x1EC7; kh&#xE9;p k&#xED;n.</p><h2 id="k%E1%BA%BFt-lu%E1%BA%ADn-cu%E1%BB%91i-c%C3%B9ng">K&#x1EBF;t Lu&#x1EAD;n Cu&#x1ED1;i C&#xF9;ng</h2><p>K&#x1EF7; nguy&#xEA;n huy &#x111;&#x1ED9;ng v&#x1ED1;n c&#x1ED9;ng &#x111;&#x1ED3;ng v&#xE0; phong tr&#xE0;o m&#xE3; ngu&#x1ED3;n m&#x1EDF; &#x111;&#xE3; v&#x129;nh vi&#x1EC5;n thay &#x111;&#x1ED5;i ph&#x1B0;&#x1A1;ng th&#x1EE9;c &#x111;&#x1ECB;nh h&#xEC;nh c&#xE1;c d&#x1EF1; &#xE1;n s&#xE1;ng t&#x1EA1;o, nh&#x1B0;ng s&#x1EF1; th&#xE0;nh c&#xF4;ng kh&#xF4;ng c&#xF2;n l&#xE0; s&#xE2;n ch&#x1A1;i c&#x1EE7;a nh&#x1EEF;ng k&#x1EBB; m&#x1ED9;ng m&#x1A1; thi&#x1EBF;u chi&#x1EBF;n l&#x1B0;&#x1EE3;c.</p><p>Vi&#x1EC7;c v&#x1EAD;n h&#xE0;nh m&#x1ED9;t chi&#x1EBF;n d&#x1ECB;ch g&#x1ECD;i v&#x1ED1;n tr&#xEA;n <strong>Kickstarter</strong> l&#xE0; m&#x1ED9;t h&#x1EC7; th&#x1ED1;ng to&#xE1;n h&#x1ECD;c kh&#xE9;p k&#xED;n: n&#xF3; &#x111;&#xF2;i h&#x1ECF;i s&#x1EF1; hi&#x1EC3;u bi&#x1EBF;t v&#x1EC1; c&#x1EA5;u tr&#xFA;c doanh nghi&#x1EC7;p xuy&#xEA;n bi&#xEA;n gi&#x1EDB;i, s&#x1EF1; c&#x1EA9;n tr&#x1ECD;ng tuy&#x1EC7;t &#x111;&#x1ED1;i v&#x1EDB;i c&#xE1;c ngh&#x129;a v&#x1EE5; b&#xE1;o c&#xE1;o thu&#x1EBF; c&#x1EE7;a IRS (&#x111;&#x1EB7;c bi&#x1EC7;t l&#xE0; m&#x1ED1;i &#x111;e d&#x1ECD;a 25.000 USD t&#x1EEB; M&#x1EAB;u 5472), kh&#x1EA3; n&#x103;ng hack thu&#x1EAD;t to&#xE1;n n&#x1EC1;n t&#x1EA3;ng b&#x1EB1;ng c&#xE1;c m&#x1EE5;c ti&#xEA;u khi&#xEA;m t&#x1ED1;n k&#x1EBF;t h&#x1EE3;p v&#x1EDB;i m&#x1ED9;t danh s&#xE1;ch kh&#xE1;ch h&#xE0;ng ti&#x1EC1;n kh&#x1EDF;i ch&#x1EA1;y kh&#x1ED5;ng l&#x1ED3;, v&#xE0; m&#x1ED9;t ngh&#x1EC7; thu&#x1EAD;t k&#x1EC3; chuy&#x1EC7;n &#x111;&#xE1;nh v&#xE0;o c&#x1EA3;m x&#xFA;c. M&#x1ECD;i s&#x1EF1; th&#x1EA5;t b&#x1EA1;i trong vi&#x1EC7;c t&#xED;nh to&#xE1;n chi ph&#xED; h&#x1EAD;u c&#x1EA7;n v&#xE0; thu&#x1EBF; quan s&#x1EBD; nhanh ch&#xF3;ng bi&#x1EBF;n s&#x1ED1; ti&#x1EC1;n huy &#x111;&#x1ED9;ng &#x111;&#x1B0;&#x1EE3;c th&#xE0;nh m&#x1ED9;t th&#x1EA3;m h&#x1ECD;a chu&#x1ED7;i cung &#x1EE9;ng, nh&#x1EA5;n ch&#xEC;m to&#xE0;n b&#x1ED9; c&#xF4;ng s&#x1EE9;c nghi&#xEA;n c&#x1EE9;u.</p><p>Trong khi &#x111;&#xF3;, tr&#xEA;n m&#x1EB7;t tr&#x1EAD;n <strong>Ph&#x1EA7;n m&#x1EC1;m M&#xE3; ngu&#x1ED3;n M&#x1EDF; (OSS)</strong>, s&#x1EF1; chuy&#x1EC3;n d&#x1ECB;ch m&#xF4; h&#xEC;nh b&#x1EA3;o v&#x1EC7; t&#xE0;i s&#x1EA3;n tr&#xED; tu&#x1EC7; l&#xE0; kh&#xF4;ng th&#x1EC3; &#x111;&#x1EA3;o ng&#x1B0;&#x1EE3;c. Gi&#x1EEF;a b&#x1ED1;i c&#x1EA3;nh c&#xE1;c nh&#xE0; cung c&#x1EA5;p &#x111;&#xE1;m m&#xE2;y li&#xEA;n t&#x1EE5;c th&#x1B0;&#x1A1;ng m&#x1EA1;i h&#xF3;a ch&#x1EA5;t x&#xE1;m c&#x1ED9;ng &#x111;&#x1ED3;ng, c&#xE1;c nh&#xE0; ph&#xE1;t tri&#x1EC3;n bu&#x1ED9;c ph&#x1EA3;i chuy&#x1EC3;n &#x111;&#x1ED5;i t&#x1EEB; t&#x1B0; duy nh&#x1EAD;n quy&#xEA;n g&#xF3;p sang c&#xE1;c m&#xF4; h&#xEC;nh doanh nghi&#x1EC7;p chi&#x1EBF;n l&#x1B0;&#x1EE3;c nh&#x1B0; C&#x1EA5;p ph&#xE9;p K&#xE9;p (Dual Licensing) ho&#x1EB7;c C&#x1ED1;t l&#xF5;i M&#x1EDF; (Open Core), k&#x1EBF;t h&#x1EE3;p c&#xF9;ng k&#x1EF9; n&#x103;ng ti&#x1EBF;p th&#x1ECB; Developer PLG &#x111;&#x1EC3; ti&#x1EBF;p c&#x1EAD;n kh&#xE1;ch h&#xE0;ng ti&#x1EC1;m n&#x103;ng. Tuy nhi&#xEA;n, b&#xE0;i h&#x1ECD;c &#x111;&#x1EAF;t gi&#xE1; t&#x1EEB; HashiCorp v&#xE0; Redis &#x111;&#xE3; ch&#x1EC9; ra gi&#x1EDB;i h&#x1EA1;n c&#x1EE7;a vi&#x1EC7;c &#xE1;p &#x111;&#x1EB7;t c&#xE1;c quy t&#x1EAF;c kh&#xE9;p k&#xED;n: Vi&#x1EC7;c &#x111;&#xE1;nh m&#x1EA5;t danh x&#x1B0;ng M&#xE3; ngu&#x1ED3;n m&#x1EDF; c&#xF3; th&#x1EC3; k&#xED;ch ho&#x1EA1;t l&#xE0;n s&#xF3;ng r&#x1EBD; nh&#xE1;nh m&#xE3; ngu&#x1ED3;n (forking), h&#x1EE7;y ho&#x1EA1;i l&#xF2;ng tin c&#x1ED9;ng &#x111;&#x1ED3;ng v&#xE0; t&#x1EA1;o ra c&#xE1;c &#x111;&#x1ED1;i th&#x1EE7; c&#x1EA1;nh tranh kh&#x1ED1;c li&#x1EC7;t ngay ch&#xED;nh t&#x1EEB; c&#x1A1; s&#x1EDF; m&#xE3; g&#x1ED1;c do ch&#xED;nh h&#x1ECD; vi&#x1EBF;t ra. S&#x1EF1; tr&#x1ED7;i d&#x1EAD;y c&#x1EE7;a c&#xE1;c n&#x1EC1;n t&#x1EA3;ng minh b&#x1EA1;ch nh&#x1B0; Open Collective, Polar.sh v&#xE0; ti&#x1EC1;m n&#x103;ng c&#x1EE7;a vi&#x1EC7;c m&#xE3; h&#xF3;a gi&#x1EA5;y ph&#xE9;p h&#x1EE9;a h&#x1EB9;n m&#x1ED9;t t&#x1B0;&#x1A1;ng lai n&#x1A1;i c&#xE1;c nh&#xE0; ph&#xE1;t tri&#x1EC3;n cu&#x1ED1;i c&#xF9;ng c&#xF3; th&#x1EC3; nh&#x1EAD;n &#x111;&#x1B0;&#x1EE3;c s&#x1EF1; &#x111;&#x1EC1;n b&#xF9; x&#x1EE9;ng &#x111;&#xE1;ng cho lao &#x111;&#x1ED9;ng c&#x1EE7;a h&#x1ECD; , b&#x1EA3;o v&#x1EC7; ng&#x1ECD;n l&#x1EED;a s&#xE1;ng t&#x1EA1;o c&#x1EE7;a m&#xE3; ngu&#x1ED3;n m&#x1EDF; m&#xE0; kh&#xF4;ng c&#x1EA7;n hy sinh quy&#x1EC1;n qu&#x1EA3;n tr&#x1ECB; &#x111;a d&#x1EA1;ng v&#xE0; t&#x1EF1; do c&#xF4;ng ngh&#x1EC7;.</p>]]></content:encoded></item><item><title><![CDATA[Làm Chủ Dữ Liệu Reactive trong SwiftUI với Property Wrappers]]></title><description><![CDATA[Trong bài viết này, chúng ta sẽ cùng nhau khám phá các Property Wrappers quan trọng trong SwiftUI, giúp bạn làm chủ dữ liệu reactive (phản ứng) và khiến giao diện của mình có thể "biến đổi" một cách dễ dàng.]]></description><link>https://makexyz.fun/reactive-user-interface-with-property-wrappers-in-swiftui/</link><guid isPermaLink="false">67de2a0ff04c901ae49b1cf7</guid><category><![CDATA[SwiftUI]]></category><dc:creator><![CDATA[Tony Phạm]]></dc:creator><pubDate>Sat, 22 Mar 2025 06:00:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Ch&#xE0;o m&#x1EEB;ng c&#xE1;c b&#x1EA1;n &#x111;&#x1EBF;n v&#x1EDB;i th&#x1EBF; gi&#x1EDB;i SwiftUI &#x111;&#x1EA7;y th&#xFA; v&#x1ECB;! Trong b&#xE0;i vi&#x1EBF;t n&#xE0;y, ch&#xFA;ng ta s&#x1EBD; c&#xF9;ng nhau kh&#xE1;m ph&#xE1; c&#xE1;c <strong>Property Wrappers</strong> quan tr&#x1ECD;ng trong SwiftUI, gi&#xFA;p b&#x1EA1;n l&#xE0;m ch&#x1EE7; d&#x1EEF; li&#x1EC7;u reactive (ph&#x1EA3;n &#x1EE9;ng) v&#xE0; khi&#x1EBF;n giao di&#x1EC7;n c&#x1EE7;a m&#xEC;nh c&#xF3; th&#x1EC3; &quot;bi&#x1EBF;n &#x111;&#x1ED5;i&quot; m&#x1ED9;t c&#xE1;ch d&#x1EC5; d&#xE0;ng.  B&#x1EA1;n s&#x1EB5;n s&#xE0;ng ch&#x1B0;a? C&#xF9;ng b&#x1EAF;t &#x111;&#x1EA7;u nh&#xE9;!</p>
<h2 id="1-property-wrappers-l%C3%A0-g%C3%AC-v%C3%A0-t%E1%BA%A1i-sao-ch%C3%BAng-l%E1%BA%A1i-vi-di%E1%BB%87u-%F0%9F%A4%94">1. Property Wrappers l&#xE0; g&#xEC; v&#xE0; t&#x1EA1;i sao ch&#xFA;ng l&#x1EA1;i &quot;vi di&#x1EC7;u&quot;? &#x1F914;</h2>
<p>H&#xE3;y t&#x1B0;&#x1EDF;ng t&#x1B0;&#x1EE3;ng b&#x1EA1;n c&#xF3; m&#x1ED9;t c&#xF4;ng t&#x1EAF;c &#x111;&#xE8;n trong nh&#xE0;. Khi b&#x1EA1;n b&#x1EAD;t c&#xF4;ng t&#x1EAF;c, &#x111;&#xE8;n s&#xE1;ng l&#xEA;n ngay l&#x1EAD;p t&#x1EE9;c. Khi b&#x1EA1;n t&#x1EAF;t, &#x111;&#xE8;n c&#x169;ng t&#x1EAF;t ngay. &#x110;&#xF3; ch&#xED;nh l&#xE0; t&#xED;nh ph&#x1EA3;n &#x1EE9;ng (reactive)! Trong SwiftUI, Property Wrappers &#x111;&#xF3;ng vai tr&#xF2; nh&#x1B0; nh&#x1EEF;ng &quot;c&#xF4;ng t&#x1EAF;c&quot; n&#xE0;y, k&#x1EBF;t n&#x1ED1;i d&#x1EEF; li&#x1EC7;u c&#x1EE7;a b&#x1EA1;n v&#x1EDB;i giao di&#x1EC7;n. Khi d&#x1EEF; li&#x1EC7;u thay &#x111;&#x1ED5;i, &quot;c&#xF4;ng t&#x1EAF;c&quot; s&#x1EBD; t&#x1EF1; &#x111;&#x1ED9;ng &quot;b&#x1EAD;t&quot; ho&#x1EB7;c &quot;t&#x1EAF;t&quot;, v&#xE0; giao di&#x1EC7;n s&#x1EBD; &quot;ph&#x1EA3;n &#x1EE9;ng&quot; theo, c&#x1EAD;p nh&#x1EAD;t ngay l&#x1EAD;p t&#x1EE9;c m&#xE0; b&#x1EA1;n kh&#xF4;ng c&#x1EA7;n ph&#x1EA3;i &quot;ra l&#x1EC7;nh&quot; th&#x1EE7; c&#xF4;ng.</p>
<p>C&#xE1;c Property Wrappers ch&#xED;nh m&#xE0; ch&#xFA;ng ta s&#x1EBD; kh&#xE1;m ph&#xE1; h&#xF4;m nay l&#xE0;:</p>
<ul>
<li><strong><code>@State</code></strong>: &quot;Tr&#x1EA1;ng th&#xE1;i c&#xE1; nh&#xE2;n&quot; c&#x1EE7;a View</li>
<li><strong><code>@Binding</code></strong>: &quot;C&#x1EA7;u n&#x1ED1;i d&#x1EEF; li&#x1EC7;u&quot; gi&#x1EEF;a c&#xE1;c View</li>
<li><strong><code>@ObservedObject</code> &amp; <code>@Published</code></strong>: &quot;Nh&#xE0; qu&#x1EA3;n l&#xFD; d&#x1EEF; li&#x1EC7;u&quot; chuy&#xEA;n nghi&#x1EC7;p</li>
<li><strong><code>@EnvironmentObject</code></strong>: &quot;D&#x1EEF; li&#x1EC7;u to&#xE0;n c&#x1EE5;c&quot; cho &#x1EE9;ng d&#x1EE5;ng</li>
</ul>
<p>&#x110;&#x1EC3; d&#x1EC5; h&#xEC;nh dung h&#x1A1;n, ch&#xFA;ng ta h&#xE3;y &#x111;i v&#xE0;o chi ti&#x1EBF;t t&#x1EEB;ng lo&#x1EA1;i v&#xE0; xem v&#xED; d&#x1EE5; c&#x1EE5; th&#x1EC3; nh&#xE9;!</p>
<h2 id="2-c%C3%A1c-property-wrappers-quan-tr%E1%BB%8Dng">2. C&#xE1;c Property Wrappers quan tr&#x1ECD;ng</h2>
<h3 id="state-tr%E1%BA%A1ng-th%C3%A1i-c%C3%A1-nh%C3%A2n-c%E1%BB%A7a-view-%F0%9F%8F%A0"><code>@State</code>: &quot;Tr&#x1EA1;ng th&#xE1;i c&#xE1; nh&#xE2;n&quot; c&#x1EE7;a View &#x1F3E0;</h3>
<p><code>@State</code> gi&#x1ED1;ng nh&#x1B0; &quot;tr&#x1EA1;ng th&#xE1;i&quot; ri&#xEA;ng c&#x1EE7;a m&#x1ED9;t View. N&#xF3; qu&#x1EA3;n l&#xFD; d&#x1EEF; li&#x1EC7;u <strong>c&#x1EE5;c b&#x1ED9;</strong> v&#xE0; &#x111;&#x1A1;n gi&#x1EA3;n, ch&#x1EC9; &#x1EA3;nh h&#x1B0;&#x1EDF;ng &#x111;&#x1EBF;n View m&#xE0; n&#xF3; &#x111;&#x1B0;&#x1EE3;c khai b&#xE1;o. Khi gi&#xE1; tr&#x1ECB; <code>@State</code> thay &#x111;&#x1ED5;i, SwiftUI s&#x1EBD; t&#x1EF1; &#x111;&#x1ED9;ng &quot;v&#x1EBD; l&#x1EA1;i&quot; (re-render) View &#x111;&#xF3; &#x111;&#x1EC3; c&#x1EAD;p nh&#x1EAD;t giao di&#x1EC7;n.</p>
<p><strong>V&#xED; d&#x1EE5;:</strong> M&#x1ED9;t n&#xFA;t b&#x1EA5;m thay &#x111;&#x1ED5;i ch&#x1EEF; khi nh&#x1EA5;n</p>
<pre><code class="language-swift">import SwiftUI

struct ContentView: View {
    @State private var buttonText: String = &quot;Nh&#x1EA5;n v&#xE0;o t&#xF4;i&quot; // Bi&#x1EBF;n State cho text n&#xFA;t

    var body: some View {
        VStack {
            Button(buttonText) { // N&#xFA;t v&#x1EDB;i text reactive
                if buttonText == &quot;Nh&#x1EA5;n v&#xE0;o t&#xF4;i&quot; {
                    buttonText = &quot;&#x110;&#xE3; nh&#x1EA5;n!&quot;
                } else {
                    buttonText = &quot;Nh&#x1EA5;n l&#x1EA1;i!&quot;
                }
            }
            .padding()
        }
    }
}
</code></pre>
<p><strong>Gi&#x1EA3;i th&#xED;ch:</strong></p>
<ul>
<li><code>@State private var buttonText: String = &quot;Nh&#x1EA5;n v&#xE0;o t&#xF4;i&quot;</code>: Ch&#xFA;ng ta khai b&#xE1;o <code>buttonText</code> l&#xE0; m&#x1ED9;t bi&#x1EBF;n <code>@State</code>.  Khi <code>buttonText</code> thay &#x111;&#x1ED5;i, View <code>ContentView</code> s&#x1EBD; t&#x1EF1; &#x111;&#x1ED9;ng c&#x1EAD;p nh&#x1EAD;t.</li>
<li><code>Button(buttonText) { ... }</code>: N&#xFA;t hi&#x1EC3;n th&#x1ECB; text t&#x1EEB; <code>buttonText</code>. B&#xEA;n trong n&#xFA;t, ch&#xFA;ng ta thay &#x111;&#x1ED5;i gi&#xE1; tr&#x1ECB; <code>buttonText</code>. V&#xEC; <code>buttonText</code> l&#xE0; <code>@State</code>, text c&#x1EE7;a n&#xFA;t s&#x1EBD; t&#x1EF1; &#x111;&#x1ED9;ng c&#x1EAD;p nh&#x1EAD;t theo!</li>
</ul>
<h3 id="binding-c%E1%BA%A7u-n%E1%BB%91i-d%E1%BB%AF-li%E1%BB%87u-gi%E1%BB%AFa-c%C3%A1c-view-%F0%9F%8C%89"><code>@Binding</code>: &quot;C&#x1EA7;u n&#x1ED1;i d&#x1EEF; li&#x1EC7;u&quot; gi&#x1EEF;a c&#xE1;c View &#x1F309;</h3>
<p><code>@Binding</code> t&#x1EA1;o ra m&#x1ED9;t <strong>k&#x1EBF;t n&#x1ED1;i hai chi&#x1EC1;u</strong> gi&#x1EEF;a d&#x1EEF; li&#x1EC7;u <code>@State</code> c&#x1EE7;a View cha v&#xE0; m&#x1ED9;t View con.  N&#xF3; cho ph&#xE9;p View con <strong>&#x111;&#x1ECD;c v&#xE0; thay &#x111;&#x1ED5;i</strong> d&#x1EEF; li&#x1EC7;u c&#x1EE7;a View cha.  Gi&#x1ED1;ng nh&#x1B0; m&#x1ED9;t &quot;c&#x1EA7;u n&#x1ED1;i&quot; &#x111;&#x1EC3; d&#x1EEF; li&#x1EC7;u &quot;ch&#x1EA3;y&quot; qua l&#x1EA1;i gi&#x1EEF;a c&#xE1;c View.</p>
<p><strong>V&#xED; d&#x1EE5;:</strong>  N&#xFA;t b&#x1EA5;m trong View con t&#x103;ng b&#x1ED9; &#x111;&#x1EBF;m &#x1EDF; View cha</p>
<pre><code class="language-swift">import SwiftUI

struct ContentView: View {
    @State private var counter = 0 // Bi&#x1EBF;n State b&#x1ED9; &#x111;&#x1EBF;m &#x1EDF; View cha

    var body: some View {
        VStack {
            Text(&quot;Gi&#xE1; tr&#x1ECB; b&#x1ED9; &#x111;&#x1EBF;m: \(counter)&quot;) // Hi&#x1EC3;n th&#x1ECB; b&#x1ED9; &#x111;&#x1EBF;m

            CounterButton(count: $counter) // Truy&#x1EC1;n Binding c&#x1EE7;a `counter` xu&#x1ED1;ng View con
        }
    }
}

struct CounterButton: View {
    @Binding var count: Int // Nh&#x1EAD;n Binding t&#x1EEB; View cha

    var body: some View {
        Button(&quot;T&#x103;ng b&#x1ED9; &#x111;&#x1EBF;m&quot;) {
            count += 1 // Thay &#x111;&#x1ED5;i gi&#xE1; tr&#x1ECB; `count`, View cha c&#x169;ng c&#x1EAD;p nh&#x1EAD;t
        }
        .padding()
    }
}
</code></pre>
<p><strong>Gi&#x1EA3;i th&#xED;ch:</strong></p>
<ul>
<li>Trong <code>ContentView</code>: <code>$counter</code> t&#x1EA1;o ra m&#x1ED9;t <strong>Binding</strong> t&#x1EEB; bi&#x1EBF;n <code>@State</code> <code>counter</code> v&#xE0; truy&#x1EC1;n xu&#x1ED1;ng <code>CounterButton</code>.</li>
<li>Trong <code>CounterButton</code>: <code>@Binding var count: Int</code> khai b&#xE1;o m&#x1ED9;t bi&#x1EBF;n <code>@Binding</code> &#x111;&#x1EC3; nh&#x1EAD;n k&#x1EBF;t n&#x1ED1;i.  Khi <code>count</code> thay &#x111;&#x1ED5;i trong <code>CounterButton</code>, n&#xF3; <strong>th&#x1EF1;c s&#x1EF1; thay &#x111;&#x1ED5;i bi&#x1EBF;n <code>@State</code> <code>counter</code> &#x1EDF; <code>ContentView</code></strong>, khi&#x1EBF;n <code>ContentView</code> c&#x1EAD;p nh&#x1EAD;t giao di&#x1EC7;n.</li>
</ul>
<h3 id="observedobject-published-nh%C3%A0-qu%E1%BA%A3n-l%C3%BD-d%E1%BB%AF-li%E1%BB%87u-chuy%C3%AAn-nghi%E1%BB%87p-%F0%9F%92%BC"><code>@ObservedObject</code> &amp; <code>@Published</code>: &quot;Nh&#xE0; qu&#x1EA3;n l&#xFD; d&#x1EEF; li&#x1EC7;u&quot; chuy&#xEA;n nghi&#x1EC7;p &#x1F4BC;</h3>
<p>Khi &#x1EE9;ng d&#x1EE5;ng c&#x1EE7;a b&#x1EA1;n ph&#x1EE9;c t&#x1EA1;p h&#x1A1;n, d&#x1EEF; li&#x1EC7;u kh&#xF4;ng ch&#x1EC9; l&#xE0; nh&#x1EEF;ng bi&#x1EBF;n &#x111;&#x1A1;n gi&#x1EA3;n n&#x1EEF;a. B&#x1EA1;n c&#xF3; th&#x1EC3; c&#x1EA7;n qu&#x1EA3;n l&#xFD; c&#xE1;c <strong>model d&#x1EEF; li&#x1EC7;u ph&#x1EE9;c t&#x1EA1;p</strong> (th&#x1B0;&#x1EDD;ng l&#xE0; c&#xE1;c class).  <code>@ObservedObject</code> v&#xE0; <code>@Published</code> s&#x1EBD; gi&#xFA;p b&#x1EA1;n!</p>
<ul>
<li><strong><code>ObservableObject</code></strong>:  M&#x1ED9;t protocol m&#xE0; class d&#x1EEF; li&#x1EC7;u c&#x1EE7;a b&#x1EA1;n c&#x1EA7;n tu&#xE2;n th&#x1EE7; &#x111;&#x1EC3; &quot;b&#xE1;o hi&#x1EC7;u&quot; cho SwiftUI bi&#x1EBF;t khi n&#xE0;o d&#x1EEF; li&#x1EC7;u b&#xEA;n trong n&#xF3; thay &#x111;&#x1ED5;i.</li>
<li><strong><code>@Published</code></strong>:  &#x110;&#xE1;nh d&#x1EA5;u c&#xE1;c thu&#x1ED9;c t&#xED;nh trong <code>ObservableObject</code> m&#xE0; b&#x1EA1;n mu&#x1ED1;n SwiftUI theo d&#xF5;i s&#x1EF1; thay &#x111;&#x1ED5;i. Khi m&#x1ED9;t thu&#x1ED9;c t&#xED;nh <code>@Published</code> thay &#x111;&#x1ED5;i, c&#xE1;c View &#x111;ang &quot;quan s&#xE1;t&quot; <code>ObservableObject</code> s&#x1EBD; &#x111;&#x1B0;&#x1EE3;c c&#x1EAD;p nh&#x1EAD;t.</li>
<li><strong><code>@ObservedObject</code></strong>:  S&#x1EED; d&#x1EE5;ng trong View &#x111;&#x1EC3; &quot;quan s&#xE1;t&quot; m&#x1ED9;t instance c&#x1EE7;a <code>ObservableObject</code>.</li>
</ul>
<p><strong>V&#xED; d&#x1EE5;:</strong> Qu&#x1EA3;n l&#xFD; t&#xEA;n ng&#x1B0;&#x1EDD;i d&#xF9;ng v&#xE0; c&#x1EAD;p nh&#x1EAD;t giao di&#x1EC7;n khi t&#xEA;n thay &#x111;&#x1ED5;i</p>
<pre><code class="language-swift">import SwiftUI
import Combine // Import Combine framework

class UserData: ObservableObject { // Class qu&#x1EA3;n l&#xFD; d&#x1EEF; li&#x1EC7;u, tu&#xE2;n th&#x1EE7; ObservableObject
    @Published var userName: String = &quot;Kh&#xE1;ch&quot; // Thu&#x1ED9;c t&#xED;nh Published

    func changeUserName(newName: String) {
        userName = newName
    }
}

struct ContentView: View {
    @ObservedObject var userData = UserData() // Quan s&#xE1;t instance c&#x1EE7;a UserData

    var body: some View {
        VStack {
            Text(&quot;Xin ch&#xE0;o, \(userData.userName)&quot;) // Hi&#x1EC3;n th&#x1ECB; t&#xEA;n ng&#x1B0;&#x1EDD;i d&#xF9;ng

            Button(&quot;&#x110;&#x1ED5;i t&#xEA;n&quot;) {
                userData.changeUserName(newName: &quot;Ng&#x1B0;&#x1EDD;i d&#xF9;ng m&#x1EDB;i&quot;) // Thay &#x111;&#x1ED5;i t&#xEA;n trong UserData
            }
            .padding()
        }
    }
}
</code></pre>
<p><strong>Gi&#x1EA3;i th&#xED;ch:</strong></p>
<ul>
<li><code>class UserData: ObservableObject</code>:  <code>UserData</code> l&#xE0; m&#x1ED9;t class qu&#x1EA3;n l&#xFD; d&#x1EEF; li&#x1EC7;u, tu&#xE2;n th&#x1EE7; <code>ObservableObject</code>.</li>
<li><code>@Published var userName: String</code>: <code>userName</code> l&#xE0; thu&#x1ED9;c t&#xED;nh <code>@Published</code>. Khi <code>userName</code> thay &#x111;&#x1ED5;i, SwiftUI s&#x1EBD; bi&#x1EBF;t.</li>
<li><code>@ObservedObject var userData = UserData()</code>: Trong <code>ContentView</code>, ch&#xFA;ng ta t&#x1EA1;o v&#xE0; &quot;quan s&#xE1;t&quot; m&#x1ED9;t instance c&#x1EE7;a <code>UserData</code> b&#x1EB1;ng <code>@ObservedObject</code>.</li>
<li><code>Text(&quot;Xin ch&#xE0;o, \(userData.userName)&quot;)</code>: Text hi&#x1EC3;n th&#x1ECB; <code>userData.userName</code>. Khi <code>userData.userName</code> thay &#x111;&#x1ED5;i, Text s&#x1EBD; t&#x1EF1; &#x111;&#x1ED9;ng c&#x1EAD;p nh&#x1EAD;t.</li>
</ul>
<h3 id="environmentobject-d%E1%BB%AF-li%E1%BB%87u-to%C3%A0n-c%E1%BB%A5c-cho-%E1%BB%A9ng-d%E1%BB%A5ng-%F0%9F%8C%8D"><code>@EnvironmentObject</code>: &quot;D&#x1EEF; li&#x1EC7;u to&#xE0;n c&#x1EE5;c&quot; cho &#x1EE9;ng d&#x1EE5;ng &#x1F30D;</h3>
<p><code>@EnvironmentObject</code> l&#xE0; &quot;v&#x169; kh&#xED; b&#xED; m&#x1EAD;t&quot; khi b&#x1EA1;n mu&#x1ED1;n chia s&#x1EBB; <strong>d&#x1EEF; li&#x1EC7;u chung cho to&#xE0;n b&#x1ED9; &#x1EE9;ng d&#x1EE5;ng</strong> m&#xE0; kh&#xF4;ng c&#x1EA7;n ph&#x1EA3;i &quot;truy&#x1EC1;n tay&quot; qua t&#x1EEB;ng View.  R&#x1EA5;t h&#x1EEF;u &#xED;ch cho d&#x1EEF; li&#x1EC7;u nh&#x1B0; theme &#x1EE9;ng d&#x1EE5;ng, c&#xE0;i &#x111;&#x1EB7;t ng&#x1B0;&#x1EDD;i d&#xF9;ng, tr&#x1EA1;ng th&#xE1;i &#x111;&#x103;ng nh&#x1EAD;p...</p>
<p>&#x110;&#x1EC3; s&#x1EED; d&#x1EE5;ng <code>@EnvironmentObject</code>, b&#x1EA1;n c&#x1EA7;n:</p>
<ol>
<li><strong>T&#x1EA1;o <code>ObservableObject</code></strong> ch&#x1EE9;a d&#x1EEF; li&#x1EC7;u chung.</li>
<li><strong>&quot;Inject&quot; object v&#xE0;o m&#xF4;i tr&#x1B0;&#x1EDD;ng</strong> b&#x1EB1;ng <code>.environmentObject()</code> &#x1EDF; View &quot;g&#x1ED1;c&quot; (th&#x1B0;&#x1EDD;ng l&#xE0; App ho&#x1EB7;c Scene).</li>
<li><strong>Truy c&#x1EAD;p d&#x1EEF; li&#x1EC7;u</strong> trong b&#x1EA5;t k&#x1EF3; View con n&#xE0;o b&#x1EB1;ng <code>@EnvironmentObject</code>.</li>
</ol>
<p><strong>(V&#xED; d&#x1EE5; v&#x1EC1; <code>@EnvironmentObject</code> s&#x1EBD; ph&#x1EE9;c t&#x1EA1;p h&#x1A1;n m&#x1ED9;t ch&#xFA;t v&#xE0; th&#x1B0;&#x1EDD;ng &#x111;&#x1B0;&#x1EE3;c s&#x1EED; d&#x1EE5;ng trong c&#xE1;c d&#x1EF1; &#xE1;n l&#x1EDB;n h&#x1A1;n.  B&#x1EA1;n c&#xF3; th&#x1EC3; t&#xEC;m hi&#x1EC3;u th&#xEA;m v&#x1EC1; n&#xF3; khi l&#xE0;m quen v&#x1EDB;i ki&#x1EBF;n tr&#xFA;c &#x1EE9;ng d&#x1EE5;ng SwiftUI n&#xE2;ng cao nh&#xE9;!)</strong></p>
<h2 id="3-b%E1%BA%A3ng-so-s%C3%A1nh-property-wrappers-nh%C3%ACn-m%E1%BB%99t-l%E1%BA%A7n-nh%E1%BB%9B-m%C3%A3i-%F0%9F%98%89">3. B&#x1EA3;ng So S&#xE1;nh Property Wrappers: &quot;Nh&#xEC;n M&#x1ED9;t L&#x1EA7;n Nh&#x1EDB; M&#xE3;i&quot; &#x1F609;</h2>
<p>&#x110;&#x1EC3; gi&#xFA;p b&#x1EA1;n d&#x1EC5; d&#xE0;ng so s&#xE1;nh v&#xE0; l&#x1EF1;a ch&#x1ECD;n Property Wrapper ph&#xF9; h&#x1EE3;p, &#x111;&#xE2;y l&#xE0; b&#x1EA3;ng t&#x1ED5;ng h&#x1EE3;p:</p>
<table>
<thead>
<tr>
<th>T&#xED;nh n&#x103;ng/&#x110;&#x1EB7;c &#x111;i&#x1EC3;m</th>
<th><code>@State</code></th>
<th><code>@Binding</code></th>
<th><code>@ObservedObject</code> &amp; <code>@Published</code></th>
<th><code>@EnvironmentObject</code></th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>M&#x1EE5;c &#x111;&#xED;ch s&#x1EED; d&#x1EE5;ng</strong></td>
<td>Qu&#x1EA3;n l&#xFD; tr&#x1EA1;ng th&#xE1;i <strong>c&#x1EE5;c b&#x1ED9;</strong> c&#x1EE7;a View.</td>
<td>T&#x1EA1;o <strong>k&#x1EBF;t n&#x1ED1;i hai chi&#x1EC1;u</strong> v&#x1EDB;i d&#x1EEF; li&#x1EC7;u <code>@State</code>.</td>
<td>Qu&#x1EA3;n l&#xFD; <strong>d&#x1EEF; li&#x1EC7;u ph&#x1EE9;c t&#x1EA1;p</strong>, chia s&#x1EBB; gi&#x1EEF;a nhi&#x1EC1;u View.</td>
<td>Chia s&#x1EBB; <strong>d&#x1EEF; li&#x1EC7;u &#x1EE9;ng d&#x1EE5;ng r&#x1ED9;ng</strong>, truy c&#x1EAD;p d&#x1EC5; d&#xE0;ng.</td>
</tr>
<tr>
<td><strong>Ph&#x1EA1;m vi d&#x1EEF; li&#x1EC7;u</strong></td>
<td><strong>C&#x1EE5;c b&#x1ED9;</strong> trong View khai b&#xE1;o.</td>
<td><strong>Li&#xEA;n k&#x1EBF;t</strong> v&#x1EDB;i d&#x1EEF; li&#x1EC7;u <code>@State</code> &#x1EDF; View cha.</td>
<td><strong>To&#xE0;n b&#x1ED9; &#x1EE9;ng d&#x1EE5;ng</strong> (th&#xF4;ng qua ObservableObject).</td>
<td><strong>To&#xE0;n b&#x1ED9; c&#xE2;y View</strong> n&#x1A1;i &#x111;&#x1B0;&#x1EE3;c inject v&#xE0;o m&#xF4;i tr&#x1B0;&#x1EDD;ng.</td>
</tr>
<tr>
<td><strong>Quy&#x1EC1;n s&#x1EDF; h&#x1EEF;u d&#x1EEF; li&#x1EC7;u</strong></td>
<td>View khai b&#xE1;o <code>@State</code> <strong>s&#x1EDF; h&#x1EEF;u</strong> d&#x1EEF; li&#x1EC7;u.</td>
<td>Kh&#xF4;ng s&#x1EDF; h&#x1EEF;u, <strong>tham chi&#x1EBF;u</strong> &#x111;&#x1EBF;n d&#x1EEF; li&#x1EC7;u g&#x1ED1;c.</td>
<td><code>ObservableObject</code> <strong>s&#x1EDF; h&#x1EEF;u</strong> d&#x1EEF; li&#x1EC7;u.</td>
<td><code>ObservableObject</code> <strong>s&#x1EDF; h&#x1EEF;u</strong> d&#x1EEF; li&#x1EC7;u.</td>
</tr>
<tr>
<td><strong>Lo&#x1EA1;i d&#x1EEF; li&#x1EC7;u ph&#xF9; h&#x1EE3;p</strong></td>
<td>&#x110;&#x1A1;n gi&#x1EA3;n (Int, String, Bool, Struct...).</td>
<td>B&#x1EA5;t k&#x1EF3; lo&#x1EA1;i d&#x1EEF; li&#x1EC7;u n&#xE0;o c&#x1EE7;a <code>@State</code> g&#x1ED1;c.</td>
<td><strong>Class</strong> tu&#xE2;n th&#x1EE7; <code>ObservableObject</code>.</td>
<td><strong>Class</strong> tu&#xE2;n th&#x1EE7; <code>ObservableObject</code>.</td>
</tr>
<tr>
<td><strong>C&#x1A1; ch&#x1EBF; reactive</strong></td>
<td>Thay &#x111;&#x1ED5;i gi&#xE1; tr&#x1ECB; -&gt; <strong>re-render View</strong>.</td>
<td>Thay &#x111;&#x1ED5;i gi&#xE1; tr&#x1ECB; -&gt; <strong>c&#x1EAD;p nh&#x1EAD;t View cha</strong>.</td>
<td><code>@Published</code> th&#xF4;ng b&#xE1;o thay &#x111;&#x1ED5;i -&gt; View c&#x1EAD;p nh&#x1EAD;t.</td>
<td><code>@Published</code> th&#xF4;ng b&#xE1;o thay &#x111;&#x1ED5;i -&gt; View c&#x1EAD;p nh&#x1EAD;t.</td>
</tr>
<tr>
<td><strong>C&#xE1;ch khai b&#xE1;o</strong></td>
<td><code>swift @State private var tenBien = giaTriBanDau </code></td>
<td><code>swift @Binding var tenBien: KieuDuLieu </code> (trong View con)</td>
<td><code>swift @ObservedObject var tenObject = TenObservableObject() </code></td>
<td><code>swift @EnvironmentObject var tenObject: TenObservableObject </code></td>
</tr>
<tr>
<td><strong>C&#xE1;ch truy&#x1EC1;n d&#x1EEF; li&#x1EC7;u</strong></td>
<td>Kh&#xF4;ng c&#x1EA7;n truy&#x1EC1;n, d&#xF9;ng tr&#x1EF1;c ti&#x1EBF;p trong View.</td>
<td>Truy&#x1EC1;n qua <strong>Binding</strong> (<code>$tenBienState</code>) t&#x1EEB; View cha.</td>
<td>T&#x1EA1;o instance c&#x1EE7;a <code>ObservableObject</code> v&#xE0; d&#xF9;ng <code>@ObservedObject</code>.</td>
<td>Inject v&#xE0;o m&#xF4;i tr&#x1B0;&#x1EDD;ng b&#x1EB1;ng <code>.environmentObject()</code> &#x1EDF; View cha.</td>
</tr>
<tr>
<td><strong>Khi n&#xE0;o n&#xEA;n d&#xF9;ng</strong></td>
<td>Tr&#x1EA1;ng th&#xE1;i UI &#x111;&#x1A1;n gi&#x1EA3;n, c&#x1EE5;c b&#x1ED9;.</td>
<td>Chia s&#x1EBB; v&#xE0; s&#x1EED;a &#x111;&#x1ED5;i d&#x1EEF; li&#x1EC7;u gi&#x1EEF;a View cha v&#xE0; con.</td>
<td>Qu&#x1EA3;n l&#xFD; model d&#x1EEF; li&#x1EC7;u, logic nghi&#x1EC7;p v&#x1EE5; ph&#x1EE9;c t&#x1EA1;p.</td>
<td>D&#x1EEF; li&#x1EC7;u c&#x1EA5;u h&#xEC;nh &#x1EE9;ng d&#x1EE5;ng, theme, tr&#x1EA1;ng th&#xE1;i &#x111;&#x103;ng nh&#x1EAD;p.</td>
</tr>
<tr>
<td><strong>V&#xED; d&#x1EE5;</strong></td>
<td>Bi&#x1EBF;n &#x111;&#x1EBF;m, tr&#x1EA1;ng th&#xE1;i toggle, text input t&#x1EA1;m th&#x1EDD;i.</td>
<td>Truy&#x1EC1;n d&#x1EEF; li&#x1EC7;u t&#x1EEB; Form cha xu&#x1ED1;ng TextField con.</td>
<td>D&#x1EEF; li&#x1EC7;u ng&#x1B0;&#x1EDD;i d&#xF9;ng, danh s&#xE1;ch s&#x1EA3;n ph&#x1EA9;m, gi&#x1ECF; h&#xE0;ng.</td>
<td>Theme &#x1EE9;ng d&#x1EE5;ng, ng&#xF4;n ng&#x1EEF;, c&#xE0;i &#x111;&#x1EB7;t ng&#x1B0;&#x1EDD;i d&#xF9;ng.</td>
</tr>
</tbody>
</table>
<h2 id="4-t%E1%BB%95ng-h%E1%BB%A3p">4. T&#x1ED5;ng h&#x1EE3;p</h2>
<h3 id="t%C3%B3m-t%E1%BA%AFt-%C4%91i%E1%BB%83m-gi%E1%BB%91ng-nhau-gi%E1%BB%AFa-c%C3%A1c-property-wrappers">T&#xF3;m t&#x1EAF;t &#x111;i&#x1EC3;m gi&#x1ED1;ng nhau gi&#x1EEF;a c&#xE1;c Property Wrappers:</h3>
<ul>
<li><strong>T&#xED;nh Reactive:</strong> T&#x1EA5;t c&#x1EA3; &#x111;&#x1EC1;u gi&#xFA;p d&#x1EEF; li&#x1EC7;u tr&#x1EDF; n&#xEA;n reactive, ngh&#x129;a l&#xE0; khi d&#x1EEF; li&#x1EC7;u thay &#x111;&#x1ED5;i, giao di&#x1EC7;n ng&#x1B0;&#x1EDD;i d&#xF9;ng s&#x1EBD; t&#x1EF1; &#x111;&#x1ED9;ng c&#x1EAD;p nh&#x1EAD;t &#x111;&#x1EC3; ph&#x1EA3;n &#xE1;nh s&#x1EF1; thay &#x111;&#x1ED5;i &#x111;&#xF3;. &#x110;&#xE2;y l&#xE0; c&#x1ED1;t l&#xF5;i c&#x1EE7;a SwiftUI v&#xE0; declarative UI.</li>
<li><strong>Property Wrappers:</strong>  V&#x1EC1; m&#x1EB7;t k&#x1EF9; thu&#x1EAD;t, ch&#xFA;ng &#x111;&#x1EC1;u l&#xE0; Property Wrappers trong Swift, cung c&#x1EA5;p m&#x1ED9;t l&#x1EDB;p tr&#x1EEB;u t&#x1B0;&#x1EE3;ng &#x111;&#x1EC3; qu&#x1EA3;n l&#xFD; vi&#x1EC7;c l&#x1B0;u tr&#x1EEF; v&#xE0; truy c&#x1EAD;p d&#x1EEF; li&#x1EC7;u, &#x111;&#x1ED3;ng th&#x1EDD;i th&#xEA;m c&#xE1;c h&#xE0;nh vi &#x111;&#x1EB7;c bi&#x1EC7;t (&#x1EDF; &#x111;&#xE2;y l&#xE0; t&#xED;nh reactive).</li>
<li><strong>S&#x1EED; d&#x1EE5;ng trong View:</strong> Ch&#xFA;ng &#x111;&#x1B0;&#x1EE3;c s&#x1EED; d&#x1EE5;ng &#x111;&#x1EC3; khai b&#xE1;o c&#xE1;c thu&#x1ED9;c t&#xED;nh b&#xEA;n trong struct <code>View</code> trong SwiftUI.</li>
</ul>
<h3 id="t%C3%B3m-t%E1%BA%AFt-%C4%91i%E1%BB%83m-kh%C3%A1c-nhau-ch%C3%ADnh-gi%E1%BB%AFa-c%C3%A1c-property-wrappers">T&#xF3;m t&#x1EAF;t &#x111;i&#x1EC3;m kh&#xE1;c nhau ch&#xED;nh gi&#x1EEF;a c&#xE1;c Property Wrappers:</h3>
<ul>
<li>
<p><strong>Ph&#x1EA1;m vi v&#xE0; Quy&#x1EC1;n s&#x1EDF; h&#x1EEF;u d&#x1EEF; li&#x1EC7;u:</strong> &#x110;&#xE2;y l&#xE0; kh&#xE1;c bi&#x1EC7;t l&#x1EDB;n nh&#x1EA5;t.</p>
<ul>
<li><code>@State</code>: D&#x1EEF; li&#x1EC7;u c&#x1EE5;c b&#x1ED9;, View t&#x1EF1; s&#x1EDF; h&#x1EEF;u.</li>
<li><code>@Binding</code>: Tham chi&#x1EBF;u &#x111;&#x1EBF;n d&#x1EEF; li&#x1EC7;u <code>@State</code> c&#x1EE7;a View kh&#xE1;c, kh&#xF4;ng s&#x1EDF; h&#x1EEF;u.</li>
<li><code>@ObservedObject</code> &amp; <code>@Published</code>: D&#x1EEF; li&#x1EC7;u thu&#x1ED9;c v&#x1EC1; <code>ObservableObject</code>, chia s&#x1EBB; r&#x1ED9;ng r&#xE3;i, c&#xF3; th&#x1EC3; &#x111;&#x1B0;&#x1EE3;c s&#x1EDF; h&#x1EEF;u b&#x1EDF;i m&#x1ED9;t class qu&#x1EA3;n l&#xFD; d&#x1EEF; li&#x1EC7;u ri&#xEA;ng.</li>
<li><code>@EnvironmentObject</code>: D&#x1EEF; li&#x1EC7;u &#x1EE9;ng d&#x1EE5;ng r&#x1ED9;ng, &#x111;&#x1B0;&#x1EE3;c &quot;inject&quot; v&#xE0;o m&#xF4;i tr&#x1B0;&#x1EDD;ng, c&#x169;ng thu&#x1ED9;c v&#x1EC1; <code>ObservableObject</code> nh&#x1B0;ng &#x111;&#x1B0;&#x1EE3;c qu&#x1EA3;n l&#xFD; &#x1EDF; m&#x1EE9;c cao h&#x1A1;n (th&#x1B0;&#x1EDD;ng l&#xE0; App ho&#x1EB7;c Scene).</li>
</ul>
</li>
<li>
<p><strong>M&#x1EE5;c &#x111;&#xED;ch s&#x1EED; d&#x1EE5;ng:</strong> M&#x1ED7;i Property Wrapper &#x111;&#x1B0;&#x1EE3;c thi&#x1EBF;t k&#x1EBF; cho m&#x1ED9;t m&#x1EE5;c &#x111;&#xED;ch c&#x1EE5; th&#x1EC3;, t&#x1EEB; qu&#x1EA3;n l&#xFD; tr&#x1EA1;ng th&#xE1;i c&#x1EE5;c b&#x1ED9; &#x111;&#x1A1;n gi&#x1EA3;n &#x111;&#x1EBF;n chia s&#x1EBB; d&#x1EEF; li&#x1EC7;u ph&#x1EE9;c t&#x1EA1;p tr&#xEA;n to&#xE0;n &#x1EE9;ng d&#x1EE5;ng.</p>
</li>
<li>
<p><strong>C&#xE1;ch truy&#x1EC1;n d&#x1EEF; li&#x1EC7;u v&#xE0; truy c&#x1EAD;p:</strong> C&#xE1;ch b&#x1EA1;n truy&#x1EC1;n d&#x1EEF; li&#x1EC7;u (n&#x1EBF;u c&#x1EA7;n) v&#xE0; c&#xE1;ch c&#xE1;c View truy c&#x1EAD;p d&#x1EEF; li&#x1EC7;u kh&#xE1;c nhau t&#xF9;y thu&#x1ED9;c v&#xE0;o Property Wrapper b&#x1EA1;n s&#x1EED; d&#x1EE5;ng.</p>
</li>
</ul>
<h3 id="l%C6%B0u-%C3%BD-quan-tr%E1%BB%8Dng">L&#x1B0;u &#xFD; quan tr&#x1ECD;ng:**</h3>
<ul>
<li><strong><code>@Published</code> kh&#xF4;ng ph&#x1EA3;i l&#xE0; Property Wrapper &#x111;&#x1ED9;c l&#x1EAD;p:</strong> <code>@Published</code> lu&#xF4;n &#x111;&#x1B0;&#x1EE3;c s&#x1EED; d&#x1EE5;ng <strong>b&#xEA;n trong</strong> m&#x1ED9;t class tu&#xE2;n th&#x1EE7; <code>ObservableObject</code>. N&#xF3; &#x111;&#xE1;nh d&#x1EA5;u c&#xE1;c thu&#x1ED9;c t&#xED;nh trong class &#x111;&#xF3; m&#xE0; khi thay &#x111;&#x1ED5;i s&#x1EBD; k&#xED;ch ho&#x1EA1;t th&#xF4;ng b&#xE1;o c&#x1EAD;p nh&#x1EAD;t giao di&#x1EC7;n.</li>
<li><strong><code>@Environment</code> (kh&#xF4;ng c&#xF3; trong b&#x1EA3;ng tr&#xEA;n, nh&#x1B0;ng li&#xEA;n quan &#x111;&#x1EBF;n <code>@EnvironmentObject</code>):</strong>  <code>@Environment</code> l&#xE0; m&#x1ED9;t Property Wrapper kh&#xE1;c, cho ph&#xE9;p b&#x1EA1;n truy c&#x1EAD;p c&#xE1;c gi&#xE1; tr&#x1ECB; <strong>m&#xF4;i tr&#x1B0;&#x1EDD;ng h&#x1EC7; th&#x1ED1;ng</strong> (nh&#x1B0; theme h&#x1EC7; th&#x1ED1;ng, k&#xED;ch th&#x1B0;&#x1EDB;c font ch&#x1EEF;, ch&#x1EBF; &#x111;&#x1ED9; dark mode) m&#xE0; SwiftUI cung c&#x1EA5;p. N&#xF3; kh&#xE1;c v&#x1EDB;i <code>@EnvironmentObject</code> &#x1EDF; ch&#x1ED7; n&#xF3; kh&#xF4;ng ph&#x1EA3;i l&#xE0; d&#x1EEF; li&#x1EC7;u b&#x1EA1;n t&#x1EF1; t&#x1EA1;o ra v&#xE0; inject, m&#xE0; l&#xE0; d&#x1EEF; li&#x1EC7;u h&#x1EC7; th&#x1ED1;ng c&#xF3; s&#x1EB5;n.</li>
</ul>
<h3 id="ch%E1%BB%8Dn-property-wrapper-n%C3%A0o-cho-chu%E1%BA%A9n-%F0%9F%A4%94">Ch&#x1ECD;n Property Wrapper n&#xE0;o cho &quot;chu&#x1EA9;n&quot;? &#x1F914;</h3>
<p>Kh&#xF4;ng c&#xF3; &quot;c&#xF4;ng th&#x1EE9;c&quot; n&#xE0;o &#x111;&#xFA;ng cho m&#x1ECD;i tr&#x1B0;&#x1EDD;ng h&#x1EE3;p, nh&#x1B0;ng &#x111;&#xE2;y l&#xE0; m&#x1ED9;t v&#xE0;i g&#x1EE3;i &#xFD;:</p>
<ol>
<li>D&#x1EEF; li&#x1EC7;u n&#xE0;y ch&#x1EC9; c&#x1EA7;n thi&#x1EBF;t cho View n&#xE0;y th&#xF4;i ph&#x1EA3;i kh&#xF4;ng?  -&gt;  <code>@State</code></li>
<li>T&#xF4;i c&#x1EA7;n chia s&#x1EBB; d&#x1EEF; li&#x1EC7;u n&#xE0;y v&#x1EDB;i View con v&#xE0; cho ph&#xE9;p View con s&#x1EED;a &#x111;&#x1ED5;i n&#xF3;? -&gt; <code>@Binding</code></li>
<li>D&#x1EEF; li&#x1EC7;u c&#x1EE7;a t&#xF4;i ph&#x1EE9;c t&#x1EA1;p h&#x1A1;n v&#xE0; c&#x1EA7;n chia s&#x1EBB; gi&#x1EEF;a nhi&#x1EC1;u View ho&#x1EB7;c qu&#x1EA3;n l&#xFD; logic nghi&#x1EC7;p v&#x1EE5;? -&gt; <code>@ObservedObject</code> &amp; <code>@Published</code></li>
<li>D&#x1EEF; li&#x1EC7;u n&#xE0;y l&#xE0; c&#x1EA5;u h&#xEC;nh &#x1EE9;ng d&#x1EE5;ng, theme, ho&#x1EB7;c tr&#x1EA1;ng th&#xE1;i chung m&#xE0; nhi&#x1EC1;u View c&#x1EA7;n truy c&#x1EAD;p? -&gt; <code>@EnvironmentObject</code></li>
</ol>
<p>Hy v&#x1ECD;ng b&#xE0;i vi&#x1EBF;t n&#xE0;y &#x111;&#xE3; gi&#xFA;p b&#x1EA1;n hi&#x1EC3;u r&#xF5; h&#x1A1;n v&#x1EC1; Property Wrappers v&#xE0; c&#xE1;ch ch&#xFA;ng mang l&#x1EA1;i t&#xED;nh reactive cho SwiftUI.  H&#xE3;y th&#x1EED; nghi&#x1EC7;m, th&#x1EF1;c h&#xE0;nh v&#x1EDB;i c&#xE1;c v&#xED; d&#x1EE5; v&#xE0; b&#x1EA1;n s&#x1EBD; th&#x1EA5;y vi&#x1EC7;c t&#x1EA1;o ra giao di&#x1EC7;n &quot;bi&#x1EBF;n &#x111;&#x1ED5;i&quot; trong SwiftUI th&#x1EAD;t d&#x1EC5; d&#xE0;ng v&#xE0; th&#xFA; v&#x1ECB;!</p>
<p>Ch&#xFA;c b&#x1EA1;n th&#xE0;nh c&#xF4;ng tr&#xEA;n h&#xE0;nh tr&#xEC;nh chinh ph&#x1EE5;c SwiftUI!  N&#x1EBF;u c&#xF3; b&#x1EA5;t k&#x1EF3; c&#xE2;u h&#x1ECF;i n&#xE0;o, &#x111;&#x1EEB;ng ng&#x1EA7;n ng&#x1EA1;i &#x111;&#x1EC3; l&#x1EA1;i b&#xEC;nh lu&#x1EAD;n b&#xEA;n d&#x1B0;&#x1EDB;i nh&#xE9;! &#x1F44B;</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Nâng Cấp SwiftUI: Làm Chủ Components, Modifiers và "Vũ Khí" Custom Views!]]></title><description><![CDATA[Trong bài viết hôm nay, chúng ta sẽ cùng nhau "nâng cấp" kỹ năng SwiftUI, khám phá những công cụ mạnh mẽ giúp bạn tạo ra giao diện ứng dụng không chỉ đẹp mà còn linh hoạt, dễ bảo trì và đậm chất riêng: Components, Modifiers và Custom Views!]]></description><link>https://makexyz.fun/nang-cap-swiftui-lam-chu-components-modifiers-va-vu-khi-custom-views/</link><guid isPermaLink="false">67de33acf04c901ae49b1d29</guid><category><![CDATA[SwiftUI]]></category><dc:creator><![CDATA[Tony Phạm]]></dc:creator><pubDate>Sat, 22 Mar 2025 03:53:47 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h2 id="m%E1%BB%9F-%C4%91%E1%BA%A7u">M&#x1EDF; &#x111;&#x1EA7;u:</h2>
<p>Ch&#xE0;o m&#x1EEB;ng b&#x1EA1;n tr&#x1EDF; l&#x1EA1;i v&#x1EDB;i h&#xE0;nh tr&#xEC;nh kh&#xE1;m ph&#xE1; SwiftUI! N&#x1EBF;u b&#x1EA1;n &#x111;&#xE3; t&#x1EEB;ng b&#x1B0;&#x1EDB;c ch&#xE2;n v&#xE0;o th&#x1EBF; gi&#x1EDB;i SwiftUI v&#xE0; l&#xE0;m quen v&#x1EDB;i nh&#x1EEF;ng th&#xE0;nh ph&#x1EA7;n c&#x1A1; b&#x1EA3;n nh&#x1B0; <code>Text</code> v&#xE0; <code>Button</code>, th&#xEC; xin ch&#xFA;c m&#x1EEB;ng, b&#x1EA1;n &#x111;&#xE3; c&#xF3; m&#x1ED9;t kh&#x1EDF;i &#x111;&#x1EA7;u tuy&#x1EC7;t v&#x1EDD;i! Nh&#x1B0;ng &#x111;&#x1EC3; th&#x1EF1;c s&#x1EF1; &quot;l&#xE0;m ch&#x1EE7;&quot; SwiftUI v&#xE0; x&#xE2;y d&#x1EF1;ng nh&#x1EEF;ng &#x1EE9;ng d&#x1EE5;ng iOS chuy&#xEA;n nghi&#x1EC7;p, &#x111;&#x1EB9;p m&#x1EAF;t, ch&#xFA;ng ta c&#x1EA7;n ti&#x1EBF;n xa h&#x1A1;n n&#x1EEF;a.</p>
<p>Trong b&#xE0;i vi&#x1EBF;t h&#xF4;m nay, ch&#xFA;ng ta s&#x1EBD; c&#xF9;ng nhau &quot;n&#xE2;ng c&#x1EA5;p&quot; k&#x1EF9; n&#x103;ng SwiftUI, kh&#xE1;m ph&#xE1; nh&#x1EEF;ng c&#xF4;ng c&#x1EE5; m&#x1EA1;nh m&#x1EBD; gi&#xFA;p b&#x1EA1;n t&#x1EA1;o ra giao di&#x1EC7;n &#x1EE9;ng d&#x1EE5;ng kh&#xF4;ng ch&#x1EC9; &#x111;&#x1EB9;p m&#xE0; c&#xF2;n linh ho&#x1EA1;t, d&#x1EC5; b&#x1EA3;o tr&#xEC; v&#xE0; &#x111;&#x1EAD;m ch&#x1EA5;t ri&#xEA;ng: <strong>Components, Modifiers v&#xE0; Custom Views!</strong></p>
<h2 id="1-m%E1%BB%9F-r%E1%BB%99ng-v%C5%A9-tr%E1%BB%A5-components-kh%C3%B4ng-ch%E1%BB%89-c%C3%B3-text-v%C3%A0-button">1. M&#x1EDF; R&#x1ED9;ng &quot;V&#x169; Tr&#x1EE5;&quot; Components: Kh&#xF4;ng Ch&#x1EC9; C&#xF3; Text v&#xE0; Button!</h2>
<p>SwiftUI cung c&#x1EA5;p m&#x1ED9;t th&#x1B0; vi&#x1EC7;n phong ph&#xFA; c&#xE1;c th&#xE0;nh ph&#x1EA7;n giao di&#x1EC7;n (Components) &#x111;&#x1EC3; b&#x1EA1;n th&#x1ECF;a s&#x1EE9;c s&#xE1;ng t&#x1EA1;o.  Kh&#xF4;ng ch&#x1EC9; d&#x1EEB;ng l&#x1EA1;i &#x1EDF; <code>Text</code> v&#xE0; <code>Button</code>, h&#xE3;y c&#xF9;ng kh&#xE1;m ph&#xE1; th&#xEA;m nh&#x1EEF;ng &quot;ng&#x1B0;&#x1EDD;i b&#x1EA1;n &#x111;&#x1ED3;ng h&#xE0;nh&quot; &#x111;&#x1EAF;c l&#x1EF1;c kh&#xE1;c:</p>
<h3 id="imagehi%E1%BB%83n-th%E1%BB%8B-h%C3%ACnh-%E1%BA%A3nh"><code>Image</code> - Hi&#x1EC3;n Th&#x1ECB; H&#xEC;nh &#x1EA2;nh:</h3>
<pre><code>*   T&#x1EEB; logo &#x1EE9;ng d&#x1EE5;ng, &#x1EA3;nh s&#x1EA3;n ph&#x1EA9;m &#x111;&#x1EBF;n avatar ng&#x1B0;&#x1EDD;i d&#xF9;ng, `Image` gi&#xFA;p b&#x1EA1;n &#x111;&#x1B0;a h&#xEC;nh &#x1EA3;nh v&#xE0;o &#x1EE9;ng d&#x1EE5;ng m&#x1ED9;t c&#xE1;ch d&#x1EC5; d&#xE0;ng.
*   T&#xEC;m hi&#x1EC3;u c&#xE1;ch: Hi&#x1EC3;n th&#x1ECB; &#x1EA3;nh t&#x1EEB; Assets Catalog (`Image(&quot;t&#xEA;n_&#x1EA3;nh&quot;)`), t&#xF9;y ch&#x1EC9;nh k&#xED;ch th&#x1B0;&#x1EDB;c (`.resizable()`, `.scaledToFit()`, `.scaledToFill()`, `.frame()`), bo g&#xF3;c (`.cornerRadius()`), v&#xE0; th&#x1EAD;m ch&#xED; &quot;c&#x1EAF;t&quot; &#x1EA3;nh theo h&#xEC;nh d&#x1EA1;ng b&#x1EA5;t k&#x1EF3; (`.clipShape()`).

```swift
Image(&quot;logo_app&quot;)
    .resizable()
    .scaledToFit()
    .frame(width: 100, height: 100)
    .cornerRadius(15)
```
</code></pre>
<h3 id="textfield%C3%B4-nh%E1%BA%ADp-li%E1%BB%87u-v%C4%83n-b%E1%BA%A3n"><code>TextField</code> - &#xD4; Nh&#x1EAD;p Li&#x1EC7;u V&#x103;n B&#x1EA3;n:</h3>
<pre><code>*   Thu th&#x1EAD;p th&#xF4;ng tin t&#x1EEB; ng&#x1B0;&#x1EDD;i d&#xF9;ng ch&#x1B0;a bao gi&#x1EDD; d&#x1EC5; d&#xE0;ng &#x111;&#x1EBF;n th&#x1EBF;! `TextField` cho ph&#xE9;p b&#x1EA1;n t&#x1EA1;o c&#xE1;c &#xF4; nh&#x1EAD;p li&#x1EC7;u linh ho&#x1EA1;t cho t&#xEA;n, email, &#x111;&#x1ECB;a ch&#x1EC9;...
*   T&#xEC;m hi&#x1EC3;u c&#xE1;ch: T&#x1EA1;o &#xF4; nh&#x1EAD;p li&#x1EC7;u v&#x1EDB;i placeholder text, t&#xF9;y ch&#x1EC9;nh ki&#x1EC3;u b&#xE0;n ph&#xED;m (`.keyboardType()`), style (`.textFieldStyle()`), v&#xE0; quan tr&#x1ECD;ng nh&#x1EA5;t l&#xE0; li&#xEA;n k&#x1EBF;t d&#x1EEF; li&#x1EC7;u nh&#x1EAD;p v&#xE0;o v&#x1EDB;i bi&#x1EBF;n tr&#x1EA1;ng th&#xE1;i b&#x1EB1;ng `@State`.

```swift
@State private var username: String = &quot;&quot;

TextField(&quot;T&#xEA;n &#x111;&#x103;ng nh&#x1EAD;p&quot;, text: $username)
    .textFieldStyle(RoundedBorderTextFieldStyle())
    .padding()
```
</code></pre>
<h3 id="sliderthanh-tr%C6%B0%E1%BB%A3t-gi%C3%A1-tr%E1%BB%8B"><code>Slider</code> - Thanh Tr&#x1B0;&#x1EE3;t Gi&#xE1; Tr&#x1ECB;:</h3>
<pre><code>*   Cho ph&#xE9;p ng&#x1B0;&#x1EDD;i d&#xF9;ng ch&#x1ECD;n m&#x1ED9;t gi&#xE1; tr&#x1ECB; trong m&#x1ED9;t kho&#x1EA3;ng c&#x1EE5; th&#x1EC3;, `Slider` r&#x1EA5;t h&#x1EEF;u &#xED;ch cho vi&#x1EC7;c &#x111;i&#x1EC1;u ch&#x1EC9;nh &#xE2;m l&#x1B0;&#x1EE3;ng, &#x111;&#x1ED9; s&#xE1;ng, ho&#x1EB7;c b&#x1EA5;t k&#x1EF3; gi&#xE1; tr&#x1ECB; s&#x1ED1; n&#xE0;o.
*   T&#xEC;m hi&#x1EC3;u c&#xE1;ch: T&#x1EA1;o thanh tr&#x1B0;&#x1EE3;t, gi&#x1EDB;i h&#x1EA1;n gi&#xE1; tr&#x1ECB; (`in: ...`), b&#x1B0;&#x1EDB;c nh&#x1EA3;y (`step:`), v&#xE0; hi&#x1EC3;n th&#x1ECB; gi&#xE1; tr&#x1ECB; hi&#x1EC7;n t&#x1EA1;i.

```swift
@State private var volume: Double = 50.0

HStack {
    Slider(value: $volume, in: 0...100, step: 1)
    Text(&quot;\(Int(volume))&quot;)
}
```
</code></pre>
<h3 id="togglec%C3%B4ng-t%E1%BA%AFc-b%E1%BA%ADtt%E1%BA%AFt"><code>Toggle</code> - C&#xF4;ng T&#x1EAF;c B&#x1EAD;t/T&#x1EAF;t:</h3>
<pre><code>*   Th&#xEA;m ch&#x1EE9;c n&#x103;ng b&#x1EAD;t/t&#x1EAF;t m&#x1ED9;t c&#xE0;i &#x111;&#x1EB7;t ho&#x1EB7;c t&#xED;nh n&#x103;ng n&#xE0;o &#x111;&#xF3; trong &#x1EE9;ng d&#x1EE5;ng c&#x1EE7;a b&#x1EA1;n v&#x1EDB;i `Toggle`.
*   T&#xEC;m hi&#x1EC3;u c&#xE1;ch: T&#x1EA1;o c&#xF4;ng t&#x1EAF;c v&#x1EDB;i ti&#xEA;u &#x111;&#x1EC1; (`&quot;...&quot;`), v&#xE0; li&#xEA;n k&#x1EBF;t tr&#x1EA1;ng th&#xE1;i b&#x1EAD;t/t&#x1EAF;t v&#x1EDB;i bi&#x1EBF;n `@State` (`isOn: $bi&#x1EBF;n_state`).

```swift
@State private var darkModeEnabled: Bool = false

Toggle(&quot;Ch&#x1EBF; &#x111;&#x1ED9; t&#x1ED1;i&quot;, isOn: $darkModeEnabled)
    .padding()
```
</code></pre>
<h3 id="pickerdanh-s%C3%A1ch-l%E1%BB%B1a-ch%E1%BB%8Dn"><code>Picker</code> - Danh S&#xE1;ch L&#x1EF1;a Ch&#x1ECD;n:</h3>
<pre><code>*   Khi b&#x1EA1;n c&#x1EA7;n cho ng&#x1B0;&#x1EDD;i d&#xF9;ng ch&#x1ECD;n m&#x1ED9;t gi&#xE1; tr&#x1ECB; t&#x1EEB; m&#x1ED9;t danh s&#xE1;ch c&#xE1;c t&#xF9;y ch&#x1ECD;n, `Picker` l&#xE0; l&#x1EF1;a ch&#x1ECD;n ho&#xE0;n h&#x1EA3;o.
*   T&#xEC;m hi&#x1EC3;u c&#xE1;ch: T&#x1EA1;o dropdown ho&#x1EB7;c picker wheel, cung c&#x1EA5;p danh s&#xE1;ch l&#x1EF1;a ch&#x1ECD;n (`ForEach`), v&#xE0; li&#xEA;n k&#x1EBF;t gi&#xE1; tr&#x1ECB; &#x111;&#x1B0;&#x1EE3;c ch&#x1ECD;n v&#x1EDB;i bi&#x1EBF;n `@State` (`selection: $bi&#x1EBF;n_state`).

```swift
@State private var selectedColor = &quot;&#x110;&#x1ECF;&quot;
let colors = [&quot;&#x110;&#x1ECF;&quot;, &quot;Xanh&quot;, &quot;V&#xE0;ng&quot;]

Picker(&quot;Ch&#x1ECD;n m&#xE0;u&quot;, selection: $selectedColor) {
    ForEach(colors, id: \.self) { color in
        Text(color)
    }
}
.padding()
```
</code></pre>
<h3 id="progressviewhi%E1%BB%83n-th%E1%BB%8B-ti%E1%BA%BFn-tr%C3%ACnh"><code>ProgressView</code> - Hi&#x1EC3;n Th&#x1ECB; Ti&#x1EBF;n Tr&#xEC;nh:</h3>
<pre><code>*   Th&#xF4;ng b&#xE1;o cho ng&#x1B0;&#x1EDD;i d&#xF9;ng bi&#x1EBF;t m&#x1ED9;t c&#xF4;ng vi&#x1EC7;c &#x111;ang di&#x1EC5;n ra (v&#xED; d&#x1EE5;: t&#x1EA3;i d&#x1EEF; li&#x1EC7;u, x&#x1EED; l&#xFD; t&#xE1;c v&#x1EE5;) v&#x1EDB;i `ProgressView`.
*   T&#xEC;m hi&#x1EC3;u c&#xE1;ch: Hi&#x1EC3;n th&#x1ECB; ti&#x1EBF;n tr&#xEC;nh v&#xF4; &#x111;&#x1ECB;nh (indeterminate - ch&#x1EC9; b&#xE1;o &#x111;ang ch&#x1EA1;y) v&#xE0; x&#xE1;c &#x111;&#x1ECB;nh (determinate - hi&#x1EC3;n th&#x1ECB; ph&#x1EA7;n tr&#x103;m ho&#xE0;n th&#xE0;nh).

```swift
ProgressView() // Indeterminate

ProgressView(&quot;&#x110;ang t&#x1EA3;i...&quot;, value: progressValue, total: 100) // Determinate
```
</code></pre>
<h3 id="spacerkh%C3%B4ng-gian-%E1%BA%A3o-linh-ho%E1%BA%A1t"><code>Spacer</code> - &quot;Kh&#xF4;ng Gian &#x1EA2;o&quot; Linh Ho&#x1EA1;t:</h3>
<pre><code>*   `Spacer` kh&#xF4;ng hi&#x1EC3;n th&#x1ECB; b&#x1EA5;t c&#x1EE9; th&#x1EE9; g&#xEC; tr&#xEA;n giao di&#x1EC7;n, nh&#x1B0;ng l&#x1EA1;i l&#xE0; &quot;v&#x169; kh&#xED; b&#xED; m&#x1EAD;t&quot; &#x111;&#x1EC3; t&#x1EA1;o ra b&#x1ED1; c&#x1EE5;c &#x111;&#x1EB9;p m&#x1EAF;t v&#xE0; c&#xE2;n &#x111;&#x1ED1;i. N&#xF3; t&#x1EA1;o ra kho&#x1EA3;ng tr&#x1ED1;ng linh ho&#x1EA1;t, gi&#xFA;p b&#x1EA1;n c&#x103;n ch&#x1EC9;nh c&#xE1;c th&#xE0;nh ph&#x1EA7;n kh&#xE1;c m&#x1ED9;t c&#xE1;ch d&#x1EC5; d&#xE0;ng.
*   T&#xEC;m hi&#x1EC3;u c&#xE1;ch: S&#x1EED; d&#x1EE5;ng `Spacer()` &#x111;&#x1EC3; chi&#x1EBF;m to&#xE0;n b&#x1ED9; kh&#xF4;ng gian c&#xF3; th&#x1EC3;, ho&#x1EB7;c t&#xF9;y ch&#x1EC9;nh k&#xED;ch th&#x1B0;&#x1EDB;c b&#x1EB1;ng `.frame()`.

```swift
HStack {
    Text(&quot;B&#xEA;n tr&#xE1;i&quot;)
    Spacer() // &#x110;&#x1EA9;y Text &quot;B&#xEA;n ph&#x1EA3;i&quot; v&#x1EC1; ph&#xED;a b&#xEA;n ph&#x1EA3;i
    Text(&quot;B&#xEA;n ph&#x1EA3;i&quot;)
}
```
</code></pre>
<h2 id="2-modifiers-ph%C3%A9p-thu%E1%BA%ADt-t%C3%B9y-bi%E1%BA%BFn-giao-di%E1%BB%87n-theo-%C3%BD-mu%E1%BB%91n">2. Modifiers: &quot;Ph&#xE9;p Thu&#x1EAD;t&quot; T&#xF9;y Bi&#x1EBF;n Giao Di&#x1EC7;n Theo &#xDD; Mu&#x1ED1;n</h2>
<p>Modifiers gi&#x1ED1;ng nh&#x1B0; nh&#x1EEF;ng &quot;b&#x1ED9; l&#x1ECD;c&quot; ma thu&#x1EAD;t, cho ph&#xE9;p b&#x1EA1;n thay &#x111;&#x1ED5;i m&#x1ECD;i kh&#xED;a c&#x1EA1;nh c&#x1EE7;a m&#x1ED9;t View: t&#x1EEB; k&#xED;ch th&#x1B0;&#x1EDB;c, m&#xE0;u s&#x1EAF;c, font ch&#x1EEF;, b&#x1ED1; c&#x1EE5;c, &#x111;&#x1EBF;n h&#xE0;nh vi t&#x1B0;&#x1A1;ng t&#xE1;c.  Ch&#xFA;ng l&#xE0; ch&#xEC;a kh&#xF3;a &#x111;&#x1EC3; bi&#x1EBF;n nh&#x1EEF;ng component c&#x1A1; b&#x1EA3;n th&#xE0;nh giao di&#x1EC7;n &#x111;&#x1ED9;c &#x111;&#xE1;o v&#xE0; ph&#xF9; h&#x1EE3;p v&#x1EDB;i phong c&#xE1;ch &#x1EE9;ng d&#x1EE5;ng c&#x1EE7;a b&#x1EA1;n.</p>
<p>C&#xE1;c Modifiers ph&#x1ED5; bi&#x1EBF;n &#x111;&#x1B0;&#x1EE3;c chia th&#xE0;nh c&#xE1;c nh&#xF3;m ch&#xED;nh:</p>
<h3 id="layout-modifiers-thay-%C4%91%E1%BB%95i-c%C3%A1ch-view-%C4%91%C6%B0%E1%BB%A3c-b%E1%BB%91-tr%C3%AD-v%C3%A0-s%E1%BA%AFp-x%E1%BA%BFp">Layout Modifiers:  Thay &#x111;&#x1ED5;i c&#xE1;ch View &#x111;&#x1B0;&#x1EE3;c b&#x1ED1; tr&#xED; v&#xE0; s&#x1EAF;p x&#x1EBF;p.</h3>
<pre><code>*   `.padding()`: T&#x1EA1;o kho&#x1EA3;ng c&#xE1;ch l&#x1EC1; xung quanh View.
*   `.frame(width:height:alignment:)`: Thi&#x1EBF;t l&#x1EAD;p k&#xED;ch th&#x1B0;&#x1EDB;c v&#xE0; v&#x1ECB; tr&#xED; View.
*   `.position(x:y:)` &amp; `.offset(x:y:)`: &#x110;&#x1ECB;nh v&#x1ECB; View trong h&#x1EC7; t&#x1ECD;a &#x111;&#x1ED9; c&#x1EE7;a parent view.
</code></pre>
<h3 id="appearance-modifiers-thay-%C4%91%E1%BB%95i-h%C3%ACnh-th%E1%BB%A9c-hi%E1%BB%83n-th%E1%BB%8B-c%E1%BB%A7a-view">Appearance Modifiers:  Thay &#x111;&#x1ED5;i h&#xEC;nh th&#x1EE9;c hi&#x1EC3;n th&#x1ECB; c&#x1EE7;a View.</h3>
<pre><code>*   `.font(_:)`: T&#xF9;y ch&#x1EC9;nh font ch&#x1EEF; (`.title`, `.body`, `.system(size:weight:design:)`).
*   `.foregroundColor(_:)`: Thay &#x111;&#x1ED5;i m&#xE0;u ch&#x1EEF; ho&#x1EB7;c m&#xE0;u s&#x1EAF;c chung c&#x1EE7;a View.
*   `.background(_:ignoresSafeArea:)`: &#x110;&#x1EB7;t m&#xE0;u n&#x1EC1;n ho&#x1EB7;c background View kh&#xE1;c.
*   `.cornerRadius(_:)`: Bo tr&#xF2;n g&#xF3;c View.
*   `.border(_:width:)`: T&#x1EA1;o &#x111;&#x1B0;&#x1EDD;ng vi&#x1EC1;n cho View.
*   `.shadow(color:radius:x:y:)`: Th&#xEA;m b&#xF3;ng &#x111;&#x1ED5; &#x111;&#x1EC3; t&#x1EA1;o chi&#x1EC1;u s&#xE2;u.
*   `.opacity(_:)`: &#x110;i&#x1EC1;u ch&#x1EC9;nh &#x111;&#x1ED9; trong su&#x1ED1;t c&#x1EE7;a View.
</code></pre>
<h3 id="behavior-modifiers-thay-%C4%91%E1%BB%95i-c%C3%A1ch-view-t%C6%B0%C6%A1ng-t%C3%A1c-v%E1%BB%9Bi-ng%C6%B0%E1%BB%9Di-d%C3%B9ng">Behavior Modifiers:  Thay &#x111;&#x1ED5;i c&#xE1;ch View t&#x1B0;&#x1A1;ng t&#xE1;c v&#x1EDB;i ng&#x1B0;&#x1EDD;i d&#xF9;ng.</h3>
<pre><code>*   `.onTapGesture(count:perform:)`: X&#x1EED; l&#xFD; s&#x1EF1; ki&#x1EC7;n ch&#x1EA1;m (tap).
*   `.onLongPressGesture(minimumDuration:perform:onPressingChanged:)`: X&#x1EED; l&#xFD; nh&#x1EA5;n gi&#x1EEF;.
*   `.disabled(_:)`: V&#xF4; hi&#x1EC7;u h&#xF3;a t&#x1B0;&#x1A1;ng t&#xE1;c c&#x1EE7;a View.
*   `.hidden()`: &#x1EA8;n View kh&#x1ECF;i giao di&#x1EC7;n.
</code></pre>
<p><strong>Quan tr&#x1ECD;ng:</strong> Modifiers &#x111;&#x1B0;&#x1EE3;c &quot;chain&quot; (n&#x1ED1;i ti&#x1EBF;p) nhau v&#xE0; <strong>th&#x1EE9; t&#x1EF1;</strong> c&#x1EE7;a ch&#xFA;ng c&#xF3; th&#x1EC3; &#x1EA3;nh h&#x1B0;&#x1EDF;ng &#x111;&#x1EBF;n k&#x1EBF;t qu&#x1EA3; hi&#x1EC3;n th&#x1ECB;. H&#xE3;y th&#x1EED; nghi&#x1EC7;m v&#xE0; quan s&#xE1;t s&#x1EF1; kh&#xE1;c bi&#x1EC7;t!</p>
<h2 id="3-custom-components-v%C5%A9-kh%C3%AD-b%C3%AD-m%E1%BA%ADt-ch%E1%BB%91ng-l%E1%BA%A1i-dot-panic-v%C3%A0-t%C3%A1i-s%E1%BB%AD-d%E1%BB%A5ng-code">3. Custom Components: &quot;V&#x169; Kh&#xED;&quot; B&#xED; M&#x1EAD;t Ch&#x1ED1;ng L&#x1EA1;i &quot;Dot Panic&quot; v&#xE0; T&#xE1;i S&#x1EED; D&#x1EE5;ng Code</h2>
<p>Khi giao di&#x1EC7;n &#x1EE9;ng d&#x1EE5;ng tr&#x1EDF; n&#xEA;n ph&#x1EE9;c t&#x1EA1;p, vi&#x1EC7;c &quot;chain&quot; qu&#xE1; nhi&#x1EC1;u modifiers l&#xEA;n m&#x1ED9;t View c&#xF3; th&#x1EC3; d&#x1EAB;n &#x111;&#x1EBF;n code d&#xE0;i d&#xF2;ng, kh&#xF3; &#x111;&#x1ECD;c, kh&#xF3; b&#x1EA3;o tr&#xEC;, v&#xE0; g&#xE2;y ra t&#xEC;nh tr&#x1EA1;ng &quot;dot panic&quot; (l&#x1EA1;m d&#x1EE5;ng d&#x1EA5;u ch&#x1EA5;m).  &#x110;&#x1EC3; gi&#x1EA3;i quy&#x1EBF;t v&#x1EA5;n &#x111;&#x1EC1; n&#xE0;y, v&#xE0; &#x111;&#x1ED3;ng th&#x1EDD;i t&#x1EA1;o ra code t&#xE1;i s&#x1EED; d&#x1EE5;ng, gi&#x1EA3;i ph&#xE1;p t&#x1ED1;i &#x1B0;u ch&#xED;nh l&#xE0; <strong>Custom Components (Custom Views)</strong>!</p>
<h3 id="custom-components-l%C3%A0-g%C3%AC">Custom Components l&#xE0; g&#xEC;?</h3>
<p>&#x110;&#x1A1;n gi&#x1EA3;n, Custom Components l&#xE0; nh&#x1EEF;ng View &quot;con&quot; m&#xE0; b&#x1EA1;n t&#x1EF1; t&#x1EA1;o ra, &#x111;&#xF3;ng g&#xF3;i logic giao di&#x1EC7;n v&#xE0; style ri&#xEA;ng. Ch&#xFA;ng gi&#xFA;p b&#x1EA1;n:</p>
<ul>
<li><strong>T&#xE1;i s&#x1EED; d&#x1EE5;ng code:</strong> S&#x1EED; d&#x1EE5;ng l&#x1EA1;i component nhi&#x1EC1;u l&#x1EA7;n trong &#x1EE9;ng d&#x1EE5;ng m&#xE0; kh&#xF4;ng c&#x1EA7;n vi&#x1EBF;t l&#x1EA1;i code style.</li>
<li><strong>&#x110;&#x1EA3;m b&#x1EA3;o t&#xED;nh nh&#x1EA5;t qu&#xE1;n:</strong>  Duy tr&#xEC; style UI nh&#x1EA5;t qu&#xE1;n tr&#xEA;n to&#xE0;n b&#x1ED9; &#x1EE9;ng d&#x1EE5;ng.</li>
<li><strong>D&#x1EC5; d&#xE0;ng b&#x1EA3;o tr&#xEC;:</strong>  Thay &#x111;&#x1ED5;i style c&#x1EE7;a component ch&#x1EC9; c&#x1EA7;n s&#x1EED;a &#x1EDF; m&#x1ED9;t v&#x1ECB; tr&#xED; duy nh&#x1EA5;t.</li>
<li><strong>Code s&#x1EA1;ch &#x111;&#x1EB9;p v&#xE0; d&#x1EC5; &#x111;&#x1ECD;c:</strong>  Code View cha tr&#x1EDF; n&#xEA;n g&#x1ECD;n g&#xE0;ng, d&#x1EC5; hi&#x1EC3;u h&#x1A1;n, tr&#xE1;nh &#x111;&#x1B0;&#x1EE3;c &quot;dot panic&quot;.</li>
</ul>
<h3 id="v%C3%AD-d%E1%BB%A5-v%E1%BB%81-custom-components">V&#xED; d&#x1EE5; v&#x1EC1; Custom Components:</h3>
<ul>
<li>
<p><strong><code>TitleLabelView</code> (Custom Label):</strong></p>
<pre><code class="language-swift">struct TitleLabelView: View {
    var text: String

    var body: some View {
        Text(text)
            .font(.title2)
            .fontWeight(.bold)
            .foregroundColor(.primary)
            .padding(.bottom, 5)
    }
}

// S&#x1EED; d&#x1EE5;ng:
TitleLabelView(text: &quot;Ti&#xEA;u &#x111;&#x1EC1; Trang&quot;)
</code></pre>
</li>
<li>
<p><strong><code>PrimaryButton</code> (Custom Button):</strong></p>
<pre><code class="language-swift">struct PrimaryButton: View {
    var title: String
    var action: () -&gt; Void

    var body: some View {
        Button(action: action) {
            Text(title)
                .font(.headline)
                .foregroundColor(.white)
                .padding(.horizontal, 30)
                .padding(.vertical, 12)
                .background(Color.blue)
                .cornerRadius(8)
        }
    }
}

// S&#x1EED; d&#x1EE5;ng:
PrimaryButton(title: &quot;X&#xE1;c Nh&#x1EAD;n&quot;, action: { /* H&#xE0;nh &#x111;&#x1ED9;ng khi nh&#x1EA5;n n&#xFA;t */ })
</code></pre>
</li>
<li>
<p><strong><code>RoundedImageView</code> (Custom Image View):</strong></p>
<pre><code class="language-swift">struct RoundedImageView: View {
    var imageName: String

    var body: some View {
        Image(imageName)
            .resizable()
            .scaledToFit()
            .frame(width: 60, height: 60)
            .clipShape(Circle())
            .overlay(Circle().stroke(Color.gray, lineWidth: 1))
    }
}

// S&#x1EED; d&#x1EE5;ng:
RoundedImageView(imageName: &quot;avatar_default&quot;)
</code></pre>
</li>
</ul>
<h2 id="4-th%E1%BB%AD-th%C3%A1ch-th%E1%BB%B1c-h%C3%A0nh-x%C3%A2y-d%E1%BB%B1ng-giao-di%E1%BB%87n-v%E1%BB%9Bi-custom-components">4. Th&#x1EED; Th&#xE1;ch Th&#x1EF1;c H&#xE0;nh: X&#xE2;y D&#x1EF1;ng Giao Di&#x1EC7;n V&#x1EDB;i Custom Components!</h2>
<p>&#x110;&#x1EC3; th&#x1EF1;c s&#x1EF1; l&#xE0;m ch&#x1EE7; ki&#x1EBF;n th&#x1EE9;c v&#x1EEB;a h&#x1ECD;c, h&#xE3;y c&#xF9;ng th&#x1EED; s&#x1EE9;c v&#x1EDB;i c&#xE1;c th&#x1EED; th&#xE1;ch thi&#x1EBF;t k&#x1EBF; giao di&#x1EC7;n sau, t&#x1EAD;p trung v&#xE0;o vi&#x1EC7;c s&#x1EED; d&#x1EE5;ng Custom Components:</p>
<p><strong>Th&#x1EED; th&#xE1;ch 1: M&#xE0;n h&#xEC;nh &#x110;&#x103;ng nh&#x1EAD;p (Login Screen)</strong></p>
<ul>
<li><strong>M&#xF4; t&#x1EA3;:</strong> T&#x1EA1;o m&#xE0;n h&#xEC;nh &#x111;&#x103;ng nh&#x1EAD;p c&#x1A1; b&#x1EA3;n v&#x1EDB;i ti&#xEA;u &#x111;&#x1EC1;, &#xF4; nh&#x1EAD;p email/t&#xEA;n &#x111;&#x103;ng nh&#x1EAD;p, &#xF4; nh&#x1EAD;p m&#x1EAD;t kh&#x1EA9;u, n&#xFA;t &quot;&#x110;&#x103;ng nh&#x1EAD;p&quot; v&#xE0; link &quot;Qu&#xEA;n m&#x1EAD;t kh&#x1EA9;u?&quot;.</li>
<li><strong>Y&#xEA;u c&#x1EA7;u Custom Components:</strong>
<ul>
<li><code>CustomTextField</code>: &#xD4; nh&#x1EAD;p li&#x1EC7;u (Email/T&#xEA;n &#x111;&#x103;ng nh&#x1EAD;p, M&#x1EAD;t kh&#x1EA9;u).</li>
<li><code>PrimaryButton</code>: N&#xFA;t &quot;&#x110;&#x103;ng nh&#x1EAD;p&quot;.</li>
<li><strong>(T&#xF9;y ch&#x1ECD;n)</strong> <code>TitleLabelView</code>: Ti&#xEA;u &#x111;&#x1EC1; trang.</li>
</ul>
</li>
<li><strong>G&#x1EE3;i &#xFD;:</strong> S&#x1EED; d&#x1EE5;ng <code>VStack</code>, <code>TextField</code>, <code>SecureField</code>, <code>Button</code>, <code>Text</code>, <code>Spacer</code>, modifiers <code>.padding()</code>, <code>.frame()</code>, <code>.font()</code>, <code>.foregroundColor()</code>, <code>.background()</code>, <code>.cornerRadius()</code>, <code>.border()</code>, <code>.placeholder()</code>, <code>.keyboardType()</code>.</li>
<li><strong>M&#x1EE5;c ti&#xEA;u:</strong> Luy&#x1EC7;n t&#x1EAD;p layout d&#x1ECD;c, <code>TextField</code>, <code>SecureField</code>, <code>@State</code>, Binding, t&#xE1;i s&#x1EED; d&#x1EE5;ng <code>PrimaryButton</code>, t&#x1EA1;o m&#x1EDB;i <code>CustomTextField</code>.</li>
</ul>
<p><strong>Th&#x1EED; th&#xE1;ch 2: Th&#x1EBB; S&#x1EA3;n ph&#x1EA9;m (Product Card)</strong></p>
<ul>
<li><strong>M&#xF4; t&#x1EA3;:</strong> Thi&#x1EBF;t k&#x1EBF; th&#x1EBB; s&#x1EA3;n ph&#x1EA9;m hi&#x1EC3;n th&#x1ECB; &#x1EA3;nh, t&#xEA;n, gi&#xE1; (g&#x1ED1;c v&#xE0; khuy&#x1EBF;n m&#xE3;i), n&#xFA;t &quot;Th&#xEA;m v&#xE0;o gi&#x1ECF; h&#xE0;ng&quot;.</li>
<li><strong>Y&#xEA;u c&#x1EA7;u Custom Components:</strong>
<ul>
<li><code>ProductImageView</code>: Hi&#x1EC3;n th&#x1ECB; &#x1EA3;nh s&#x1EA3;n ph&#x1EA9;m.</li>
<li><code>PriceLabelView</code>: Hi&#x1EC3;n th&#x1ECB; gi&#xE1; s&#x1EA3;n ph&#x1EA9;m (gi&#xE1; g&#x1ED1;c v&#xE0; khuy&#x1EBF;n m&#xE3;i).</li>
<li><code>SecondaryButton</code>: N&#xFA;t &quot;Th&#xEA;m v&#xE0;o gi&#x1ECF; h&#xE0;ng&quot; (style kh&#xE1;c <code>PrimaryButton</code>).</li>
</ul>
</li>
<li><strong>G&#x1EE3;i &#xFD;:</strong> S&#x1EED; d&#x1EE5;ng <code>HStack</code>, <code>VStack</code>, <code>Image</code>, <code>Text</code>, <code>Button</code>, <code>Spacer</code>, modifiers <code>.padding()</code>, <code>.frame()</code>, <code>.font()</code>, <code>.foregroundColor()</code>, <code>.background()</code>, <code>.cornerRadius()</code>, <code>.overlay()</code>, <code>.border()</code>, <code>.aspectRatio()</code>, <code>.resizable()</code>, <code>.scaledToFit()</code>.</li>
<li><strong>M&#x1EE5;c ti&#xEA;u:</strong> Luy&#x1EC7;n t&#x1EAD;p layout ph&#x1EE9;c t&#x1EA1;p h&#x1A1;n (k&#x1EBF;t h&#x1EE3;p <code>HStack</code>, <code>VStack</code>), <code>Image</code>, t&#x1EA1;o <code>PriceLabelView</code>, ph&#xE2;n bi&#x1EC7;t <code>SecondaryButton</code>.</li>
</ul>
<p><strong>Th&#x1EED; th&#xE1;ch 3: Trang C&#xE0;i &#x111;&#x1EB7;t (Settings Screen - &#x110;&#x1A1;n gi&#x1EA3;n)</strong></p>
<ul>
<li><strong>M&#xF4; t&#x1EA3;:</strong> Trang c&#xE0;i &#x111;&#x1EB7;t &#x111;&#x1A1;n gi&#x1EA3;n v&#x1EDB;i section &quot;Chung&quot; (Toggle Ch&#x1EBF; &#x111;&#x1ED9; t&#x1ED1;i, Th&#xF4;ng b&#xE1;o) v&#xE0; &quot;T&#xE0;i kho&#x1EA3;n&quot; (&#x1EA2;nh &#x111;&#x1EA1;i di&#x1EC7;n, T&#xEA;n ng&#x1B0;&#x1EDD;i d&#xF9;ng, &#x110;&#x103;ng xu&#x1EA5;t).</li>
<li><strong>Y&#xEA;u c&#x1EA7;u Custom Components:</strong>
<ul>
<li><code>SectionHeaderView</code>: Ti&#xEA;u &#x111;&#x1EC1; section (&quot;Chung&quot;, &quot;T&#xE0;i kho&#x1EA3;n&quot;).</li>
<li><code>SettingsRowView</code>: H&#xE0;ng c&#xE0;i &#x111;&#x1EB7;t (ch&#x1EE9;a ti&#xEA;u &#x111;&#x1EC1; v&#xE0; Toggle/Image/Text).</li>
<li><code>RoundedImageView</code>: &#x1EA2;nh &#x111;&#x1EA1;i di&#x1EC7;n.</li>
</ul>
</li>
<li><strong>G&#x1EE3;i &#xFD;:</strong> S&#x1EED; d&#x1EE5;ng <code>NavigationView</code>, <code>Form</code> (ho&#x1EB7;c <code>VStack</code> l&#x1EDB;n), <code>Section</code>, <code>Toggle</code>, <code>Image</code>, <code>Text</code>, <code>Button</code>, <code>Spacer</code>, modifiers <code>.padding()</code>, <code>.frame()</code>, <code>.font()</code>, <code>.foregroundColor()</code>, <code>.background()</code>, <code>.cornerRadius()</code>, <code>.clipShape()</code>, <code>.overlay()</code>, <code>.listRowSeparator(.hidden)</code>.</li>
<li><strong>M&#x1EE5;c ti&#xEA;u:</strong> Luy&#x1EC7;n t&#x1EAD;p <code>NavigationView</code>, <code>Form</code>/<code>List</code>, <code>Toggle</code>, t&#x1EA1;o <code>SectionHeaderView</code>, <code>SettingsRowView</code>, linh ho&#x1EA1;t s&#x1EED; d&#x1EE5;ng <code>SettingsRowView</code>.</li>
</ul>
<h2 id="l%E1%BB%9Di-k%E1%BA%BFt">L&#x1EDD;i K&#x1EBF;t:</h2>
<p>Ch&#xFA;c m&#x1EEB;ng b&#x1EA1;n &#x111;&#xE3; ti&#x1EBF;n th&#xEA;m m&#x1ED9;t b&#x1B0;&#x1EDB;c quan tr&#x1ECD;ng tr&#xEA;n h&#xE0;nh tr&#xEC;nh chinh ph&#x1EE5;c SwiftUI! V&#x1EDB;i ki&#x1EBF;n th&#x1EE9;c v&#x1EC1; Components, Modifiers v&#xE0; Custom Components, b&#x1EA1;n &#x111;&#xE3; c&#xF3; trong tay nh&#x1EEF;ng c&#xF4;ng c&#x1EE5; m&#x1EA1;nh m&#x1EBD; &#x111;&#x1EC3; x&#xE2;y d&#x1EF1;ng giao di&#x1EC7;n &#x1EE9;ng d&#x1EE5;ng iOS chuy&#xEA;n nghi&#x1EC7;p v&#xE0; &#x1EA5;n t&#x1B0;&#x1EE3;ng h&#x1A1;n.</p>
<p>H&#xE3;y b&#x1EAF;t tay v&#xE0;o th&#x1EF1;c h&#xE0;nh c&#xE1;c th&#x1EED; th&#xE1;ch, kh&#xE1;m ph&#xE1; th&#xEA;m c&#xE1;c components v&#xE0; modifiers kh&#xE1;c, v&#xE0; &#x111;&#x1EEB;ng ng&#x1EA7;n ng&#x1EA1;i chia s&#x1EBB; nh&#x1EEF;ng s&#xE1;ng t&#x1EA1;o c&#x1EE7;a b&#x1EA1;n v&#x1EDB;i c&#x1ED9;ng &#x111;&#x1ED3;ng SwiftUI!  H&#x1EB9;n g&#x1EB7;p l&#x1EA1;i b&#x1EA1;n trong nh&#x1EEF;ng b&#xE0;i vi&#x1EBF;t ti&#x1EBF;p theo!</p>
<p><strong>Th&#x1EED; Th&#xE1;ch D&#xE0;nh Cho B&#x1EA1;n:</strong></p>
<p>B&#x1EA1;n &#x111;&#xE3; s&#x1EB5;n s&#xE0;ng &quot;n&#xE2;ng c&#x1EA5;p&quot; SwiftUI c&#x1EE7;a m&#xEC;nh ch&#x1B0;a? H&#xE3;y ch&#x1ECD;n m&#x1ED9;t (ho&#x1EB7;c c&#x1EA3; ba!) th&#x1EED; th&#xE1;ch thi&#x1EBF;t k&#x1EBF; giao di&#x1EC7;n tr&#xEA;n v&#xE0; b&#x1EAF;t &#x111;&#x1EA7;u th&#x1EF1;c h&#xE0;nh ngay! &#x110;&#x1EEB;ng qu&#xEA;n chia s&#x1EBB; th&#xE0;nh qu&#x1EA3; c&#x1EE7;a b&#x1EA1;n &#x1EDF; ph&#x1EA7;n b&#xEC;nh lu&#x1EAD;n b&#xEA;n d&#x1B0;&#x1EDB;i nh&#xE9;! M&#xEC;nh r&#x1EA5;t mong ch&#x1EDD; &#x111;&#x1B0;&#x1EE3;c chi&#xEA;m ng&#x1B0;&#x1EE1;ng nh&#x1EEF;ng giao di&#x1EC7;n SwiftUI tuy&#x1EC7;t v&#x1EDD;i do ch&#xED;nh b&#x1EA1;n t&#x1EA1;o ra!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Chào SwiftUI! Hành trình chuyển đổi từ UIKit và khám phá tương lai lập trình giao diện iOS]]></title><description><![CDATA[SwiftUI không phải là kẻ thay thế UIKit hoàn toàn, mà là một hướng đi mới mà Apple đang tập trung phát triển cho tương lai của lập trình giao diện trên tất cả các nền tảng của họ.]]></description><link>https://makexyz.fun/from-uikit-to-swift-ui/</link><guid isPermaLink="false">67cce9734089534a1891f955</guid><category><![CDATA[SwiftUI]]></category><category><![CDATA[UIKit]]></category><dc:creator><![CDATA[Tony Phạm]]></dc:creator><pubDate>Sun, 09 Mar 2025 02:02:50 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p><img src="https://miro.medium.com/v2/resize:fit:1400/1*5Cu2bq4zfNoE72BokNPnew.jpeg" alt="UIKit vs SwiftUI" title="UIKit vs SwiftUI" loading="lazy"></p>
<p>Xin ch&#xE0;o c&#xE1;c b&#x1EA1;n! Ch&#xFA;ng ta &#x111;&#xE3; c&#xF9;ng nhau chinh ph&#x1EE5;c th&#x1EBF; gi&#x1EDB;i l&#x1EAD;p tr&#xEC;nh &#x1EE9;ng d&#x1EE5;ng iOS v&#x1EDB;i UIKit, Xcode v&#xE0; Swift. C&#xE1;c b&#x1EA1;n &#x111;&#xE3; t&#x1EA1;o ra nh&#x1EEF;ng &#x1EE9;ng d&#x1EE5;ng c&#xF3; giao di&#x1EC7;n, &#x111;i&#x1EC1;u h&#x1B0;&#x1EDB;ng gi&#x1EEF;a c&#xE1;c m&#xE0;n h&#xEC;nh, v&#xE0; th&#x1EAD;m ch&#xED; l&#xE0;m ch&#x1EE7; &#x111;&#x1B0;&#x1EE3;c b&#x1EA3;ng bi&#x1EC3;u UITableView &#x111;&#x1EA7;y ph&#x1EE9;c t&#x1EA1;p.  H&#xE3;y t&#x1EF1; h&#xE0;o v&#x1EC1; nh&#x1EEF;ng g&#xEC; m&#xEC;nh &#x111;&#xE3; &#x111;&#x1EA1;t &#x111;&#x1B0;&#x1EE3;c nh&#xE9;! &#x110;&#xF3; l&#xE0; m&#x1ED9;t n&#x1EC1;n t&#x1EA3;ng v&#x1EEF;ng ch&#x1EAF;c, m&#x1ED9;t h&#xE0;nh trang qu&#xFD; gi&#xE1; &#x111;&#x1EC3; ch&#xFA;ng ta b&#x1B0;&#x1EDB;c ti&#x1EBF;p v&#xE0;o m&#x1ED9;t ch&#x1B0;&#x1A1;ng m&#x1EDB;i, m&#x1ED9;t th&#x1EBF; gi&#x1EDB;i m&#x1EDB;i &#x111;&#x1EA7;y th&#xFA; v&#x1ECB; v&#xE0; ti&#x1EC1;m n&#x103;ng: <strong>SwiftUI</strong>.</p>
<h2 id="1-l%E1%BB%9Di-ch%C3%A0o-t%E1%BB%AB-ng%C6%B0%E1%BB%9Di-quen-uikit">1. L&#x1EDD;i ch&#xE0;o t&#x1EEB; &quot;ng&#x1B0;&#x1EDD;i quen&quot; UIKit:</h2>
<p>Ch&#xFA;ng ta &#x111;&#xE3; &quot;quen m&#x1EB7;t&quot; v&#x1EDB;i UIKit, ng&#x1B0;&#x1EDD;i b&#x1EA1;n &#x111;&#x1ED3;ng h&#xE0;nh tin c&#x1EAD;y trong su&#x1ED1;t th&#x1EDD;i gian qua. UIKit &#x111;&#xE3; gi&#xFA;p ch&#xFA;ng ta hi&#x1EC7;n th&#x1EF1;c h&#xF3;a v&#xF4; s&#x1ED1; &#xFD; t&#x1B0;&#x1EDF;ng, t&#x1EEB; nh&#x1EEF;ng &#x1EE9;ng d&#x1EE5;ng &#x111;&#x1A1;n gi&#x1EA3;n &#x111;&#x1EBF;n ph&#x1EE9;c t&#x1EA1;p. Ch&#xFA;ng ta &#x111;&#xE3; h&#x1ECD;c c&#xE1;ch &quot;ra l&#x1EC7;nh&quot; cho t&#x1EEB;ng th&#xE0;nh ph&#x1EA7;n giao di&#x1EC7;n: t&#x1EA1;o n&#xFA;t, &#x111;&#x1EB7;t v&#x1ECB; tr&#xED;, thay &#x111;&#x1ED5;i m&#xE0;u s&#x1EAF;c, hi&#x1EC3;n th&#x1ECB; d&#x1EEF; li&#x1EC7;u...  Ch&#xFA;ng ta &#x111;&#xE3; l&#xE0;m ch&#x1EE7; &#x111;&#x1B0;&#x1EE3;c Storyboard, IBOutlet, IBAction, Delegate, v&#xE0; v&#xF4; v&#xE0;n kh&#xE1;i ni&#x1EC7;m kh&#xE1;c.</p>
<p><img src="https://www.createwithswift.com/content/images/2022/02/createwithswift.com-using-a-swiftui-view-into-a-uikit-app-001.png" alt="UIKit Storyboard" loading="lazy"></p>
<p>Nh&#x1B0;ng, gi&#x1ED1;ng nh&#x1B0; m&#x1ECD;i th&#x1EE9; tr&#xEA;n &#x111;&#x1EDD;i, c&#xF4;ng ngh&#x1EC7; c&#x169;ng kh&#xF4;ng ng&#x1EEB;ng ti&#x1EBF;n h&#xF3;a. V&#xE0; &#x111;&#x1EC3; b&#x1EAF;t k&#x1ECB;p xu h&#x1B0;&#x1EDB;ng, &#x111;&#x1EC3; t&#x1EA1;o ra nh&#x1EEF;ng &#x1EE9;ng d&#x1EE5;ng iOS hi&#x1EC7;n &#x111;&#x1EA1;i, &#x111;&#x1EB9;p m&#x1EAF;t v&#xE0; hi&#x1EC7;u qu&#x1EA3; h&#x1A1;n, ch&#xFA;ng ta c&#x1EA7;n ph&#x1EA3;i b&#x1B0;&#x1EDB;c l&#xEA;n m&#x1ED9;t &quot;con thuy&#x1EC1;n&quot; m&#x1EDB;i, m&#x1EA1;nh m&#x1EBD; h&#x1A1;n: <strong>SwiftUI</strong>.</p>
<h2 id="2-nh%C6%B0ng-th%E1%BA%BF-gi%E1%BB%9Bi-%C4%91ang-thay-%C4%91%E1%BB%95it%E1%BA%A1i-sao-c%E1%BA%A7n-swiftui">2. &quot;Nh&#x1B0;ng th&#x1EBF; gi&#x1EDB;i &#x111;ang thay &#x111;&#x1ED5;i...&quot; - T&#x1EA1;i sao c&#x1EA7;n SwiftUI?</h2>
<p><img src="https://www.macworld.com/wp-content/uploads/2023/12/apple-ecosystem.jpg?quality=50&amp;strip=all" alt="Furure of iOS EcoSystem" loading="lazy"></p>
<p>SwiftUI kh&#xF4;ng ph&#x1EA3;i l&#xE0; &quot;k&#x1EBB; thay th&#x1EBF;&quot; UIKit ho&#xE0;n to&#xE0;n, m&#xE0; l&#xE0; m&#x1ED9;t <strong>b&#x1B0;&#x1EDB;c ti&#x1EBF;n l&#x1EDB;n</strong>, m&#x1ED9;t <strong>h&#x1B0;&#x1EDB;ng &#x111;i m&#x1EDB;i</strong> m&#xE0; Apple &#x111;ang t&#x1EAD;p trung ph&#xE1;t tri&#x1EC3;n cho t&#x1B0;&#x1A1;ng lai c&#x1EE7;a l&#x1EAD;p tr&#xEC;nh giao di&#x1EC7;n tr&#xEA;n t&#x1EA5;t c&#x1EA3; c&#xE1;c n&#x1EC1;n t&#x1EA3;ng c&#x1EE7;a h&#x1ECD; (iOS, macOS, watchOS, tvOS, visionOS, v&#xE0; c&#x1EA3; visionOS m&#x1EDB;i ra m&#x1EAF;t!).  V&#x1EAD;y, &#x111;i&#x1EC1;u g&#xEC; khi&#x1EBF;n SwiftUI tr&#x1EDF; n&#xEA;n c&#x1EA7;n thi&#x1EBF;t v&#xE0; h&#x1EA5;p d&#x1EAB;n &#x111;&#x1EBF;n v&#x1EAD;y?</p>
<h3 id="l%C3%BD-do-1-s%E1%BB%B1-%C4%91%C6%A1n-gi%E1%BA%A3n-v%C3%A0-hi%E1%BB%87n-%C4%91%E1%BA%A1iless-code-more-done">L&#xFD; do #1: S&#x1EF1; &#x111;&#x1A1;n gi&#x1EA3;n v&#xE0; hi&#x1EC7;n &#x111;&#x1EA1;i - &quot;Less code, more done&quot;</h3>
<p>M&#x1ED9;t trong nh&#x1EEF;ng &#x111;i&#x1EC1;u &#x111;&#x1EA7;u ti&#xEA;n b&#x1EA1;n s&#x1EBD; nh&#x1EAD;n th&#x1EA5;y &#x1EDF; SwiftUI l&#xE0; <strong>code ng&#x1EAF;n g&#x1ECD;n h&#x1A1;n r&#x1EA5;t nhi&#x1EC1;u</strong> so v&#x1EDB;i UIKit. &#x110;&#x1EC3; l&#xE0;m c&#xF9;ng m&#x1ED9;t vi&#x1EC7;c, b&#x1EA1;n c&#xF3; th&#x1EC3; vi&#x1EBF;t &#xED;t code h&#x1A1;n, d&#x1EC5; &#x111;&#x1ECD;c h&#x1A1;n, v&#xE0; d&#x1EC5; hi&#x1EC3;u h&#x1A1;n.</p>
<ul>
<li>
<p><strong>V&#xED; d&#x1EE5;:</strong> &#x110;&#x1EC3; hi&#x1EC3;n th&#x1ECB; m&#x1ED9;t d&#xF2;ng ch&#x1EEF; &quot;Xin ch&#xE0;o!&quot; tr&#xEA;n m&#xE0;n h&#xEC;nh:</p>
<ul>
<li><strong>UIKit (Imperative):</strong></li>
</ul>
<pre><code class="language-swift">let label = UILabel()
label.text = &quot;Xin ch&#xE0;o!&quot;
label.frame = CGRect(x: 100, y: 100, width: 200, height: 30) // Ph&#x1EA3;i t&#x1EF1; t&#xED;nh to&#xE1;n v&#x1ECB; tr&#xED;, k&#xED;ch th&#x1B0;&#x1EDB;c
view.addSubview(label)
</code></pre>
<ul>
<li><strong>SwiftUI (Declarative):</strong></li>
</ul>
<pre><code class="language-swift">Text(&quot;Xin ch&#xE0;o!&quot;)
</code></pre>
<p>B&#x1EA1;n th&#x1EA5;y s&#x1EF1; kh&#xE1;c bi&#x1EC7;t ch&#x1EE9;?  SwiftUI t&#x1EAD;p trung v&#xE0;o vi&#x1EC7;c <strong>m&#xF4; t&#x1EA3; giao di&#x1EC7;n b&#x1EA1;n mu&#x1ED1;n</strong>, thay v&#xEC; &quot;ra l&#x1EC7;nh&quot; t&#x1EEB;ng b&#x1B0;&#x1EDB;c nh&#x1B0; UIKit.  Code ng&#x1EAF;n g&#x1ECD;n h&#x1A1;n &#x111;&#x1ED3;ng ngh&#x129;a v&#x1EDB;i vi&#x1EC7;c <strong>&#xED;t l&#x1ED7;i h&#x1A1;n, ph&#xE1;t tri&#x1EC3;n nhanh h&#x1A1;n, v&#xE0; b&#x1EA3;o tr&#xEC; d&#x1EC5; d&#xE0;ng h&#x1A1;n</strong>.</p>
</li>
</ul>
<!--kg-card-end: markdown--><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/qk2y-TiLDZo?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen title="SwiftUI vs UIKit &#x2013; Comparison of building the same app in each framework"></iframe></figure><!--kg-card-begin: markdown--><h3 id="l%C3%BD-do-2-preview-tr%E1%BB%B1c-quanth%E1%BA%A5y-l%C3%A0-tin-ngay">L&#xFD; do #2: Preview tr&#x1EF1;c quan - &quot;Th&#x1EA5;y l&#xE0; tin ngay!&quot;**</h3>
<p><img src="https://www.swiftyplace.com/wp-content/uploads/2023/09/xcode-selectable-preview-1024x705.webp" alt="Canvas Preview - SwiftUI" loading="lazy"></p>
<p>Canvas Preview c&#x1EE7;a SwiftUI th&#x1EF1;c s&#x1EF1; l&#xE0; m&#x1ED9;t &quot;ph&#xE9;p m&#xE0;u&quot;!  Khi b&#x1EA1;n vi&#x1EBF;t code SwiftUI, b&#x1EA1;n s&#x1EBD; th&#x1EA5;y <strong>giao di&#x1EC7;n &#x1EE9;ng d&#x1EE5;ng c&#x1EE7;a b&#x1EA1;n hi&#x1EC3;n th&#x1ECB; ngay l&#x1EAD;p t&#x1EE9;c</strong> &#x1EDF; b&#xEA;n c&#x1EA1;nh, <strong>thay &#x111;&#x1ED5;i theo th&#x1EDD;i gian th&#x1EF1;c</strong> khi b&#x1EA1;n ch&#x1EC9;nh s&#x1EED;a code.</p>
<ul>
<li><strong>Kh&#xF4;ng c&#x1EA7;n build-run li&#xEA;n t&#x1EE5;c:</strong>  B&#x1EA1;n kh&#xF4;ng c&#x1EA7;n ph&#x1EA3;i ch&#x1EDD; &#x111;&#x1EE3;i qu&#xE1; tr&#xEC;nh build v&#xE0; ch&#x1EA1;y simulator/thi&#x1EBF;t b&#x1ECB; m&#x1ED7;i khi mu&#x1ED1;n xem thay &#x111;&#x1ED5;i nh&#x1ECF; tr&#xEA;n giao di&#x1EC7;n.</li>
<li><strong>Th&#x1EED; nghi&#x1EC7;m nhanh ch&#xF3;ng:</strong>  D&#x1EC5; d&#xE0;ng th&#x1EED; nghi&#x1EC7;m c&#xE1;c &#xFD; t&#x1B0;&#x1EDF;ng thi&#x1EBF;t k&#x1EBF;, thay &#x111;&#x1ED5;i m&#xE0;u s&#x1EAF;c, font ch&#x1EEF;, b&#x1ED1; c&#x1EE5;c... v&#xE0; th&#x1EA5;y k&#x1EBF;t qu&#x1EA3; t&#x1EE9;c th&#xEC;.</li>
<li><strong>Thi&#x1EBF;t k&#x1EBF; v&#xE0; code song h&#xE0;nh:</strong>  Qu&#xE1; tr&#xEC;nh thi&#x1EBF;t k&#x1EBF; giao di&#x1EC7;n v&#xE0; vi&#x1EBF;t code tr&#x1EDF; n&#xEA;n li&#x1EC1;n m&#x1EA1;ch v&#xE0; tr&#x1EF1;c quan h&#x1A1;n bao gi&#x1EDD; h&#x1EBF;t.</li>
</ul>
<p>Preview gi&#xFA;p <strong>t&#x103;ng t&#x1ED1;c &#x111;&#x1ED9; ph&#xE1;t tri&#x1EC3;n &#x1EE9;ng d&#x1EE5;ng</strong> &#x111;&#xE1;ng k&#x1EC3; v&#xE0; mang l&#x1EA1;i tr&#x1EA3;i nghi&#x1EC7;m l&#x1EAD;p tr&#xEC;nh <strong>th&#xFA; v&#x1ECB; v&#xE0; tr&#x1EF1;c quan</strong> h&#x1A1;n r&#x1EA5;t nhi&#x1EC1;u.</p>
<h3 id="l%C3%BD-do-3-t%C6%B0%C6%A1ng-lai-c%E1%BB%A7a-apple-v%C3%A0-h%E1%BB%87-sinh-th%C3%A1ivi%E1%BA%BFt-m%E1%BB%99t-l%E1%BA%A7n-ch%E1%BA%A1y-m%E1%BB%8Di-n%C6%A1i-apple">L&#xFD; do #3: T&#x1B0;&#x1A1;ng lai c&#x1EE7;a Apple v&#xE0; h&#x1EC7; sinh th&#xE1;i - &quot;Vi&#x1EBF;t m&#x1ED9;t l&#x1EA7;n, ch&#x1EA1;y m&#x1ECD;i n&#x1A1;i (Apple)&quot;</h3>
<p><img src="https://i0.wp.com/appleworld.today/wp-content/uploads/2025/01/Apple-Product-Lineup.jpg?fit=1200%2C355&amp;quality=89&amp;ssl=1" alt="iOS Ecosytem" loading="lazy"></p>
<p>Apple &#x111;ang &#x111;&#x1EB7;t c&#x1B0;&#x1EE3;c l&#x1EDB;n v&#xE0;o SwiftUI.  H&#x1ECD; li&#xEA;n t&#x1EE5;c c&#x1EA3;i ti&#x1EBF;n v&#xE0; b&#x1ED5; sung t&#xED;nh n&#x103;ng m&#x1EDB;i cho SwiftUI qua m&#x1ED7;i phi&#xEA;n b&#x1EA3;n h&#x1EC7; &#x111;i&#x1EC1;u h&#xE0;nh.  SwiftUI kh&#xF4;ng ch&#x1EC9; d&#xE0;nh cho iOS, m&#xE0; c&#xF2;n <strong>ho&#x1EA1;t &#x111;&#x1ED9;ng tr&#xEA;n t&#x1EA5;t c&#x1EA3; c&#xE1;c n&#x1EC1;n t&#x1EA3;ng Apple</strong>: macOS, watchOS, tvOS, v&#xE0; c&#x1EA3; n&#x1EC1;n t&#x1EA3;ng th&#x1EF1;c t&#x1EBF; &#x1EA3;o m&#x1EDB;i visionOS.</p>
<p>&#x110;i&#x1EC1;u n&#xE0;y c&#xF3; ngh&#x129;a l&#xE0;, v&#x1EDB;i SwiftUI, b&#x1EA1;n c&#xF3; th&#x1EC3; <strong>chia s&#x1EBB; ph&#x1EA7;n l&#x1EDB;n code giao di&#x1EC7;n</strong> gi&#x1EEF;a c&#xE1;c &#x1EE9;ng d&#x1EE5;ng tr&#xEA;n c&#xE1;c n&#x1EC1;n t&#x1EA3;ng kh&#xE1;c nhau c&#x1EE7;a Apple.  &quot;Vi&#x1EBF;t m&#x1ED9;t l&#x1EA7;n, ch&#x1EA1;y m&#x1ECD;i n&#x1A1;i&quot; trong h&#x1EC7; sinh th&#xE1;i Apple kh&#xF4;ng c&#xF2;n l&#xE0; gi&#x1EA5;c m&#x1A1; n&#x1EEF;a!</p>
<h3 id="l%C3%BD-do-4-bonus-vui-h%C6%A1n-th%C3%BA-v%E1%BB%8B-h%C6%A1ntr%E1%BA%A3i-nghi%E1%BB%87m-l%E1%BA%ADp-tr%C3%ACnh-m%E1%BB%9Bi-m%E1%BA%BB">L&#xFD; do #4 (Bonus): &quot;Vui h&#x1A1;n, th&#xFA; v&#x1ECB; h&#x1A1;n!&quot; - Tr&#x1EA3;i nghi&#x1EC7;m l&#x1EAD;p tr&#xEC;nh m&#x1EDB;i m&#x1EBB;</h3>
<p><strong>(H&#xEC;nh &#x1EA3;nh minh h&#x1ECD;a: H&#xEC;nh &#x1EA3;nh l&#x1EAD;p tr&#xEC;nh vi&#xEA;n &#x111;ang vui v&#x1EBB;, s&#xE1;ng t&#x1EA1;o v&#x1EDB;i SwiftUI)</strong></p>
<p>SwiftUI mang &#x111;&#x1EBF;n m&#x1ED9;t <strong>lu&#x1ED3;ng gi&#xF3; m&#x1EDB;i</strong> cho l&#x1EAD;p tr&#xEC;nh giao di&#x1EC7;n.  V&#x1EDB;i c&#xFA; ph&#xE1;p Swift hi&#x1EC7;n &#x111;&#x1EA1;i, c&#xE1;ch ti&#x1EBF;p c&#x1EAD;n declarative, v&#xE0; preview tr&#x1EF1;c quan, vi&#x1EC7;c x&#xE2;y d&#x1EF1;ng giao di&#x1EC7;n &#x1EE9;ng d&#x1EE5;ng tr&#x1EDF; n&#xEA;n <strong>th&#xFA; v&#x1ECB; v&#xE0; s&#xE1;ng t&#x1EA1;o</strong> h&#x1A1;n r&#x1EA5;t nhi&#x1EC1;u.</p>
<p>C&#x1ED9;ng &#x111;&#x1ED3;ng SwiftUI c&#x169;ng &#x111;ang ph&#xE1;t tri&#x1EC3;n m&#x1EA1;nh m&#x1EBD;, v&#x1EDB;i r&#x1EA5;t nhi&#x1EC1;u t&#xE0;i li&#x1EC7;u, th&#x1B0; vi&#x1EC7;n h&#x1ED7; tr&#x1EE3;, v&#xE0; nh&#x1EEF;ng ng&#x1B0;&#x1EDD;i s&#x1EB5;n s&#xE0;ng gi&#xFA;p &#x111;&#x1EE1; l&#x1EAB;n nhau.  H&#x1ECD;c SwiftUI kh&#xF4;ng ch&#x1EC9; l&#xE0; h&#x1ECD;c m&#x1ED9;t c&#xF4;ng ngh&#x1EC7; m&#x1EDB;i, m&#xE0; c&#xF2;n l&#xE0; <strong>tham gia v&#xE0;o m&#x1ED9;t c&#x1ED9;ng &#x111;&#x1ED3;ng n&#x103;ng &#x111;&#x1ED9;ng v&#xE0; &#x111;&#x1EA7;y ti&#x1EC1;m n&#x103;ng</strong>.</p>
<h2 id="3-thay-%C4%91%E1%BB%95i-%C4%91%E1%BB%83-t%E1%BB%91t-h%C6%A1nso-s%C3%A1nh-uikit-v%C3%A0-swiftui-v%E1%BB%81-c%E1%BB%91t-l%C3%B5i">3. &quot;Thay &#x111;&#x1ED5;i &#x111;&#x1EC3; t&#x1ED1;t h&#x1A1;n&quot; - So s&#xE1;nh UIKit v&#xE0; SwiftUI v&#x1EC1; c&#x1ED1;t l&#xF5;i:</h2>
<p><strong>B&#x1EA3;ng So S&#xE1;nh UIKit v&#xE0; SwiftUI</strong></p>
<table>
<thead>
<tr>
<th>T&#xED;nh n&#x103;ng</th>
<th>UIKit (Imperative)</th>
<th>SwiftUI (Declarative)</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>T&#x1B0; duy l&#x1EAD;p tr&#xEC;nh</strong></td>
<td>Imperative (Ra l&#x1EC7;nh t&#x1EEB;ng b&#x1B0;&#x1EDB;c)</td>
<td>Declarative (M&#xF4; t&#x1EA3; giao di&#x1EC7;n)</td>
</tr>
<tr>
<td><strong>X&#xE2;y d&#x1EF1;ng UI</strong></td>
<td>Storyboard, Xibs (K&#xE9;o th&#x1EA3;, giao di&#x1EC7;n &#x111;&#x1ED3; h&#x1ECD;a)</td>
<td>Code (Swift), Canvas Preview (Code &amp; tr&#x1EF1;c quan)</td>
</tr>
<tr>
<td><strong>B&#x1ED1; c&#x1EE5;c giao di&#x1EC7;n</strong></td>
<td>Constraints (R&#xE0;ng bu&#x1ED9;c ph&#x1EE9;c t&#x1EA1;p)</td>
<td>Stacks (VStack, HStack, ZStack), Modifiers (&#x110;&#x1A1;n gi&#x1EA3;n)</td>
</tr>
<tr>
<td><strong>T&#x1B0;&#x1A1;ng t&#xE1;c &amp; D&#x1EEF; li&#x1EC7;u</strong></td>
<td>Delegate, IBAction, Target-Action (Ph&#x1EE9;c t&#x1EA1;p h&#x1A1;n)</td>
<td><code>@State</code>, Binding (&#x110;&#x1A1;n gi&#x1EA3;n, t&#x1EF1; &#x111;&#x1ED9;ng c&#x1EAD;p nh&#x1EAD;t)</td>
</tr>
<tr>
<td><strong>&#x110;&#x1ED9; d&#xE0;i code</strong></td>
<td>Th&#x1B0;&#x1EDD;ng d&#xE0;i d&#xF2;ng h&#x1A1;n</td>
<td>Ng&#x1EAF;n g&#x1ECD;n h&#x1A1;n, s&#xFA;c t&#xED;ch h&#x1A1;n</td>
</tr>
<tr>
<td><strong>Preview</strong></td>
<td>Ch&#x1EA1;y tr&#xEA;n Simulator/Thi&#x1EBF;t b&#x1ECB; &#x111;&#x1EC3; xem giao di&#x1EC7;n</td>
<td>Canvas Preview tr&#x1EF1;c quan, th&#x1EDD;i gian th&#x1EF1;c</td>
</tr>
<tr>
<td><strong>&#x110;a n&#x1EC1;n t&#x1EA3;ng Apple</strong></td>
<td>H&#x1EA1;n ch&#x1EBF; (ch&#x1EE7; y&#x1EBF;u iOS, iPadOS)</td>
<td>M&#x1EA1;nh m&#x1EBD; (iOS, macOS, watchOS, tvOS, visionOS)</td>
</tr>
<tr>
<td><strong>&#x110;&#x1B0;&#x1EDD;ng cong h&#x1ECD;c t&#x1EAD;p</strong></td>
<td>Layout Constraints ban &#x111;&#x1EA7;u kh&#xF3;</td>
<td>T&#x1ED5;ng th&#x1EC3; d&#x1EC5; h&#x1ECD;c v&#xE0; ti&#x1EBF;p c&#x1EAD;n h&#x1A1;n</td>
</tr>
</tbody>
</table>
<p>Chuy&#x1EC3;n t&#x1EEB; UIKit sang SwiftUI kh&#xF4;ng c&#xF3; ngh&#x129;a l&#xE0; &quot;v&#x1EE9;t b&#x1ECF;&quot; t&#x1EA5;t c&#x1EA3; nh&#x1EEF;ng g&#xEC; b&#x1EA1;n &#x111;&#xE3; h&#x1ECD;c.  Ki&#x1EBF;n th&#x1EE9;c UIKit v&#x1EAB;n r&#x1EA5;t gi&#xE1; tr&#x1ECB;, gi&#xFA;p b&#x1EA1;n hi&#x1EC3;u s&#xE2;u h&#x1A1;n v&#x1EC1; c&#xE1;ch th&#x1EE9;c ho&#x1EA1;t &#x111;&#x1ED9;ng c&#x1EE7;a h&#x1EC7; th&#x1ED1;ng.  Tuy nhi&#xEA;n, SwiftUI mang &#x111;&#x1EBF;n nh&#x1EEF;ng <strong>thay &#x111;&#x1ED5;i c&#x1ED1;t l&#xF5;i</strong> trong c&#xE1;ch ch&#xFA;ng ta x&#xE2;y d&#x1EF1;ng giao di&#x1EC7;n v&#xE0; t&#x1B0;&#x1A1;ng t&#xE1;c v&#x1EDB;i d&#x1EEF; li&#x1EC7;u.</p>
<h3 id="thay-%C4%91%E1%BB%95i-1-t%C6%B0-duy-l%E1%BA%ADp-tr%C3%ACnhimperative-uikit-vs-declarative-swiftui">Thay &#x111;&#x1ED5;i #1: T&#x1B0; duy l&#x1EAD;p tr&#xEC;nh - Imperative (UIKit) vs. Declarative (SwiftUI)**</h3>
<p><img src="https://i0.wp.com/itiscloudy.com/wp-content/uploads/2022/10/image-33.png?ssl=1" alt="Imperative vs Declarative" loading="lazy"></p>
<p><img src="https://i0.wp.com/itiscloudy.com/wp-content/uploads/2022/10/image-29.png?ssl=1" alt="Imperative-UIKit vs Declarative-SwiftUI" loading="lazy"></p>
<p>&#x110;&#xE2;y l&#xE0; s&#x1EF1; kh&#xE1;c bi&#x1EC7;t l&#x1EDB;n nh&#x1EA5;t v&#xE0; quan tr&#x1ECD;ng nh&#x1EA5;t.</p>
<ul>
<li>
<p><strong>UIKit (Imperative - &quot;Ra l&#x1EC7;nh&quot;):</strong>  B&#x1EA1;n &quot;ra l&#x1EC7;nh&quot; cho &#x1EE9;ng d&#x1EE5;ng ph&#x1EA3;i l&#xE0;m g&#xEC; <strong>t&#x1EEB;ng b&#x1B0;&#x1EDB;c</strong>, <strong>t&#x1EEB;ng h&#xE0;nh &#x111;&#x1ED9;ng</strong>.  V&#xED; d&#x1EE5;: &quot;t&#x1EA1;o n&#xFA;t&quot;, &quot;&#x111;&#x1EB7;t n&#xFA;t &#x1EDF; v&#x1ECB; tr&#xED; X, Y&quot;, &quot;khi n&#xFA;t &#x111;&#x1B0;&#x1EE3;c nh&#x1EA5;n, h&#xE3;y thay &#x111;&#x1ED5;i text c&#x1EE7;a label&quot;.  B&#x1EA1;n ki&#x1EC3;m so&#xE1;t <strong>t&#x1EEB;ng chi ti&#x1EBF;t</strong> v&#xE0; <strong>th&#x1EDD;i &#x111;i&#x1EC3;m</strong> m&#x1ECD;i th&#x1EE9; x&#x1EA3;y ra.</p>
</li>
<li>
<p><strong>SwiftUI (Declarative - &quot;M&#xF4; t&#x1EA3;&quot;):</strong> B&#x1EA1;n <strong>m&#xF4; t&#x1EA3;</strong> giao di&#x1EC7;n b&#x1EA1;n <strong>mu&#x1ED1;n</strong> hi&#x1EC3;n th&#x1ECB;, <strong>tr&#x1EA1;ng th&#xE1;i</strong> c&#x1EE7;a giao di&#x1EC7;n, v&#xE0; <strong>c&#xE1;ch d&#x1EEF; li&#x1EC7;u li&#xEA;n k&#x1EBF;t v&#x1EDB;i giao di&#x1EC7;n</strong>.  H&#x1EC7; th&#x1ED1;ng SwiftUI s&#x1EBD; t&#x1EF1; &#x111;&#x1ED9;ng lo ph&#x1EA7;n c&#xF2;n l&#x1EA1;i, <strong>t&#x1ED1;i &#x1B0;u h&#xF3;a v&#xE0; v&#x1EBD; giao di&#x1EC7;n</strong> d&#x1EF1;a tr&#xEA;n m&#xF4; t&#x1EA3; c&#x1EE7;a b&#x1EA1;n.  B&#x1EA1;n t&#x1EAD;p trung v&#xE0;o <strong>&quot;what&quot; (mu&#x1ED1;n g&#xEC;)</strong> h&#x1A1;n l&#xE0; <strong>&quot;how&quot; (l&#xE0;m nh&#x1B0; th&#x1EBF; n&#xE0;o)</strong>.</p>
</li>
</ul>
<p><strong>V&#xED; d&#x1EE5;:</strong>  Thay &#x111;&#x1ED5;i text c&#x1EE7;a label khi n&#xFA;t &#x111;&#x1B0;&#x1EE3;c nh&#x1EA5;n (&#x1EE9;ng d&#x1EE5;ng Counter kinh &#x111;i&#x1EC3;n):</p>
<ul>
<li>
<p><strong>UIKit (Imperative):</strong> B&#x1EA1;n ph&#x1EA3;i vi&#x1EBF;t code &#x111;&#x1EC3; <strong>t&#xEC;m &#x111;&#x1EBF;n label</strong>, <strong>thay &#x111;&#x1ED5;i thu&#x1ED9;c t&#xED;nh <code>text</code></strong> c&#x1EE7;a label trong h&#xE0;m x&#x1EED; l&#xFD; s&#x1EF1; ki&#x1EC7;n n&#xFA;t nh&#x1EA5;n.</p>
</li>
<li>
<p><strong>SwiftUI (Declarative):</strong> B&#x1EA1;n ch&#x1EC9; c&#x1EA7;n <strong>m&#xF4; t&#x1EA3;</strong> r&#x1EB1;ng text c&#x1EE7;a <code>Text</code> view <strong>ph&#x1EE5; thu&#x1ED9;c v&#xE0;o m&#x1ED9;t bi&#x1EBF;n tr&#x1EA1;ng th&#xE1;i</strong>. Khi bi&#x1EBF;n tr&#x1EA1;ng th&#xE1;i thay &#x111;&#x1ED5;i, SwiftUI s&#x1EBD; <strong>t&#x1EF1; &#x111;&#x1ED9;ng c&#x1EAD;p nh&#x1EAD;t</strong> Text view.</p>
</li>
</ul>
<h3 id="thay-%C4%91%E1%BB%95i-2-x%C3%A2y-d%E1%BB%B1ng-giao-di%E1%BB%87nstoryboardxibs-uikit-vs-code-canvas-swiftui">Thay &#x111;&#x1ED5;i #2: X&#xE2;y d&#x1EF1;ng giao di&#x1EC7;n - Storyboard/Xibs (UIKit) vs. Code &amp; Canvas (SwiftUI)</h3>
<p><img src="https://sarunw.com/images/swiftui-as-uiviewcontroller-storyboard-add-segue.png" alt="Storyboard-UIKit" loading="lazy"></p>
<ul>
<li>
<p><strong>Storyboard/Xibs (UIKit):</strong>  Giao di&#x1EC7;n &#x111;&#x1B0;&#x1EE3;c thi&#x1EBF;t k&#x1EBF; ch&#x1EE7; y&#x1EBF;u b&#x1EB1;ng c&#xE1;ch <strong>k&#xE9;o th&#x1EA3; c&#xE1;c &#x111;&#x1ED1;i t&#x1B0;&#x1EE3;ng</strong> tr&#xEA;n giao di&#x1EC7;n &#x111;&#x1ED3; h&#x1ECD;a, sau &#x111;&#xF3; k&#x1EBF;t n&#x1ED1;i v&#x1EDB;i code.  Tr&#x1EF1;c quan ban &#x111;&#x1EA7;u, nh&#x1B0;ng <strong>kh&#xF3; qu&#x1EA3;n l&#xFD; d&#x1EF1; &#xE1;n l&#x1EDB;n</strong>, <strong>kh&#xF3; merge code</strong> khi l&#xE0;m vi&#x1EC7;c nh&#xF3;m, v&#xE0; <strong>k&#xE9;m linh ho&#x1EA1;t</strong> trong vi&#x1EC7;c t&#x1EA1;o ra c&#xE1;c giao di&#x1EC7;n ph&#x1EE9;c t&#x1EA1;p, &#x111;&#x1ED9;ng.</p>
</li>
<li>
<p><strong>Code &amp; Canvas (SwiftUI):</strong>  Giao di&#x1EC7;n &#x111;&#x1B0;&#x1EE3;c x&#xE2;y d&#x1EF1;ng <strong>ho&#xE0;n to&#xE0;n b&#x1EB1;ng code Swift</strong>, s&#x1EED; d&#x1EE5;ng c&#xE1;c <strong>View</strong> (th&#xE0;nh ph&#x1EA7;n giao di&#x1EC7;n) v&#xE0; <strong>Modifiers</strong> (thu&#x1ED9;c t&#xED;nh t&#xF9;y ch&#x1EC9;nh).  Canvas Preview cho ph&#xE9;p b&#x1EA1;n th&#x1EA5;y giao di&#x1EC7;n tr&#x1EF1;c quan ngay khi vi&#x1EBF;t code.  <strong>Linh ho&#x1EA1;t h&#x1A1;n, d&#x1EC5; qu&#x1EA3;n l&#xFD; code h&#x1A1;n, d&#x1EC5; t&#xE1;i s&#x1EED; d&#x1EE5;ng component</strong>, v&#xE0; ph&#xF9; h&#x1EE3;p v&#x1EDB;i phong c&#xE1;ch l&#x1EAD;p tr&#xEC;nh hi&#x1EC7;n &#x111;&#x1EA1;i.</p>
</li>
</ul>
<p><img src="https://miro.medium.com/v2/resize:fit:1400/1*4Cx7aiELGm4911OzceeVqA.png" alt="Canvas-SwiftUI" loading="lazy"></p>
<h3 id="thay-%C4%91%E1%BB%95i-3-b%E1%BB%91-c%E1%BB%A5c-giao-di%E1%BB%87nconstraints-uikit-vs-stacks-modifiers-swiftui">Thay &#x111;&#x1ED5;i #3: B&#x1ED1; c&#x1EE5;c giao di&#x1EC7;n - Constraints (UIKit) vs. Stacks &amp; Modifiers (SwiftUI)</h3>
<p><img src="https://benoitpasquier.com/images/2022/03/constraints-debugger.png" alt="Constraint-UIKit" loading="lazy"></p>
<ul>
<li><strong>Constraints (UIKit):</strong>  S&#x1EED; d&#x1EE5;ng h&#x1EC7; th&#x1ED1;ng r&#xE0;ng bu&#x1ED9;c (Constraints) &#x111;&#x1EC3; <strong>&#x111;&#x1ECB;nh v&#x1ECB; v&#xE0; k&#xED;ch th&#x1B0;&#x1EDB;c</strong> c&#xE1;c view.  Kh&#xE1; <strong>ph&#x1EE9;c t&#x1EA1;p</strong> v&#xE0; <strong>kh&#xF3; l&#xE0;m quen</strong>, &#x111;&#x1EB7;c bi&#x1EC7;t v&#x1EDB;i c&#xE1;c layout ph&#x1EE9;c t&#x1EA1;p, responsive tr&#xEA;n nhi&#x1EC1;u k&#xED;ch th&#x1B0;&#x1EDB;c m&#xE0;n h&#xEC;nh.</li>
</ul>
<p><img src="https://miro.medium.com/v2/resize:fit:1200/1*zgykUsO8zPERSahyjxxInw.png" alt="Stack-SwiftUI" loading="lazy"></p>
<ul>
<li><strong>Stacks (VStack, HStack, ZStack) &amp; Modifiers (SwiftUI):</strong>  S&#x1EED; d&#x1EE5;ng c&#xE1;c Stack (VStack - x&#x1EBF;p d&#x1ECD;c, HStack - x&#x1EBF;p ngang, ZStack - x&#x1EBF;p ch&#x1ED3;ng l&#xEA;n nhau) &#x111;&#x1EC3; <strong>t&#x1ED5; ch&#x1EE9;c b&#x1ED1; c&#x1EE5;c</strong> m&#x1ED9;t c&#xE1;ch <strong>&#x111;&#x1A1;n gi&#x1EA3;n v&#xE0; tr&#x1EF1;c quan</strong>.  Modifiers gi&#xFA;p <strong>t&#xF9;y ch&#x1EC9;nh</strong> giao di&#x1EC7;n (padding, font, m&#xE0;u s&#x1EAF;c, k&#xED;ch th&#x1B0;&#x1EDB;c...) m&#x1ED9;t c&#xE1;ch d&#x1EC5; d&#xE0;ng.  Layout tr&#x1EDF; n&#xEA;n <strong>&quot;d&#x1EC5; th&#x1EDF;&quot;</strong> h&#x1A1;n r&#x1EA5;t nhi&#x1EC1;u v&#x1EDB;i SwiftUI.</li>
</ul>
<h3 id="thay-%C4%91%E1%BB%95i-4-t%C6%B0%C6%A1ng-t%C3%A1c-d%E1%BB%AF-li%E1%BB%87u-giao-di%E1%BB%87ndelegateibaction-uikit-vs-state-binding-swiftui">Thay &#x111;&#x1ED5;i #4: T&#x1B0;&#x1A1;ng t&#xE1;c d&#x1EEF; li&#x1EC7;u &amp; giao di&#x1EC7;n - Delegate/IBAction (UIKit) vs. <code>@State</code>, Binding (SwiftUI)</h3>
<p><img src="https://assets.alexandria.raywenderlich.com/books/ia/images/016e5b2d035b717909105511a1e1403ab496e294d906746c256345b916895acb/original.png" alt="UIKit Delegate, IBAction" loading="lazy"></p>
<ul>
<li><strong>SwiftUI @State, Binding:</strong>  S&#x1EED; d&#x1EE5;ng c&#x1A1; ch&#x1EBF; <strong>Delegate</strong>, <strong>IBAction</strong>, <strong>Target-Action</strong> &#x111;&#x1EC3; x&#x1EED; l&#xFD; s&#x1EF1; ki&#x1EC7;n ng&#x1B0;&#x1EDD;i d&#xF9;ng v&#xE0; c&#x1EAD;p nh&#x1EAD;t giao di&#x1EC7;n.  C&#xF3; th&#x1EC3; tr&#x1EDF; n&#xEA;n <strong>kh&#xE1; ph&#x1EE9;c t&#x1EA1;p</strong> khi &#x1EE9;ng d&#x1EE5;ng l&#x1EDB;n v&#xE0; c&#xF3; nhi&#x1EC1;u t&#x1B0;&#x1A1;ng t&#xE1;c.</li>
</ul>
<p><img src="https://docs-assets.developer.apple.com/published/d98251c2fac9fc4f6843be1e4836cb93/Managing-User-Interface-State-1@2x.png" alt="UIKit Delegate, IBAction" loading="lazy"></p>
<ul>
<li><strong><code>@State</code>, Binding (SwiftUI):</strong>  S&#x1EED; d&#x1EE5;ng <strong><code>@State</code></strong> &#x111;&#x1EC3; khai b&#xE1;o <strong>bi&#x1EBF;n tr&#x1EA1;ng th&#xE1;i</strong> (d&#x1EEF; li&#x1EC7;u thay &#x111;&#x1ED5;i c&#x1EE7;a giao di&#x1EC7;n).  <strong>Binding</strong> (li&#xEA;n k&#x1EBF;t d&#x1EEF; li&#x1EC7;u) gi&#xFA;p <strong>k&#x1EBF;t n&#x1ED1;i d&#x1EEF; li&#x1EC7;u tr&#x1EA1;ng th&#xE1;i v&#x1EDB;i giao di&#x1EC7;n</strong>.  Khi d&#x1EEF; li&#x1EC7;u tr&#x1EA1;ng th&#xE1;i thay &#x111;&#x1ED5;i, SwiftUI <strong>t&#x1EF1; &#x111;&#x1ED9;ng c&#x1EAD;p nh&#x1EAD;t</strong> giao di&#x1EC7;n.  <strong>&#x110;&#x1A1;n gi&#x1EA3;n h&#x1A1;n, d&#x1EC5; qu&#x1EA3;n l&#xFD; lu&#x1ED3;ng d&#x1EEF; li&#x1EC7;u h&#x1A1;n</strong>, v&#xE0; code &#xED;t boilerplate h&#x1A1;n.</li>
</ul>
<p><strong>&#x110;&#x1EC3; d&#x1EC5; d&#xE0;ng h&#xEC;nh dung h&#x1A1;n, ch&#xFA;ng ta h&#xE3;y c&#xF9;ng xem b&#x1EA3;ng so s&#xE1;nh t&#xF3;m t&#x1EAF;t nh&#x1EEF;ng kh&#xE1;c bi&#x1EC7;t ch&#xED;nh gi&#x1EEF;a UIKit v&#xE0; SwiftUI:</strong></p>
<h2 id="4-b%E1%BA%AFt-%C4%91%E1%BA%A7u-h%C3%A0nh-tr%C3%ACnh-swiftui-c%E1%BB%A7a-b%E1%BA%A1nl%E1%BB%9Di-khuy%C3%AAn-v%C3%A0-ngu%E1%BB%93n-t%C3%A0i-li%E1%BB%87u">4. &quot;B&#x1EAF;t &#x111;&#x1EA7;u h&#xE0;nh tr&#xEC;nh SwiftUI c&#x1EE7;a b&#x1EA1;n!&quot; - L&#x1EDD;i khuy&#xEA;n v&#xE0; ngu&#x1ED3;n t&#xE0;i li&#x1EC7;u:</h2>
<p><img src="https://pbs.twimg.com/media/GU9zfiia4AIPd2m.jpg" alt="SwiftUI Roadmap" loading="lazy"><br>
<strong>(H&#xEC;nh &#x1EA3;nh minh h&#x1ECD;a: H&#xEC;nh &#x1EA3;nh con &#x111;&#x1B0;&#x1EDD;ng ph&#xED;a tr&#x1B0;&#x1EDB;c v&#x1EDB;i logo SwiftUI &#x1EDF; cu&#x1ED1;i &#x111;&#x1B0;&#x1EDD;ng, ho&#x1EB7;c h&#xEC;nh &#x1EA3;nh h&#x1ECD;c sinh &#x111;ang h&#xE0;o h&#x1EE9;ng h&#x1ECD;c SwiftUI)</strong></p>
<p>SwiftUI l&#xE0; t&#x1B0;&#x1A1;ng lai c&#x1EE7;a l&#x1EAD;p tr&#xEC;nh giao di&#x1EC7;n Apple.  H&#x1ECD;c SwiftUI ngay t&#x1EEB; b&#xE2;y gi&#x1EDD; s&#x1EBD; gi&#xFA;p b&#x1EA1;n <strong>n&#x1EAF;m b&#x1EAF;t l&#x1EE3;i th&#x1EBF;</strong>, t&#x1EA1;o ra nh&#x1EEF;ng &#x1EE9;ng d&#x1EE5;ng <strong>hi&#x1EC7;n &#x111;&#x1EA1;i v&#xE0; &#x1EA5;n t&#x1B0;&#x1EE3;ng</strong>, v&#xE0; m&#x1EDF; ra <strong>c&#x1A1; h&#x1ED9;i ngh&#x1EC1; nghi&#x1EC7;p r&#x1ED9;ng l&#x1EDB;n</strong>.</p>
<h3 id="l%E1%BB%9Di-khuy%C3%AAn-h%E1%BB%8Dc-t%E1%BA%ADp">L&#x1EDD;i khuy&#xEA;n h&#x1ECD;c t&#x1EAD;p:**</h3>
<ul>
<li><strong>B&#x1EAF;t &#x111;&#x1EA7;u t&#x1EEB; nh&#x1EEF;ng &#x111;i&#x1EC1;u c&#x1A1; b&#x1EA3;n:</strong>  H&#xE3;y b&#x1EAF;t &#x111;&#x1EA7;u l&#xE0;m quen v&#x1EDB;i c&#xE1;c <strong>View</strong> c&#x1A1; b&#x1EA3;n (Text, Image, Button...), <strong>Stacks</strong>, <strong>Modifiers</strong>, v&#xE0; kh&#xE1;i ni&#x1EC7;m <strong><code>@State</code>, Binding</strong>.</li>
<li><strong>Th&#x1EF1;c h&#xE0;nh th&#x1B0;&#x1EDD;ng xuy&#xEA;n:</strong>  C&#xE1;ch t&#x1ED1;t nh&#x1EA5;t &#x111;&#x1EC3; h&#x1ECD;c SwiftUI l&#xE0; <strong>th&#x1EF1;c h&#xE0;nh</strong>. H&#xE3;y th&#x1EED; x&#xE2;y d&#x1EF1;ng c&#xE1;c &#x1EE9;ng d&#x1EE5;ng nh&#x1ECF;, th&#x1EED; nghi&#x1EC7;m c&#xE1;c giao di&#x1EC7;n kh&#xE1;c nhau, v&#xE0; gi&#x1EA3;i quy&#x1EBF;t c&#xE1;c b&#xE0;i t&#x1EAD;p th&#x1EF1;c h&#xE0;nh.</li>
<li><strong>&#x110;&#x1ECD;c t&#xE0;i li&#x1EC7;u, tutorial ch&#xED;nh th&#x1EE9;c c&#x1EE7;a Apple:</strong>  Apple cung c&#x1EA5;p r&#x1EA5;t nhi&#x1EC1;u <strong>t&#xE0;i li&#x1EC7;u v&#xE0; tutorial ch&#x1EA5;t l&#x1B0;&#x1EE3;ng cao</strong> v&#x1EC1; SwiftUI. &#x110;&#xE2;y l&#xE0; ngu&#x1ED3;n t&#xE0;i li&#x1EC7;u t&#x1ED1;t nh&#x1EA5;t v&#xE0; lu&#xF4;n &#x111;&#x1B0;&#x1EE3;c c&#x1EAD;p nh&#x1EAD;t.</li>
<li><strong>Tham gia c&#x1ED9;ng &#x111;&#x1ED3;ng SwiftUI:</strong>  H&#xE3;y tham gia c&#xE1;c di&#x1EC5;n &#x111;&#xE0;n, nh&#xF3;m c&#x1ED9;ng &#x111;&#x1ED3;ng SwiftUI &#x111;&#x1EC3; <strong>h&#x1ECD;c h&#x1ECF;i kinh nghi&#x1EC7;m</strong>, <strong>&#x111;&#x1EB7;t c&#xE2;u h&#x1ECF;i</strong>, v&#xE0; <strong>chia s&#x1EBB; ki&#x1EBF;n th&#x1EE9;c</strong> v&#x1EDB;i nh&#x1EEF;ng ng&#x1B0;&#x1EDD;i kh&#xE1;c.</li>
</ul>
<h3 id="ngu%E1%BB%93n-t%C3%A0i-li%E1%BB%87u-tham-kh%E1%BA%A3o">Ngu&#x1ED3;n t&#xE0;i li&#x1EC7;u tham kh&#x1EA3;o:</h3>
<ul>
<li><strong>Apple SwiftUI Tutorials:</strong> <a href="https://developer.apple.com/tutorials/swiftui/">https://developer.apple.com/tutorials/swiftui/</a></li>
<li><strong>Hacking with Swift (Paul Hudson):</strong> <a href="https://www.hackingwithswift.com/">https://www.hackingwithswift.com/</a> (R&#x1EA5;t nhi&#x1EC1;u b&#xE0;i vi&#x1EBF;t v&#xE0; kh&#xF3;a h&#x1ECD;c mi&#x1EC5;n ph&#xED; v&#x1EC1; SwiftUI)</li>
<li><strong>Ray Wenderlich SwiftUI tutorials:</strong> <a href="https://www.raywenderlich.com/">https://www.raywenderlich.com/</a> (Website n&#x1ED5;i ti&#x1EBF;ng v&#x1EDB;i c&#xE1;c tutorial ch&#x1EA5;t l&#x1B0;&#x1EE3;ng cao v&#x1EC1; iOS development, bao g&#x1ED3;m SwiftUI)</li>
<li><strong>SwiftUI by Example:</strong> <a href="https://swiftui-lab.com/">https://swiftui-lab.com/</a> (T&#x1ED5;ng h&#x1EE3;p v&#xED; d&#x1EE5; code SwiftUI cho nhi&#x1EC1;u t&#xEC;nh hu&#x1ED1;ng kh&#xE1;c nhau)</li>
</ul>
<p><strong>(H&#xEC;nh &#x1EA3;nh k&#x1EBF;t th&#xFA;c: Logo SwiftUI l&#x1EDB;n, ho&#x1EB7;c c&#xE2;u slogan &quot;Welcome to the world of SwiftUI!&quot;)</strong></p>
<p>Ch&#xE0;o m&#x1EEB;ng &#x111;&#x1EBF;n v&#x1EDB;i th&#x1EBF; gi&#x1EDB;i SwiftUI!  H&#xE3;y c&#xF9;ng nhau b&#x1EAF;t &#x111;&#x1EA7;u h&#xE0;nh tr&#xEC;nh kh&#xE1;m ph&#xE1; v&#xE0; chinh ph&#x1EE5;c t&#x1B0;&#x1A1;ng lai c&#x1EE7;a l&#x1EAD;p tr&#xEC;nh giao di&#x1EC7;n iOS nh&#xE9;! Ch&#xFA;c c&#xE1;c b&#x1EA1;n th&#xE0;nh c&#xF4;ng v&#xE0; c&#xF3; nh&#x1EEF;ng tr&#x1EA3;i nghi&#x1EC7;m l&#x1EAD;p tr&#xEC;nh tuy&#x1EC7;t v&#x1EDD;i!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Bí kíp chinh phục chứng chỉ App Development With Swift (Certified User / Assosiate)]]></title><description><![CDATA[Bạn đang chuẩn bị cho kỳ thi Development With Swift Certified User/Associate? Đừng lo lắng! Bài viết này sẽ cung cấp cho bạn những thông tin và chiến lược cần thiết để tự tin "vượt vũ môn" và sở hữu chứng chỉ danh giá từ Apple.]]></description><link>https://makexyz.fun/bi-kip-chinh-phuc-chung-chi-app-development-with-swift-certified-user-and-assosiate/</link><guid isPermaLink="false">67c30f87b82b9d4a1c50be85</guid><category><![CDATA[Swift]]></category><category><![CDATA[Education]]></category><dc:creator><![CDATA[Tony Phạm]]></dc:creator><pubDate>Sat, 01 Mar 2025 14:13:46 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>B&#x1EA1;n &#x111;ang chu&#x1EA9;n b&#x1ECB; cho k&#x1EF3; thi Development With Swift Certified User/Associate? &#x110;&#x1EEB;ng lo l&#x1EAF;ng! B&#xE0;i vi&#x1EBF;t n&#xE0;y s&#x1EBD; cung c&#x1EA5;p cho b&#x1EA1;n nh&#x1EEF;ng th&#xF4;ng tin v&#xE0; chi&#x1EBF;n l&#x1B0;&#x1EE3;c c&#x1EA7;n thi&#x1EBF;t &#x111;&#x1EC3; t&#x1EF1; tin &quot;v&#x1B0;&#x1EE3;t v&#x169; m&#xF4;n&quot; v&#xE0; s&#x1EDF; h&#x1EEF;u ch&#x1EE9;ng ch&#x1EC9; danh gi&#xE1; t&#x1EEB; Apple.</p>
<h2 id="1-hi%E1%BB%83u-r%C3%B5-c%E1%BA%A5u-tr%C3%BAc-%C4%91%E1%BB%81-thi">1. Hi&#x1EC3;u r&#xF5; c&#x1EA5;u tr&#xFA;c &#x111;&#x1EC1; thi:</h2>
<p>B&#xE0;i thi n&#xE0;y kh&#xF4;ng ch&#x1EC9; ki&#x1EC3;m tra l&#xFD; thuy&#x1EBF;t m&#xE0; c&#xF2;n &#x111;&#xE1;nh gi&#xE1; kh&#x1EA3; n&#x103;ng <em>th&#x1EF1;c h&#xE0;nh</em> c&#x1EE7;a b&#x1EA1;n. H&#xE3;y ghi nh&#x1EDB; nh&#x1EEF;ng &#x111;i&#x1EC3;m sau:</p>
<ul>
<li><strong>Th&#x1EDD;i gian:</strong> B&#x1EA1;n s&#x1EBD; c&#xF3; 50 ph&#xFA;t &#x111;&#x1EC3; ho&#xE0;n th&#xE0;nh b&#xE0;i thi.</li>
<li><strong>S&#x1ED1; l&#x1B0;&#x1EE3;ng c&#xE2;u h&#x1ECF;i:</strong> Kho&#x1EA3;ng 35-50 c&#xE2;u (c&#xF3; th&#x1EC3; thay &#x111;&#x1ED5;i t&#xF9;y phi&#xEA;n b&#x1EA3;n).</li>
<li><strong>C&#xE1;c d&#x1EA1;ng c&#xE2;u h&#x1ECF;i b&#x1EA1;n s&#x1EBD; g&#x1EB7;p:</strong>
<ul>
<li><strong>Tr&#x1EAF;c nghi&#x1EC7;m:</strong> Ch&#x1ECD;n &#x111;&#xE1;p &#xE1;n &#x111;&#xFA;ng nh&#x1EA5;t.</li>
<li><strong>Th&#x1EF1;c h&#xE0;nh tr&#x1EF1;c ti&#x1EBF;p tr&#xEA;n Xcode (Live-in-the-app):</strong> &#x110;&#xE2;y l&#xE0; <em>ph&#x1EA7;n quan tr&#x1ECD;ng nh&#x1EA5;t</em>. B&#x1EA1;n s&#x1EBD; ph&#x1EA3;i:
<ul>
<li>Vi&#x1EBF;t code &#x111;&#x1EC3; gi&#x1EA3;i quy&#x1EBF;t v&#x1EA5;n &#x111;&#x1EC1;.</li>
<li>S&#x1EED;a l&#x1ED7;i (debug) code.</li>
<li>Thi&#x1EBF;t k&#x1EBF; giao di&#x1EC7;n (UI) theo y&#xEA;u c&#x1EA7;u.</li>
<li>K&#x1EBF;t n&#x1ED1;i c&#xE1;c th&#xE0;nh ph&#x1EA7;n trong &#x1EE9;ng d&#x1EE5;ng.</li>
<li>X&#x1EED; l&#xFD; d&#x1EEF; li&#x1EC7;u.</li>
</ul>
</li>
<li><strong>M&#x1ED9;t s&#x1ED1; d&#x1EA1;ng kh&#xE1;c (&#xED;t g&#x1EB7;p):</strong> &#x110;i&#x1EC1;n v&#xE0;o ch&#x1ED7; tr&#x1ED1;ng, k&#xE9;o th&#x1EA3; code, tr&#x1EA3; l&#x1EDD;i c&#xE2;u h&#x1ECF;i t&#xEC;nh hu&#x1ED1;ng.</li>
</ul>
</li>
</ul>
<h2 id="2-n%E1%BB%99i-dung-%C3%B4n-t%E1%BA%ADp">2. N&#x1ED9;i dung &#xF4;n t&#x1EAD;p:</h2>
<p>&#x110;&#x1EC3; &#x111;&#x1EA1;t k&#x1EBF;t qu&#x1EA3; t&#x1ED1;t, b&#x1EA1;n c&#x1EA7;n n&#x1EAF;m v&#x1EEF;ng ki&#x1EBF;n th&#x1EE9;c v&#xE0; k&#x1EF9; n&#x103;ng theo khung ch&#x1B0;&#x1A1;ng tr&#xEC;nh c&#x1EE7;a Apple:</p>
<ul>
<li><strong>Certified User:</strong> &quot;Develop in Swift Explorations&quot;</li>
<li><strong>Associate:</strong> &quot;Develop in Swift Fundamentals&quot;</li>
</ul>
<p>C&#x1EE5; th&#x1EC3;, h&#xE3;y t&#x1EAD;p trung v&#xE0;o c&#xE1;c ch&#x1EE7; &#x111;&#x1EC1; sau:</p>
<ul>
<li><strong>Xcode:</strong> S&#x1EED; d&#x1EE5;ng th&#xE0;nh th&#x1EA1;o c&#xE1;c c&#xF4;ng c&#x1EE5; c&#x1EE7;a Xcode (Interface Builder, Debugger, Simulator...).</li>
<li><strong>Swift:</strong> N&#x1EAF;m v&#x1EEF;ng t&#x1EEB; c&#x1A1; b&#x1EA3;n &#x111;&#x1EBF;n n&#xE2;ng cao (bi&#x1EBF;n, ki&#x1EC3;u d&#x1EEF; li&#x1EC7;u, to&#xE1;n t&#x1EED;, c&#x1EA5;u tr&#xFA;c &#x111;i&#x1EC1;u khi&#x1EC3;n, h&#xE0;m, l&#x1EDB;p, c&#x1EA5;u tr&#xFA;c, Optionals...).</li>
<li><strong>SwiftUI:</strong> X&#xE2;y d&#x1EF1;ng giao di&#x1EC7;n b&#x1EB1;ng SwiftUI (c&#xE1;c view, modifiers, layout, data binding...).</li>
<li><strong>L&#x1EAD;p k&#x1EBF; ho&#x1EA1;ch v&#xE0; thi&#x1EBF;t k&#x1EBF; &#x1EE9;ng d&#x1EE5;ng (Associate):</strong> Quy tr&#xEC;nh ph&#xE1;t tri&#x1EC3;n, b&#x1EA3;o m&#x1EAD;t, thi&#x1EBF;t k&#x1EBF; ti&#x1EBF;p c&#x1EAD;n.</li>
<li><strong>G&#x1EE1; l&#x1ED7;i (Associate):</strong> T&#xEC;m v&#xE0; s&#x1EED;a l&#x1ED7;i.</li>
</ul>
<h2 id="3-ch%E1%BB%A9ng-ch%E1%BB%89">3. Ch&#x1EE9;ng ch&#x1EC9;:</h2>
<ul>
<li>C&#xF3; 2 c&#x1EA5;p &#x111;&#x1ED9;: <strong>Certified User</strong> v&#xE0; <strong>Associate</strong>.</li>
<li>Ch&#x1EE9;ng ch&#x1EC9; do <strong>Apple</strong> c&#x1EA5;p, c&#xF3; gi&#xE1; tr&#x1ECB; <strong>to&#xE0;n c&#x1EA7;u</strong> v&#xE0; <strong>v&#x129;nh vi&#x1EC5;n</strong>.</li>
</ul>
<h2 id="4-b%C3%A0i-thi-th%E1%BB%AD">4. B&#xE0;i thi th&#x1EED;:</h2>
<ul>
<li>B&#x1EA1;n n&#xEA;n mua voucher k&#xE8;m theo b&#xE0;i thi th&#x1EED; (practice test) &#x111;&#x1EC3; l&#xE0;m quen v&#x1EDB;i &#x111;&#x1ECB;nh d&#x1EA1;ng &#x111;&#x1EC1;.</li>
</ul>
<!--kg-card-end: markdown--><p></p><!--kg-card-begin: html--><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2522773707742607" crossorigin="anonymous"></script>
<!-- horizontal-main-content-ads -->
<ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-2522773707742607" data-ad-slot="8813553776" data-ad-format="auto" data-full-width-responsive="true"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script><!--kg-card-end: html--><p></p><!--kg-card-begin: markdown--><h2 id="5-chi%E1%BA%BFn-l%C6%B0%E1%BB%A3c-luy%E1%BB%87n-thi-th%E1%BA%A7n-t%E1%BB%91c">5. Chi&#x1EBF;n l&#x1B0;&#x1EE3;c luy&#x1EC7;n thi &quot;Th&#x1EA7;n T&#x1ED1;c&quot;:</h2>
<p>V&#xEC; ph&#x1EA7;n l&#x1EDB;n b&#xE0;i thi l&#xE0; th&#x1EF1;c h&#xE0;nh, h&#xE3;y t&#x1EAD;p trung v&#xE0;o luy&#x1EC7;n t&#x1EAD;p <em>tr&#x1EF1;c ti&#x1EBF;p tr&#xEA;n Xcode</em>:</p>
<ul>
<li>
<p><strong>&quot;C&#xE0;y&quot; gi&#xE1;o tr&#xEC;nh &quot;Develop in Swift Explorations&quot; (cho Certified User) v&#xE0; &quot;Develop in Swift Fundamentals&quot; (cho Associate) c&#x1EE7;a Apple:</strong> &#x110;&#xE2;y l&#xE0; t&#xE0;i li&#x1EC7;u ch&#xED;nh th&#x1EE9;c, <em>mi&#x1EC5;n ph&#xED;</em> v&#xE0; &#x111;&#x1B0;&#x1EE3;c thi&#x1EBF;t k&#x1EBF; &#x111;&#x1EC3; gi&#xFA;p b&#x1EA1;n chu&#x1EA9;n b&#x1ECB; cho k&#x1EF3; thi. H&#xE3;y &#x111;&#x1EA3;m b&#x1EA3;o b&#x1EA1;n hi&#x1EC3;u r&#xF5; m&#x1ECD;i kh&#xE1;i ni&#x1EC7;m v&#xE0; l&#xE0;m h&#x1EBF;t b&#xE0;i t&#x1EAD;p.</p>
</li>
<li>
<p><strong>Th&#x1EF1;c h&#xE0;nh, th&#x1EF1;c h&#xE0;nh v&#xE0; th&#x1EF1;c h&#xE0;nh!</strong></p>
<ul>
<li><strong>B&#xE0;i t&#x1EAD;p nh&#x1ECF;:</strong> B&#x1EAF;t &#x111;&#x1EA7;u v&#x1EDB;i c&#xE1;c b&#xE0;i t&#x1EAD;p nh&#x1ECF; &#x111;&#x1EC3; n&#x1EAF;m v&#x1EEF;ng t&#x1EEB;ng kh&#xE1;i ni&#x1EC7;m (bi&#x1EBF;n, h&#xE0;m, v&#xF2;ng l&#x1EB7;p...).</li>
<li><strong>D&#x1EF1; &#xE1;n th&#x1EF1;c t&#x1EBF;:</strong> X&#xE2;y d&#x1EF1;ng c&#xE1;c &#x1EE9;ng d&#x1EE5;ng iOS &#x111;&#x1A1;n gi&#x1EA3;n, t&#x1EEB; &#xFD; t&#x1B0;&#x1EDF;ng &#x111;&#x1EBF;n ho&#xE0;n thi&#x1EC7;n.</li>
<li><strong>Swift Playgrounds:</strong> S&#x1EED; d&#x1EE5;ng c&#xF4;ng c&#x1EE5; n&#xE0;y &#x111;&#x1EC3; h&#x1ECD;c v&#xE0; th&#x1EED; nghi&#x1EC7;m code Swift m&#x1ED9;t c&#xE1;ch tr&#x1EF1;c quan.</li>
</ul>
</li>
<li>
<p><strong>T&#x1EA1;o project m&#x1EDB;i:</strong> Luy&#x1EC7;n t&#x1EAD;p t&#x1EA1;o m&#x1EDB;i &#x111;&#x1EC3; quen v&#x1EDB;i thao t&#xE1;c.<br>
*   Th&#xEA;m c&#xE1;c th&#xE0;nh ph&#x1EA7;n UI (Text, Image, Button, ...) v&#xE0;o giao di&#x1EC7;n.<br>
*   S&#x1EED; d&#x1EE5;ng c&#xE1;c modifiers &#x111;&#x1EC3; t&#xF9;y ch&#x1EC9;nh giao di&#x1EC7;n.<br>
*   K&#x1EBF;t n&#x1ED1;i c&#xE1;c th&#xE0;nh ph&#x1EA7;n UI v&#x1EDB;i code Swift.<br>
*   X&#x1EED; l&#xFD; s&#x1EF1; ki&#x1EC7;n (v&#xED; d&#x1EE5;: khi ng&#x1B0;&#x1EDD;i d&#xF9;ng nh&#x1EA5;n n&#xFA;t).<br>
*   S&#x1EED; d&#x1EE5;ng c&#xE1;c c&#x1EA5;u tr&#xFA;c &#x111;i&#x1EC1;u khi&#x1EC3;n (if/else, for, while).<br>
*   &#x110;&#x1ECB;nh ngh&#x129;a v&#xE0; s&#x1EED; d&#x1EE5;ng h&#xE0;m, l&#x1EDB;p, c&#x1EA5;u tr&#xFA;c.<br>
*   L&#xE0;m vi&#x1EC7;c v&#x1EDB;i d&#x1EEF; li&#x1EC7;u (m&#x1EA3;ng, t&#x1EEB; &#x111;i&#x1EC3;n).<br>
*   G&#x1EE1; l&#x1ED7;i (s&#x1EED; d&#x1EE5;ng breakpoints, xem gi&#xE1; tr&#x1ECB; bi&#x1EBF;n).</p>
</li>
<li>
<p><strong>L&#xE0;m b&#xE0;i thi th&#x1EED; (Practice Tests):</strong></p>
<ul>
<li><strong>GMetrix:</strong> &#x110;&#xE2;y l&#xE0; n&#x1EC1;n t&#x1EA3;ng <em>quan tr&#x1ECD;ng nh&#x1EA5;t</em> v&#xEC; n&#xF3; m&#xF4; ph&#x1ECF;ng r&#x1EA5;t s&#xE1;t b&#xE0;i thi th&#x1EAD;t. S&#x1EED; d&#x1EE5;ng c&#x1EA3; hai ch&#x1EBF; &#x111;&#x1ED9;:
<ul>
<li><strong>Training Mode:</strong> L&#xE0;m b&#xE0;i v&#xE0; xem &#x111;&#xE1;p &#xE1;n, h&#x1B0;&#x1EDB;ng d&#x1EAB;n ngay.</li>
<li><strong>Testing Mode:</strong> M&#xF4; ph&#x1ECF;ng thi th&#x1EAD;t, c&#xF3; gi&#x1EDB;i h&#x1EA1;n th&#x1EDD;i gian.</li>
</ul>
</li>
<li><strong>HackingWithSwift</strong>: Cung c&#x1EA5;p c&#xE1;c b&#xE0;i ki&#x1EC3;m tra nh&#x1ECF; mi&#x1EC5;n ph&#xED;.</li>
</ul>
</li>
<li>
<p><strong>L&#xE0;m quen v&#x1EDB;i giao di&#x1EC7;n thi:</strong> Xem video h&#x1B0;&#x1EDB;ng d&#x1EAB;n v&#x1EC1; giao di&#x1EC7;n thi c&#x1EE7;a Certiport.</p>
</li>
<li>
<p><strong>Qu&#x1EA3;n l&#xFD; th&#x1EDD;i gian:</strong> Luy&#x1EC7;n t&#x1EAD;p l&#xE0;m b&#xE0;i thi th&#x1EED; trong 50 ph&#xFA;t.</p>
</li>
<li>
<p><strong>&#xD4;n t&#x1EAD;p theo ch&#x1EE7; &#x111;&#x1EC1;:</strong> D&#x1EF1;a v&#xE0;o k&#x1EBF;t qu&#x1EA3; thi th&#x1EED;, t&#x1EAD;p trung &#xF4;n l&#x1EA1;i nh&#x1EEF;ng ph&#x1EA7;n b&#x1EA1;n c&#xF2;n y&#x1EBF;u.</p>
</li>
<li>
<p><strong>M&#xF4;i tr&#x1B0;&#x1EDD;ng thi th&#x1EED;:</strong> T&#x1ED5; ch&#x1EE9;c c&#xE1;c bu&#x1ED5;i thi th&#x1EED;, h&#x1EB9;n gi&#x1EDD; nh&#x1B0; thi th&#x1EAD;t.</p>
</li>
</ul>
<h2 id="6-m%E1%BB%99t-v%C3%A0i-l%C6%B0u-%C3%BD">6. M&#x1ED9;t v&#xE0;i l&#x1B0;u &#xFD;</h2>
<ul>
<li><strong>C&#x1EAD;p nh&#x1EAD;t ki&#x1EBF;n th&#x1EE9;c Framework</strong> 2 cu&#x1ED1;n s&#xE1;nh <strong>Develop in Swift Explorations</strong> v&#xE0; <strong>Develop in Swift Fundamentals</strong> &#x111;ang s&#x1EED; d&#x1EE5;ng Framework UIKit. &#x110;&#x1EC1; thi hi&#x1EC7;n t&#x1EA1;i &#x111;&#xE3; chuy&#x1EC3;n sang s&#x1EED; d&#x1EE5;ng framework SwiftUI. B&#x1EA1;n n&#xEA;n &#x111;&#x1ECD;c th&#xEA;m <a href="https://developer.apple.com/tutorials/swiftui/">Swift UI Tutorial (Apple)</a> v&#xE0; n&#x1EAF;m v&#x1EEF;ng n&#x1ED9;i dung.</li>
<li><strong>Th&#x1EF1;c h&#xE0;nh l&#xE0; ch&#xEC;a kh&#xF3;a:</strong> &#x110;&#x1EEB;ng ch&#x1EC9; &#x111;&#x1ECD;c l&#xFD; thuy&#x1EBF;t, h&#xE3;y d&#xE0;nh ph&#x1EA7;n l&#x1EDB;n th&#x1EDD;i gian &#x111;&#x1EC3; th&#x1EF1;c h&#xE0;nh tr&#xEA;n Xcode.</li>
<li><strong>GMetrix l&#xE0; b&#x1EA1;n &#x111;&#x1ED3;ng h&#xE0;nh:</strong> Luy&#x1EC7;n t&#x1EAD;p tr&#xEA;n GMetrix th&#x1B0;&#x1EDD;ng xuy&#xEA;n &#x111;&#x1EC3; l&#xE0;m quen v&#x1EDB;i &#x111;&#x1ECB;nh d&#x1EA1;ng v&#xE0; &#xE1;p l&#x1EF1;c th&#x1EDD;i gian.</li>
</ul>
<p>Ch&#xFA;c b&#x1EA1;n &#xF4;n t&#x1EAD;p hi&#x1EC7;u qu&#x1EA3; v&#xE0; &#x111;&#x1EA1;t k&#x1EBF;t qu&#x1EA3; cao trong k&#x1EF3; thi!</p>
<!--kg-card-end: markdown--><p></p><!--kg-card-begin: html--><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-2522773707742607" crossorigin="anonymous"></script>
<!-- horizontal-main-content-ads -->
<ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-2522773707742607" data-ad-slot="8813553776" data-ad-format="auto" data-full-width-responsive="true"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script><!--kg-card-end: html--><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[[Video Summary] Ch  4 5 Conforming to Identifiable and Using Computed Properties in SwiftUI enums (2025)]]></title><description><![CDATA[<!--kg-card-begin: markdown--><h2 id="m%C3%B4-t%E1%BA%A3-nhanh">M&#xF4; t&#x1EA3; nhanh</h2>
<p>Video n&#xE0;y tr&#xEC;nh b&#xE0;y c&#xE1;ch l&#xE0;m cho c&#xE1;c enum tu&#xE2;n th&#x1EE7; giao th&#x1EE9;c Identifiable trong SwiftUI, gi&#xFA;p x&#xE1;c &#x111;&#x1ECB;nh t&#xED;nh</p>]]></description><link>https://makexyz.fun/video-summary-ch-4-5-conforming-to-identifiable-and-using-computed-properties-in-swiftui-enums-2025/</link><guid isPermaLink="false">67b35d56ca5820942839efb7</guid><category><![CDATA[SwiftUI]]></category><category><![CDATA[Swift]]></category><category><![CDATA[Video Summary]]></category><dc:creator><![CDATA[Admin]]></dc:creator><pubDate>Mon, 24 Feb 2025 13:08:58 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h2 id="m%C3%B4-t%E1%BA%A3-nhanh">M&#xF4; t&#x1EA3; nhanh</h2>
<p>Video n&#xE0;y tr&#xEC;nh b&#xE0;y c&#xE1;ch l&#xE0;m cho c&#xE1;c enum tu&#xE2;n th&#x1EE7; giao th&#x1EE9;c Identifiable trong SwiftUI, gi&#xFA;p x&#xE1;c &#x111;&#x1ECB;nh t&#xED;nh duy nh&#x1EA5;t c&#x1EE7;a t&#x1EEB;ng ph&#x1EA7;n t&#x1EED; v&#xE0; lo&#x1EA1;i b&#x1ECF; tham s&#x1ED1; ID trong v&#xF2;ng l&#x1EB7;p ForEach. &#x110;&#x1ED3;ng th&#x1EDD;i, video c&#x169;ng h&#x1B0;&#x1EDB;ng d&#x1EAB;n c&#xE1;ch t&#x1EA1;o computed properties trong enum.</p>
<h2 id="video">Video</h2>
<p>Click v&#xE0;o h&#xEC;nh d&#x1B0;&#x1EDB;i &#x111;&#x1EC3; m&#x1EDF;:<br>
<a href="https://www.youtube.com/embed/05Daer4yY04"><img src="https://img.youtube.com/vi/05Daer4yY04/0.jpg" alt="Ch  4 5 Conforming to Identifiable and Using Computed Properties in SwiftUI enums (2025)" loading="lazy"></a></p>
<h2 id="m%C3%B4-t%E1%BA%A3-chi-ti%E1%BA%BFt">M&#xF4; t&#x1EA3; chi ti&#x1EBF;t</h2>
<p>Video n&#xE0;y h&#x1B0;&#x1EDB;ng d&#x1EAB;n c&#xE1;ch l&#xE0;m cho c&#xE1;c enum tu&#xE2;n th&#x1EE7; giao th&#x1EE9;c Identifiable trong SwiftUI, gi&#xFA;p x&#xE1;c &#x111;&#x1ECB;nh t&#xED;nh duy nh&#x1EA5;t c&#x1EE7;a t&#x1EEB;ng ph&#x1EA7;n t&#x1EED; v&#xE0; lo&#x1EA1;i b&#x1ECF; tham s&#x1ED1; ID trong v&#xF2;ng l&#x1EB7;p ForEach. &#x110;&#x1ED3;ng th&#x1EDD;i, video c&#x169;ng h&#x1B0;&#x1EDB;ng d&#x1EAB;n c&#xE1;ch t&#x1EA1;o computed properties trong enum.</p>
<p><a href="https://www.youtube.com/embed/05Daer4yY04"><img src="https://img.youtube.com/vi/05Daer4yY04/0.jpg" alt="Ch  4 5 Conforming to Identifiable and Using Computed Properties in SwiftUI enums (2025)" loading="lazy"></a></p>
<p>C&#xE1;c b&#x1B0;&#x1EDB;c th&#x1EF1;c hi&#x1EC7;n:</p>
<ol>
<li><strong>Tu&#xE2;n th&#x1EE7; giao th&#x1EE9;c Identifiable:</strong>
<ul>
<li>Th&#xEA;m <code>Identifiable</code> v&#xE0;o khai b&#xE1;o enum.</li>
<li>X&#xE1;c nh&#x1EAD;n enum tu&#xE2;n th&#x1EE7; giao th&#x1EE9;c <code>Identifiable</code> b&#x1EB1;ng c&#xE1;ch th&#xEA;m <code>comma identifiable</code> (<code>, Identifiable</code>) sau ki&#x1EC3;u d&#x1EEF; li&#x1EC7;u v&#xE0; <code>case iterable</code> (<code>, CaseIterable</code>).</li>
</ul>
</li>
<li><strong>Th&#xEA;m ID property</strong>
<ul>
<li>XCode s&#x1EBD; b&#xE1;o l&#x1ED7;i v&#xEC; giao th&#x1EE9;c <code>Identifiable</code> y&#xEA;u c&#x1EA7;u ph&#x1EA3;i c&#xF3; m&#x1ED9;t thu&#x1ED9;c t&#xED;nh <code>ID</code> duy nh&#x1EA5;t</li>
<li>Th&#xEA;m computed property <code>ID</code> v&#xE0;o enum.
<ul>
<li>Di chuy&#x1EC3;n c&#xE1;c bi&#x1EBF;n b&#xEA;n trong enums sau t&#x1EA5;t c&#x1EA3; c&#xE1;c cases.</li>
<li>S&#x1EED; d&#x1EE5;ng computed property &#x111;&#x1EC3; tr&#x1EA3; v&#x1EC1; gi&#xE1; tr&#x1ECB; rawValue c&#x1EE7;a enum l&#xE0;m ID (v&#xEC; m&#x1ED7;i rawValue l&#xE0; duy nh&#x1EA5;t).</li>
</ul>
</li>
</ul>
</li>
<li><strong>S&#x1EED; d&#x1EE5;ng ForEach m&#xE0; kh&#xF4;ng c&#x1EA7;n ID:</strong>
<ul>
<li>Khi enum &#x111;&#xE3; tu&#xE2;n th&#x1EE7; <code>Identifiable</code>, c&#xF3; th&#x1EC3; lo&#x1EA1;i b&#x1ECF; tham s&#x1ED1; <code>id: \.self</code> trong ForEach.</li>
<li>XCode s&#x1EBD; t&#x1EF1; &#x111;&#x1ED9;ng t&#xEC;m thu&#x1ED9;c t&#xED;nh <code>ID</code> duy nh&#x1EA5;t c&#x1EE7;a enum.</li>
</ul>
</li>
<li><strong>T&#x1EA1;o computed property cho description:</strong>
<ul>
<li>T&#x1EA1;o m&#x1ED9;t computed property kh&#xE1;c t&#xEA;n l&#xE0; <code>description</code> &#x111;&#x1EC3; tr&#x1EA3; v&#x1EC1; chu&#x1ED7;i m&#xF4; t&#x1EA3; c&#x1EE7;a m&#x1ED7;i enum case (v&#xED; d&#x1EE5;: &quot;1-sided&quot;, &quot;2-sided&quot;,...).</li>
<li>S&#x1EED; d&#x1EE5;ng computed property n&#xE0;y trong ti&#xEA;u &#x111;&#x1EC1; c&#x1EE7;a button.</li>
</ul>
</li>
</ol>
<h2 id="l%E1%BB%9Di-ch%C3%BAc">L&#x1EDD;i ch&#xFA;c</h2>
<p>Ch&#xFA;c b&#x1EA1;n th&#xE0;nh c&#xF4;ng tr&#xEA;n con &#x111;&#x1B0;&#x1EDD;ng chinh ph&#x1EE5;c iOS!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[[Video Summary] Ch. 4.6 Flip a Text View & More using withAnimation in SwiftUI (2025)]]></title><description><![CDATA[<!--kg-card-begin: markdown--><h2 id="m%C3%B4-t%E1%BA%A3-nhanh">M&#xF4; t&#x1EA3; nhanh</h2>
<p>Video n&#xE0;y tr&#xEC;nh b&#xE0;y c&#xE1;ch t&#x1EA1;o hi&#x1EC7;u &#x1EE9;ng l&#x1EAD;t ch&#x1EEF; (text flip animation) trong SwiftUI b&#x1EB1;ng c&#xE1;ch s&#x1EED; d&#x1EE5;ng <code>withAnimation</code> k&#x1EBF;</p>]]></description><link>https://makexyz.fun/video-summary-ch-4-6-flip-a-text-view-more-using-withanimation-in-swiftui-2025/</link><guid isPermaLink="false">67b35d54ca5820942839efb3</guid><category><![CDATA[SwiftUI]]></category><category><![CDATA[Swift]]></category><category><![CDATA[Video Summary]]></category><dc:creator><![CDATA[Admin]]></dc:creator><pubDate>Mon, 24 Feb 2025 13:08:31 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><h2 id="m%C3%B4-t%E1%BA%A3-nhanh">M&#xF4; t&#x1EA3; nhanh</h2>
<p>Video n&#xE0;y tr&#xEC;nh b&#xE0;y c&#xE1;ch t&#x1EA1;o hi&#x1EC7;u &#x1EE9;ng l&#x1EAD;t ch&#x1EEF; (text flip animation) trong SwiftUI b&#x1EB1;ng c&#xE1;ch s&#x1EED; d&#x1EE5;ng <code>withAnimation</code> k&#x1EBF;t h&#x1EE3;p v&#x1EDB;i <code>rotation3DEffect</code>. Ngo&#xE0;i ra, video c&#x169;ng gi&#x1EDB;i thi&#x1EC7;u m&#x1ED9;t s&#x1ED1; k&#x1EF9; thu&#x1EAD;t animation kh&#xE1;c nh&#x1B0; scale v&#xE0; fade.</p>
<h2 id="video">Video</h2>
<p>Click v&#xE0;o h&#xEC;nh d&#x1B0;&#x1EDB;i &#x111;&#x1EC3; m&#x1EDF;:<br>
<a href="https://www.youtube.com/embed/R6Ln5ucsicA"><img src="https://img.youtube.com/vi/R6Ln5ucsicA/0.jpg" alt="Ch. 4.6 Flip a Text View &amp; More using withAnimation in SwiftUI (2025)" loading="lazy"></a></p>
<h2 id="m%C3%B4-t%E1%BA%A3-chi-ti%E1%BA%BFt">M&#xF4; t&#x1EA3; chi ti&#x1EBF;t</h2>
<p>Video n&#xE0;y h&#x1B0;&#x1EDB;ng d&#x1EAB;n c&#xE1;ch t&#x1EA1;o hi&#x1EC7;u &#x1EE9;ng l&#x1EAD;t ch&#x1EEF; (text flip animation) trong SwiftUI b&#x1EB1;ng c&#xE1;ch s&#x1EED; d&#x1EE5;ng <code>withAnimation</code> v&#xE0; <code>rotation3DEffect</code>, &#x111;&#x1ED3;ng th&#x1EDD;i gi&#x1EDB;i thi&#x1EC7;u th&#xEA;m c&#xE1;c k&#x1EF9; thu&#x1EAD;t animation kh&#xE1;c nh&#x1B0; scale v&#xE0; fade.</p>
<p><a href="https://www.youtube.com/embed/R6Ln5ucsicA"><img src="https://img.youtube.com/vi/R6Ln5ucsicA/0.jpg" alt="Ch. 4.6 Flip a Text View &amp; More using withAnimation in SwiftUI (2025)" loading="lazy"></a></p>
<p>D&#x1B0;&#x1EDB;i &#x111;&#xE2;y l&#xE0; c&#xE1;c b&#x1B0;&#x1EDB;c chi ti&#x1EBF;t &#x111;&#x1EC3; th&#x1EF1;c hi&#x1EC7;n:</p>
<p><strong>1. T&#x1EA1;o hi&#x1EC7;u &#x1EE9;ng fade &#x111;&#x1A1;n gi&#x1EA3;n (Basic Animation):</strong></p>
<ul>
<li>S&#x1EED; d&#x1EE5;ng <code>.animation</code> modifier &#x111;&#x1EC3; t&#x1EA1;o hi&#x1EC7;u &#x1EE9;ng fade in cho text view khi gi&#xE1; tr&#x1ECB; thay &#x111;&#x1ED5;i.</li>
<li>S&#x1EED; d&#x1EE5;ng tham s&#x1ED1; <code>value</code> &#x111;&#x1EC3; ch&#x1EC9; &#x111;&#x1ECB;nh bi&#x1EBF;n n&#xE0;o s&#x1EBD; k&#xED;ch ho&#x1EA1;t animation (v&#xED; d&#x1EE5;: <code>resultMessage</code>).</li>
<li>V&#x1EA5;n &#x111;&#x1EC1;: N&#x1EBF;u gi&#xE1; tr&#x1ECB; kh&#xF4;ng thay &#x111;&#x1ED5;i (v&#xED; d&#x1EE5;: tung x&#xFA;c x&#x1EAF;c ra c&#xF9;ng m&#x1ED9;t s&#x1ED1;), animation s&#x1EBD; kh&#xF4;ng ch&#x1EA1;y.</li>
</ul>
<p><strong>2. T&#x1EA1;o animation trigger:</strong></p>
<ul>
<li>T&#x1EA1;o m&#x1ED9;t bi&#x1EBF;n <code>@State</code> m&#x1EDB;i ki&#x1EC3;u <code>Bool</code> (v&#xED; d&#x1EE5;: <code>animationTrigger</code>) v&#xE0; kh&#x1EDF;i t&#x1EA1;o gi&#xE1; tr&#x1ECB; ban &#x111;&#x1EA7;u l&#xE0; <code>false</code>.</li>
<li>Trong action c&#x1EE7;a button, s&#x1EED; d&#x1EE5;ng <code>.toggle()</code> &#x111;&#x1EC3; &#x111;&#x1EA3;o ng&#x1B0;&#x1EE3;c gi&#xE1; tr&#x1ECB; c&#x1EE7;a <code>animationTrigger</code> m&#x1ED7;i khi button &#x111;&#x1B0;&#x1EE3;c nh&#x1EA5;n. &#x110;i&#x1EC1;u n&#xE0;y &#x111;&#x1EA3;m b&#x1EA3;o animation lu&#xF4;n ch&#x1EA1;y, ngay c&#x1EA3; khi gi&#xE1; tr&#x1ECB; kh&#xF4;ng thay &#x111;&#x1ED5;i.</li>
<li>Thay &#x111;&#x1ED5;i gi&#xE1; tr&#x1ECB; <code>value</code> trong <code>.animation</code> modifier th&#xE0;nh <code>animationTrigger</code>.</li>
</ul>
<p><strong>3. T&#x1EA1;o hi&#x1EC7;u &#x1EE9;ng pulse (s&#x1EED; d&#x1EE5;ng onChange modifier v&#xE0; withAnimation):</strong></p>
<ul>
<li>X&#xF3;a <code>.animation</code> modifier c&#x169;.</li>
<li>S&#x1EED; d&#x1EE5;ng <code>.onChange</code> modifier &#x111;&#x1EC3; theo d&#xF5;i s&#x1EF1; thay &#x111;&#x1ED5;i c&#x1EE7;a <code>animationTrigger</code>.</li>
<li>T&#x1EA1;o m&#x1ED9;t bi&#x1EBF;n <code>@State</code> kh&#xE1;c ki&#x1EC3;u <code>Bool</code> (v&#xED; d&#x1EE5;: <code>isDoneAnimating</code>) v&#xE0; kh&#x1EDF;i t&#x1EA1;o l&#xE0; <code>true</code> (v&#xEC; khi b&#x1EAF;t &#x111;&#x1EA7;u app th&#xEC; ch&#x1B0;a c&#xF3; animation).</li>
<li>Trong block c&#x1EE7;a <code>.onChange</code>, &#x111;&#x1EB7;t <code>isDoneAnimating</code> th&#xE0;nh <code>false</code> (b&#x1EAF;t &#x111;&#x1EA7;u animation).</li>
<li>S&#x1EED; d&#x1EE5;ng <code>withAnimation</code> &#x111;&#x1EC3; t&#x1EA1;o animation:
<ul>
<li>&#x110;&#x1EB7;t <code>isDoneAnimating</code> th&#xE0;nh <code>true</code> b&#xEA;n trong <code>withAnimation</code>.</li>
<li>S&#x1EED; d&#x1EE5;ng <code>.scaleEffect</code> v&#xE0; <code>.opacity</code> modifiers v&#x1EDB;i ternary operator &#x111;&#x1EC3; thay &#x111;&#x1ED5;i k&#xED;ch th&#x1B0;&#x1EDB;c v&#xE0; &#x111;&#x1ED9; trong su&#x1ED1;t c&#x1EE7;a text view d&#x1EF1;a tr&#xEA;n gi&#xE1; tr&#x1ECB; c&#x1EE7;a <code>isDoneAnimating</code>.</li>
<li>S&#x1EED; d&#x1EE5;ng <code>.spring</code> animation &#x111;&#x1EC3; t&#x1EA1;o hi&#x1EC7;u &#x1EE9;ng n&#x1EA3;y.</li>
</ul>
</li>
</ul>
<p><strong>4. T&#x1EA1;o hi&#x1EC7;u &#x1EE9;ng l&#x1EAD;t (Flip Effect):</strong></p>
<ul>
<li>Comment ho&#x1EB7;c x&#xF3;a c&#xE1;c modifier <code>.scaleEffect</code> v&#xE0; <code>.opacity</code> &#x111;&#xE3; t&#x1EA1;o &#x1EDF; b&#x1B0;&#x1EDB;c tr&#x1B0;&#x1EDB;c.</li>
<li>S&#x1EED; d&#x1EE5;ng modifier <code>.rotation3DEffect</code>:
<ul>
<li><code>angle</code>: S&#x1EED; d&#x1EE5;ng ternary operator &#x111;&#x1EC3; x&#xE1;c &#x111;&#x1ECB;nh g&#xF3;c quay d&#x1EF1;a tr&#xEA;n <code>isDoneAnimating</code>. N&#x1EBF;u <code>true</code>, quay 360 &#x111;&#x1ED9;; n&#x1EBF;u <code>false</code>, quay 0 &#x111;&#x1ED9;.</li>
<li><code>axis</code>: &#x110;&#x1EB7;t tr&#x1EE5;c X l&#xE0; 1, tr&#x1EE5;c Y v&#xE0; Z l&#xE0; 0 &#x111;&#x1EC3; xoay quanh tr&#x1EE5;c ngang.</li>
</ul>
</li>
</ul>
<p><strong>5. S&#x1EED; d&#x1EE5;ng Interpolating Spring:</strong></p>
<ul>
<li>Thay th&#x1EBF; <code>.spring</code> b&#x1EB1;ng <code>.interpolatingSpring</code>.</li>
<li>S&#x1EED; d&#x1EE5;ng c&#xE1;c tham s&#x1ED1; nh&#x1B0; <code>duration</code> v&#xE0; <code>bounce</code> &#x111;&#x1EC3; &#x111;i&#x1EC1;u ch&#x1EC9;nh hi&#x1EC7;u &#x1EE9;ng n&#x1EA3;y.</li>
</ul>
<p>&lt;L&#x1EDD;i ch&#xFA;c&gt;<br>
Ch&#xFA;c b&#x1EA1;n th&#xE0;nh c&#xF4;ng v&#x1EDB;i nh&#x1EEF;ng animation SwiftUI tuy&#x1EC7;t v&#x1EDD;i!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>