Files
AgentHub/agenthub-vs-competitors.html
T

1707 lines
62 KiB
HTML

<!doctype html>
<!-- AgentHub vs competitors comparison deck (vi). Author: Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn> -->
<html lang="vi">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>AgentHub so với đối thủ</title>
<style>
:root {
--bg: #f6f8fc;
--bg2: #ffffff;
--card: #ffffff;
--line: #dde5f0;
--fg: #101c2e;
--mut: #55677f;
--dim: #93a3b8;
--acc: #1d6fd8;
--ok: #15a05a;
--warn: #c2760a;
--bad: #d64545;
--vio: #7c4ddb;
--accbg: #eaf2fe;
--accln: #b9d4f7;
--shadow: 0 1px 2px rgba(16, 28, 46, 0.05), 0 4px 14px rgba(16, 28, 46, 0.05);
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
}
body {
background: var(--bg);
color: var(--fg);
overflow: hidden;
font-family:
"Segoe UI",
system-ui,
-apple-system,
"Noto Sans",
Roboto,
sans-serif;
-webkit-font-smoothing: antialiased;
}
#deck {
position: relative;
width: 100vw;
height: 100vh;
}
.slide {
position: absolute;
inset: 0;
display: none;
flex-direction: column;
justify-content: center;
padding: min(4.2vh, 42px) min(5vw, 64px);
animation: in 0.28s ease;
}
.slide.on {
display: flex;
}
.slide {
overflow: hidden;
}
@keyframes in {
from {
opacity: 0;
transform: translateY(12px);
}
to {
opacity: 1;
transform: none;
}
}
.kicker {
color: var(--acc);
font-size: clamp(12px, 1.35vw, 16px);
font-weight: 700;
letter-spacing: 0.16em;
text-transform: uppercase;
margin-bottom: 14px;
}
h1 {
font-size: clamp(30px, 4.6vw, 62px);
line-height: 1.22;
font-weight: 800;
letter-spacing: -0.02em;
padding-bottom: 0.06em;
}
h2 {
font-size: clamp(24px, 3.1vw, 42px);
line-height: 1.3;
font-weight: 750;
letter-spacing: -0.015em;
margin-bottom: 18px;
padding-bottom: 0.06em;
}
.sub {
color: var(--mut);
font-size: clamp(15px, 1.7vw, 22px);
margin-top: 16px;
line-height: 1.5;
}
ul {
list-style: none;
display: flex;
flex-direction: column;
gap: 14px;
}
li {
position: relative;
padding-left: 30px;
font-size: clamp(15px, 1.75vw, 23px);
line-height: 1.45;
}
li::before {
content: "";
position: absolute;
left: 6px;
top: 0.62em;
width: 9px;
height: 9px;
border-radius: 50%;
background: var(--acc);
}
li b {
color: var(--fg);
font-weight: 700;
}
li .n {
color: var(--mut);
}
.cols {
display: grid;
grid-template-columns: 1fr 1fr;
gap: min(5vw, 56px);
align-items: center;
min-height: 0;
}
.cols.imgcols {
grid-template-columns: 1.12fr 0.88fr;
gap: min(3vw, 34px);
align-items: stretch;
flex: 1 1 auto;
min-height: 0;
grid-template-rows: minmax(0, 1fr);
}
.cols.imgcols.wide {
grid-template-columns: 0.8fr 1.2fr;
}
.cols.imgcols > * {
min-height: 0;
}
.cols.imgcols > div:first-child,
.cols.imgcols > ul {
display: flex;
flex-direction: column;
justify-content: center;
}
.txtcol {
display: flex;
flex-direction: column;
justify-content: center;
min-height: 0;
}
.txtcol > ul {
margin: 0;
}
.cols.imgcols .shotfit {
align-items: center;
}
.shotcell {
display: flex;
flex-direction: column;
min-height: 0;
height: 100%;
justify-content: center;
}
.shotfit {
flex: 0 0 auto;
min-height: 0;
display: flex;
align-items: center;
justify-content: center;
}
.cols.imgcols .shotcell .shot {
max-height: 72vh;
}
.imgrow .shotcell .shot {
max-height: 56vh;
}
.shotfit .shot {
max-height: 100%;
max-width: 100%;
width: auto;
height: auto;
}
.shot.s70 {
max-width: 70%;
max-height: 70%;
}
/* ảnh ngang: nở hết bề rộng khung, ảnh dọc giữ width:auto vì bị chặn bởi chiều cao */
.imgrow .shotfit .shot,
.cols.imgcols.wide .shotfit .shot {
width: 100%;
height: auto;
}
.cols.imgcols.wide .shotfit {
align-items: center;
}
.grid3 {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
.grid2 {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16px;
}
.card {
background: var(--card);
border: 1px solid var(--line);
border-radius: 14px;
padding: 18px 20px;
box-shadow: var(--shadow);
}
.card .t {
font-weight: 750;
font-size: clamp(14px, 1.55vw, 20px);
margin-bottom: 7px;
display: flex;
gap: 9px;
align-items: center;
}
.card .d {
color: var(--mut);
font-size: clamp(12px, 1.25vw, 16px);
line-height: 1.45;
}
.card.acc {
border-color: var(--accln);
background: var(--accbg);
}
.panel {
background: var(--bg2);
border: 1px solid var(--line);
border-radius: 16px;
padding: 22px;
font-size: clamp(12px, 1.3vw, 16px);
box-shadow: var(--shadow);
}
.mono {
font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
}
table {
width: 100%;
border-collapse: collapse;
font-size: clamp(13px, 1.4vw, 19px);
}
th,
td {
text-align: left;
padding: 13px 14px;
border-bottom: 1px solid var(--line);
vertical-align: top;
}
th {
color: var(--acc);
font-size: clamp(11px, 1.15vw, 14px);
letter-spacing: 0.1em;
text-transform: uppercase;
}
td:first-child {
font-weight: 700;
white-space: nowrap;
}
tr:last-child td {
border-bottom: none;
}
.pipe {
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
margin: 8px 0 22px;
}
.node {
padding: 8px 14px;
border-radius: 9px;
font-size: clamp(11px, 1.2vw, 15px);
border: 1px solid var(--line);
background: var(--card);
white-space: nowrap;
}
.node.d {
background: #e8f7ef;
border-color: var(--ok);
color: #0f7a45;
}
.node.c {
background: var(--accbg);
border-color: var(--acc);
color: #14559f;
font-weight: 650;
box-shadow: 0 0 0 3px rgba(29, 111, 216, 0.13);
}
.node.w {
background: #fdf4e3;
border-color: var(--warn);
color: var(--warn);
border-style: dashed;
}
.node.f {
background: #fdeeee;
border-color: var(--bad);
color: #b23333;
}
.arr {
color: var(--dim);
font-size: 13px;
}
.pipe.full {
flex-wrap: nowrap;
width: 100%;
gap: 6px;
}
.pipe.full .node {
flex: 1 1 0;
text-align: center;
white-space: normal;
padding: 11px 7px;
line-height: 1.3;
}
.pipe.full .arr {
flex: 0 0 auto;
}
.pipe.full .node small {
display: block;
color: var(--dim);
font-size: 0.8em;
font-weight: 400;
margin-top: 3px;
}
.pipe.sm {
gap: 4px;
margin: 0 0 10px;
}
.pipe.sm .node {
font-size: clamp(9px, 0.92vw, 12.5px);
padding: 8px 5px;
border-radius: 7px;
}
.pipe.sm .arr {
font-size: 10px;
}
.plab {
color: var(--acc);
font-size: clamp(10px, 1.1vw, 13px);
font-weight: 700;
letter-spacing: 0.11em;
text-transform: uppercase;
margin: 0 0 9px;
display: flex;
gap: 10px;
align-items: baseline;
}
.plab span {
color: var(--mut);
font-weight: 400;
letter-spacing: 0;
text-transform: none;
font-size: 0.95em;
}
.yes {
color: var(--ok);
font-size: 1.15em;
font-weight: 700;
}
.soon {
color: var(--dim);
font-style: italic;
}
/* ---------- ảnh chụp màn hình ---------- */
.shot {
display: block;
border: 1px solid var(--line);
border-radius: 12px;
box-shadow:
0 2px 6px rgba(16, 28, 46, 0.1),
0 12px 34px rgba(16, 28, 46, 0.1);
background: #0b0f17;
width: 100%;
max-width: 100%;
height: auto;
margin: 0 auto;
}
.shotbox {
margin-top: 16px;
display: flex;
justify-content: center;
min-height: 0;
}
.shotbox {
flex: 1 1 auto;
min-height: 0;
}
.shotbox .shot {
max-height: 100%;
max-width: 100%;
width: auto;
height: auto;
}
.imgrow {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin-top: 16px;
align-items: stretch;
flex: 1 1 auto;
min-height: 0;
grid-template-rows: minmax(0, 1fr);
}
.imgrow > * {
min-height: 0;
}
.cap {
color: var(--dim);
font-size: clamp(10px, 1.02vw, 12.5px);
text-align: center;
margin-top: 6px;
line-height: 1.35;
}
.vio {
border-color: var(--vio) !important;
color: #5b32ab;
}
.hl {
color: #14559f;
}
.dot.grey {
background: #aab8c9;
}
/* ---------- dark mode ---------- */
body.dark {
--bg: #0b0f17;
--bg2: #111827;
--card: #151d2b;
--line: #233046;
--fg: #e8eef8;
--mut: #93a4bd;
--dim: #64748b;
--acc: #4f9cf9;
--ok: #34d399;
--warn: #fbbf24;
--bad: #f87171;
--vio: #a78bfa;
--accbg: #15233a;
--accln: #2d4d78;
--shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
}
body.dark .vio {
color: #ddd6fe;
}
body.dark .hl {
color: #cfe2ff;
}
body.dark .note b {
color: #cfe2ff;
}
body.dark .tag.on {
color: #cfe2ff;
}
body.dark .dot.grey {
background: #374151;
}
body.dark .node.d {
background: rgba(52, 211, 153, 0.13);
color: #a7f3d0;
}
body.dark .node.c {
background: rgba(79, 156, 249, 0.16);
color: #bfdbfe;
}
body.dark .node.w {
background: rgba(251, 191, 36, 0.12);
color: #fde68a;
}
body.dark .node.f {
background: rgba(248, 113, 113, 0.13);
color: #fecaca;
}
body.dark .term {
background: #05080e;
}
body.dark .term .bar {
background: #0d1420;
}
body.dark .term .bar i {
background: #374151;
}
body.dark .term .b {
color: #d5e3f5;
}
body.dark .note.w {
background: rgba(251, 191, 36, 0.08);
}
body.dark .note.g {
background: rgba(52, 211, 153, 0.08);
}
body.dark #grid {
background: rgba(6, 9, 15, 0.97);
}
body.dark #notes {
box-shadow: none;
}
.pipe.full .node.c {
box-shadow: 0 0 0 3px rgba(29, 111, 216, 0.13);
}
.legend {
display: flex;
flex-direction: column;
gap: 11px;
}
.lg {
display: flex;
gap: 12px;
align-items: flex-start;
font-size: clamp(13px, 1.45vw, 19px);
}
.dot {
width: 15px;
height: 15px;
border-radius: 4px;
flex: 0 0 auto;
margin-top: 0.24em;
}
.term {
background: #f1f5fa;
border: 1px solid var(--line);
border-radius: 12px;
overflow: hidden;
box-shadow: var(--shadow);
font-family: ui-monospace, Consolas, monospace;
font-size: clamp(11px, 1.2vw, 15px);
}
.term .bar {
background: #e4ebf4;
padding: 8px 13px;
color: var(--mut);
border-bottom: 1px solid var(--line);
display: flex;
gap: 7px;
align-items: center;
font-size: 12px;
}
.term .bar i {
width: 10px;
height: 10px;
border-radius: 50%;
background: #c3cfdd;
display: inline-block;
}
.term .b {
padding: 15px;
line-height: 1.75;
color: #1b2b40;
}
.term .g,
.panel .g {
color: var(--ok);
font-weight: 600;
}
.term .y,
.panel .y {
color: var(--warn);
font-weight: 600;
}
.term .m {
color: var(--dim);
}
.term .a {
color: var(--acc);
font-weight: 600;
}
.tags {
display: flex;
flex-wrap: wrap;
gap: 9px;
margin-top: 6px;
}
.tag {
background: var(--bg2);
border: 1px solid var(--line);
border-radius: 999px;
padding: 7px 15px;
font-size: clamp(11px, 1.2vw, 15px);
color: var(--mut);
}
.tag.on {
border-color: var(--accln);
background: var(--accbg);
color: #14559f;
}
.note {
margin-top: 22px;
padding: 15px 18px;
border-left: 3px solid var(--acc);
background: var(--accbg);
border-radius: 0 10px 10px 0;
color: var(--mut);
font-size: clamp(13px, 1.4vw, 18px);
line-height: 1.5;
}
.note b {
color: #14559f;
}
.note.w {
border-color: var(--warn);
background: #fdf4e3;
}
.note.g {
border-color: var(--ok);
background: #e8f7ef;
}
.quote {
font-size: clamp(26px, 3.9vw, 54px);
font-weight: 800;
line-height: 1.38;
letter-spacing: -0.015em;
padding-bottom: 0.08em;
}
.center {
align-items: center;
text-align: center;
justify-content: center;
}
.center .sub {
max-width: 760px;
}
.center ul {
align-items: flex-start;
text-align: left;
}
/* chrome */
#bar {
position: fixed;
left: 0;
top: 0;
height: 3px;
background: var(--acc);
z-index: 40;
transition: width 0.25s;
}
#hud button:active {
transform: translateY(1px);
}
#hud {
position: fixed;
right: 20px;
bottom: 16px;
display: flex;
gap: 9px;
align-items: center;
z-index: 40;
color: var(--dim);
font-size: 12px;
}
#hud button {
background: var(--bg2);
border: 1px solid var(--line);
color: var(--mut);
box-shadow: var(--shadow);
border-radius: 8px;
padding: 6px 11px;
font-size: 12px;
cursor: pointer;
font-family: inherit;
}
#hud button:hover {
color: var(--acc);
border-color: var(--acc);
}
#num {
font-variant-numeric: tabular-nums;
}
#notes {
position: fixed;
left: 0;
right: 0;
bottom: 0;
max-height: 42vh;
overflow: auto;
z-index: 50;
background: var(--bg2);
border-top: 1px solid var(--line);
padding: 20px 26px;
display: none;
box-shadow: 0 -6px 24px rgba(16, 28, 46, 0.08);
}
#notes.on {
display: block;
}
#notes h4 {
color: var(--acc);
font-size: 12px;
letter-spacing: 0.14em;
text-transform: uppercase;
margin-bottom: 9px;
}
#notes p {
color: var(--mut);
font-size: 15px;
line-height: 1.65;
max-width: 1100px;
}
#grid {
position: fixed;
inset: 0;
z-index: 60;
background: rgba(246, 248, 252, 0.97);
overflow: auto;
padding: 34px;
display: none;
grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
gap: 14px;
align-content: start;
}
#grid.on {
display: grid;
}
.gi {
background: var(--bg2);
border: 1px solid var(--line);
border-radius: 11px;
padding: 15px;
cursor: pointer;
box-shadow: var(--shadow);
}
.gi:hover {
border-color: var(--acc);
}
.gi .i {
color: var(--dim);
font-size: 11px;
margin-bottom: 6px;
}
.gi .tt {
font-size: 14px;
font-weight: 650;
line-height: 1.35;
}
@media (max-width: 820px) {
.cols,
.grid3,
.grid2 {
grid-template-columns: 1fr;
gap: 16px;
}
.slide {
padding: 26px 22px;
}
#hud {
right: 10px;
bottom: 10px;
}
}
/* ---------- bổ sung cho deck so sánh ---------- */
.stats {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 14px;
margin-top: 22px;
}
.stat {
background: var(--card);
border: 1px solid var(--line);
border-radius: 14px;
padding: 16px 18px;
box-shadow: var(--shadow);
}
.stat .v {
font-size: clamp(22px, 2.8vw, 38px);
font-weight: 800;
letter-spacing: -0.02em;
color: var(--acc);
}
.stat .l {
color: var(--mut);
font-size: clamp(11px, 1.15vw, 15px);
margin-top: 4px;
line-height: 1.35;
}
table.cmp {
font-size: clamp(11.5px, 1.18vw, 16px);
}
table.cmp th,
table.cmp td {
padding: 9px 11px;
}
table.cmp th.me,
table.cmp td.me {
background: var(--accbg);
}
table.cmp td.me {
font-weight: 650;
}
.y {
color: var(--ok);
font-weight: 800;
}
.x {
color: var(--bad);
font-weight: 800;
}
.p {
color: var(--warn);
font-weight: 800;
}
.q {
color: var(--dim);
font-weight: 700;
}
.sm {
color: var(--mut);
font-weight: 400;
font-size: 0.86em;
}
.quad {
display: grid;
grid-template-columns: auto 1fr 1fr;
grid-template-rows: 1fr 1fr auto;
gap: 12px;
flex: 1 1 auto;
min-height: 0;
max-height: 62vh;
}
.quad .ax {
color: var(--dim);
font-size: clamp(11px, 1.1vw, 14px);
display: flex;
flex-direction: column;
justify-content: space-between;
text-align: right;
padding: 6px 4px;
grid-row: 1 / span 2;
border-right: 2px solid var(--line);
}
.quad .axx {
grid-column: 2 / span 2;
display: flex;
justify-content: space-between;
color: var(--dim);
font-size: clamp(11px, 1.1vw, 14px);
border-top: 2px solid var(--line);
padding-top: 6px;
}
.qc {
border: 1px solid var(--line);
border-radius: 14px;
padding: 14px 18px;
background: var(--card);
display: flex;
flex-direction: column;
gap: 8px;
}
.qc .qt {
color: var(--mut);
font-weight: 700;
font-size: clamp(12px, 1.3vw, 17px);
margin-bottom: 4px;
}
.qc .it {
display: flex;
align-items: center;
gap: 10px;
font-size: clamp(13px, 1.45vw, 19px);
}
.qc .it::before {
content: "";
width: 11px;
height: 11px;
border-radius: 50%;
background: var(--dim);
flex: 0 0 auto;
}
.qc.hot {
background: var(--accbg);
border-color: var(--acc);
border-width: 2px;
}
.qc.hot .it {
font-weight: 800;
font-size: clamp(16px, 1.9vw, 26px);
}
.qc.hot .it::before {
width: 16px;
height: 16px;
background: var(--acc);
}
.qc .empty {
color: var(--dim);
font-style: italic;
font-size: clamp(12px, 1.25vw, 16px);
}
.src {
color: var(--dim);
font-size: clamp(10px, 1vw, 12.5px);
margin-top: 10px;
line-height: 1.4;
}
.src a {
color: inherit;
}
.qa {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 14px;
}
.qa .card .t {
font-size: clamp(13px, 1.4vw, 18px);
}
@media (max-width: 820px) {
.stats,
.qa {
grid-template-columns: 1fr 1fr;
}
}
</style>
</head>
<body>
<div id="bar"></div>
<div id="deck">
<!-- 1 -->
<section
class="slide center"
data-t="Trang bìa"
data-n="Em xin cảm ơn sếp và các anh chị đã dành thời gian. Hôm nay em không đi lại từng chức năng của AgentHub như buổi trước, mà đặt nó cạnh các công cụ cùng loại đang được nói tới nhiều nhất - Claude Desktop, Codex app và Orca - để trả lời một câu hỏi thẳng: team mình có nên dùng AgentHub không, và dùng nó vào việc gì. Em sẽ nói cả chỗ AgentHub hơn lẫn chỗ nó thua."
>
<div class="kicker">SmartGift R&amp;D · Nội bộ</div>
<h1>AgentHub giữa các công cụ AI coding</h1>
<div class="sub" style="max-width: 860px">
So sánh với <b>Claude Desktop · Codex app · Orca</b> và vài công cụ khác<br />AgentHub
hơn ở đâu, thua ở đâu, và nên dùng vào việc gì
</div>
<div class="tags" style="justify-content: center; margin-top: 26px">
<span class="tag on">v2.8.32</span><span class="tag">Số liệu tại 28/10/2026</span
><span class="tag">Nói cả điểm yếu</span>
</div>
</section>
<!-- 2 -->
<section
class="slide"
data-t="Vấn đề"
data-n="Bắt đầu từ vấn đề. Khi mỗi người chạy ba, bốn agent cùng lúc, câu hỏi không còn là 'AI viết code có tốt không' nữa, mà là bốn câu này. Agent nào đang đứng chờ mình bấm phê duyệt? Hôm nay cả team đã tiêu bao nhiêu tiền, model nào ăn nhiều nhất? Agent đã sửa những file nào, có đụng vào thứ không nên đụng không? Và tài khoản Claude nào sắp hết quota, ai đang dùng tài khoản nào? Mỗi công cụ em sắp so sánh trả lời được một phần trong bốn câu này. Câu hỏi là có công cụ nào trả lời được cả bốn, cho cả team, không."
>
<div class="kicker">Bối cảnh</div>
<h2>Chạy nhiều agent song song thì mất dấu</h2>
<div class="grid2">
<div class="card">
<div class="t">⏳ Agent nào đang chờ mình?</div>
<div class="d">Bốn terminal, hai cái đang đứng chờ phê duyệt mà không ai để ý</div>
</div>
<div class="card">
<div class="t">💸 Cả team đã tiêu bao nhiêu?</div>
<div class="d">Theo người, theo dự án, theo model - không phải đợi hoá đơn cuối tháng</div>
</div>
<div class="card">
<div class="t">📝 Agent đã sửa những gì?</div>
<div class="d">File nào, hunk nào, gọi những tool nào, subagent nào sinh ra</div>
</div>
<div class="card">
<div class="t">🔑 Tài khoản nào sắp hết quota?</div>
<div class="d">Ai đang dùng tài khoản nào, đổi sang tài khoản khác thế nào</div>
</div>
</div>
<div class="note">
Mỗi công cụ trả lời được <b>một phần</b> bốn câu này. Câu hỏi của hôm nay: có công cụ nào
trả lời <b>cả bốn, cho cả team</b>?
</div>
</section>
<!-- 3 -->
<section
class="slide"
data-t="AgentHub hôm nay"
data-n="Nhắc nhanh AgentHub hôm nay là gì cho ai chưa dùng. Ba việc: quan sát - mọi thứ agent làm đều được ghi lại và tìm lại được; điều khiển - chạy Claude, Codex và các AI tool khác bằng terminal thật ngay trên trình duyệt; cấu hình - plugin, skill, MCP, tài khoản, proxy. Một nguyên tắc em muốn mọi người nhớ: AgentHub ghi nhận và hiển thị, nó không tự điều phối, không tự chạy agent thay mình. Mấy con số ở dưới để mọi người hình dung độ chín: khoảng hai trăm nghìn dòng code, gần năm nghìn test case, hơn trăm bản phát hành, riêng tháng vừa rồi hơn hai trăm commit."
>
<div class="kicker">Tổng quan</div>
<h2>AgentHub hôm nay</h2>
<div class="grid3">
<div class="card acc">
<div class="t">🔭 Quan sát</div>
<div class="d">
Session, tool call, cây subagent, transcript, token và chi phí - ghi lại và tìm lại được
</div>
</div>
<div class="card acc">
<div class="t">🎮 Điều khiển</div>
<div class="d">
Claude, Codex, Antigravity, Cursor, omp chạy bằng <b>terminal thật</b> ngay trên trình duyệt
</div>
</div>
<div class="card acc">
<div class="t">⚙️ Cấu hình</div>
<div class="d">Plugin, skill, MCP, hook, tài khoản, AI Proxy - bằng chuột, không cần nhớ lệnh</div>
</div>
</div>
<div class="stats">
<div class="stat"><div class="v">~200k</div><div class="l">dòng code (server + client)</div></div>
<div class="stat"><div class="v">~4.750</div><div class="l">test case trong 430 file test</div></div>
<div class="stat"><div class="v">~410</div><div class="l">API route, CLI <span class="mono">agenthub</span> làm được tất cả</div></div>
<div class="stat"><div class="v">100+</div><div class="l">bản phát hành từ 29/07/2026</div></div>
<div class="stat"><div class="v">205</div><div class="l">commit trong 30 ngày qua</div></div>
</div>
<div class="note g">
Nguyên tắc: AgentHub <b>ghi nhận và hiển thị, không điều phối</b>. Phiên AI đang chạy mới là
nơi ra quyết định.
</div>
</section>
<!-- 4 -->
<section
class="slide"
data-t="Các đối thủ"
data-n="Đây là những cái tên em đem ra so. Chia làm hai nhóm. Nhóm thứ nhất là app của chính hãng làm model: Claude Desktop của Anthropic, Codex app của OpenAI - rất trau chuốt, nhưng mỗi app chỉ chạy agent của hãng mình. Nhóm thứ hai là công cụ độc lập chạy được nhiều agent, mỗi agent một git worktree: Orca là cái nổi nhất - mã nguồn mở, miễn phí, chạy hơn hai mươi bảy CLI agent, có cả app điện thoại, và đang tăng sao GitHub rất nhanh. Conductor thì đẹp nhưng chỉ có trên Mac và đóng mã. Claude Squad là bản chạy trong terminal. Điểm chung của cả năm: chúng đều là app chạy trên máy từng người. Không có cái nào là web app tự host cho cả team. Vibe Kanban và Crystal em không đưa vào vì một cái đang ngừng phát triển thương mại, một cái đã ngừng từ tháng hai."
>
<div class="kicker">Thị trường</div>
<h2>Ai đang làm cùng việc này</h2>
<table class="cmp">
<tr>
<th>Công cụ</th>
<th>Của ai</th>
<th>Dạng</th>
<th>Nền tảng</th>
<th>Giấy phép / giá</th>
<th>Agent chạy được</th>
</tr>
<tr>
<td class="me">AgentHub</td>
<td class="me">SmartGift</td>
<td class="me">Web app tự host + CLI, PWA</td>
<td class="me">Linux · macOS<span class="sm"> (chưa thử máy thật)</span> · WSL2</td>
<td class="me">Nội bộ, miễn phí</td>
<td class="me">Claude, Codex, Antigravity, Cursor, omp</td>
</tr>
<tr>
<td>Claude Desktop</td>
<td>Anthropic</td>
<td>App desktop</td>
<td>macOS, Windows, Linux (beta)</td>
<td>Cần gói Claude</td>
<td>Chỉ Claude</td>
</tr>
<tr>
<td>Codex app</td>
<td>OpenAI</td>
<td>App desktop (trong ChatGPT)</td>
<td>macOS, Windows</td>
<td>Cần gói ChatGPT</td>
<td>Chỉ Codex</td>
</tr>
<tr>
<td>Orca</td>
<td>Stably AI</td>
<td>App desktop + mobile</td>
<td>macOS, Windows, Linux, iOS, Android</td>
<td>MIT, miễn phí</td>
<td>27+ CLI agent</td>
</tr>
<tr>
<td>Conductor</td>
<td>Melty Labs</td>
<td>App desktop</td>
<td>macOS</td>
<td>Đóng; Pro ~50 USD/tháng</td>
<td>Claude, Codex, Cursor, OpenCode</td>
</tr>
<tr>
<td>Claude Squad</td>
<td>Cộng đồng</td>
<td>TUI trong tmux</td>
<td>Mọi nơi có tmux</td>
<td>AGPL-3.0, miễn phí</td>
<td>Claude, Codex, Gemini, Aider</td>
</tr>
</table>
<div class="note">
Cả năm đối thủ đều là <b>app chạy trên máy từng người</b>. Không cái nào là web app tự host
cho cả team.
</div>
</section>
<!-- 5 -->
<section
class="slide"
data-t="So sánh 1/2 · Agent &amp; phiên"
data-n="Giờ so từng tính năng, chia hai slide. Slide này là phần lái agent. Hàng đầu: chạy nhiều AI tool - Claude Desktop và Codex app không làm được, Orca làm tốt nhất với hơn hai mươi bảy agent. Hàng hai: chạy đúng giao diện terminal gốc của CLI - đây là chỗ AgentHub và Orca giống nhau, còn app chính hãng thì có giao diện chat riêng. Hàng ba là điểm em muốn nhấn: phiên của AgentHub nằm trong tmux, nên đóng trình duyệt, restart dashboard, thậm chí update AgentHub đều không giết phiên. Chỗ AgentHub thua rõ: browser preview - Claude Desktop và Orca cho agent tự mở trang web để kiểm tra, AgentHub chưa có. Dấu hỏi là chỗ nguồn không nói, em chưa dám khẳng định."
>
<div class="kicker">So sánh tính năng · 1/2</div>
<h2>Lái agent và giữ phiên</h2>
<table class="cmp">
<tr>
<th>Tiêu chí</th>
<th class="me">AgentHub</th>
<th>Claude Desktop</th>
<th>Codex app</th>
<th>Orca</th>
</tr>
<tr>
<td>Nhiều AI tool, một giao diện</td>
<td class="me"><span class="y">✓</span> 5 tool</td>
<td><span class="x">✗</span></td>
<td><span class="x">✗</span></td>
<td><span class="y">✓</span> 27+</td>
</tr>
<tr>
<td>Đúng TUI gốc của CLI</td>
<td class="me"><span class="y">✓</span> tmux, attach được từ máy</td>
<td><span class="p">●</span> chat riêng + terminal phụ</td>
<td><span class="x">✗</span> chat riêng</td>
<td><span class="y">✓</span></td>
</tr>
<tr>
<td>Phiên sống khi đóng app / update</td>
<td class="me"><span class="y">✓</span> chỉ Quit mới đóng</td>
<td><span class="p">●</span> với Cloud session</td>
<td><span class="p">●</span> với cloud task</td>
<td><span class="q">?</span></td>
</tr>
<tr>
<td>Mở từ máy khác / điện thoại</td>
<td class="me"><span class="y">✓</span> mọi trình duyệt, PWA</td>
<td><span class="y">✓</span> Remote Control, app mobile</td>
<td><span class="q">?</span></td>
<td><span class="y">✓</span> app iOS / Android</td>
</tr>
<tr>
<td>Worktree riêng mỗi phiên</td>
<td class="me"><span class="y">✓</span></td>
<td><span class="y">✓</span></td>
<td><span class="y">✓</span></td>
<td><span class="y">✓</span></td>
</tr>
<tr>
<td>Browser preview cho agent</td>
<td class="me"><span class="x">✗</span></td>
<td><span class="y">✓</span> kèm iOS Simulator</td>
<td><span class="q">?</span></td>
<td><span class="y">✓</span> design mode</td>
</tr>
</table>
<div class="src">
<span class="y">✓</span> có · <span class="p">●</span> một phần · <span class="x">✗</span> không ·
<span class="q">?</span> nguồn không nói - cần kiểm lại
</div>
</section>
<!-- 6 -->
<section
class="slide"
data-t="So sánh 2/2 · Team &amp; chi phí"
data-n="Slide thứ hai là phần quản lý, và đây là chỗ AgentHub tách hẳn ra. Chi phí: AgentHub cho xem token và tiền theo model, theo phiên, theo người, có ngân sách và cảnh báo, và từ bản 2.8.31 có cả quota chi tiêu cho từng người: dùng hết là không mở được phiên mới, prompt gửi vào bị từ chối. App chính hãng chỉ cho xem hạn mức gói của mình, Orca xem được hạn mức Claude và Codex. Lịch sử: AgentHub import toàn bộ lịch sử cũ, kéo được từ máy khác qua SSH. Nhiều người dùng chung một server có phân quyền thì chỉ AgentHub có. Pool tài khoản thì Orca có đổi nhanh tài khoản Codex, AgentHub chia được tài khoản Claude, Codex, Cursor theo nhóm. Ngược lại, hai hàng cuối AgentHub không có: chạy theo lịch và cloud. Chạy theo lịch là cố ý - AgentHub không điều phối. Cloud thì với team mình, server chung chính là cloud tự host."
>
<div class="kicker">So sánh tính năng · 2/2</div>
<h2>Git, chi phí và làm việc theo team</h2>
<table class="cmp">
<tr>
<th>Tiêu chí</th>
<th class="me">AgentHub</th>
<th>Claude Desktop</th>
<th>Codex app</th>
<th>Orca</th>
</tr>
<tr>
<td>Git trong giao diện</td>
<td class="me"><span class="y">✓</span> 22 thao tác, commit theo hunk</td>
<td><span class="y">✓</span> PR, CI, auto-fix, auto-merge</td>
<td><span class="y">✓</span></td>
<td><span class="y">✓</span> PR, CI, GitHub + Linear</td>
</tr>
<tr>
<td>Token &amp; chi phí</td>
<td class="me"><span class="y">✓</span> theo người, ngân sách, cảnh báo, quota chặn</td>
<td><span class="p">●</span> hạn mức gói</td>
<td><span class="p">●</span> hạn mức gói</td>
<td><span class="p">●</span> hạn mức, giờ reset</td>
</tr>
<tr>
<td>Lịch sử &amp; phân tích phiên</td>
<td class="me"><span class="y">✓</span> import cũ, SSH, báo cáo</td>
<td><span class="p">●</span> danh sách phiên</td>
<td><span class="p">●</span> danh sách thread</td>
<td><span class="q">?</span></td>
</tr>
<tr>
<td>Nhiều người, một server</td>
<td class="me"><span class="y">✓</span> vai trò, audit log</td>
<td><span class="x">✗</span> mỗi người một máy</td>
<td><span class="x">✗</span> mỗi người một máy</td>
<td><span class="x">✗</span></td>
</tr>
<tr>
<td>Pool tài khoản, AI Proxy</td>
<td class="me"><span class="y">✓</span> Claude, Codex, Cursor</td>
<td><span class="x">✗</span></td>
<td><span class="x">✗</span></td>
<td><span class="p">●</span> đổi tài khoản Codex</td>
</tr>
<tr>
<td>Chạy theo lịch</td>
<td class="me"><span class="x">✗</span> <span class="sm">cố ý</span></td>
<td><span class="y">✓</span> scheduled tasks</td>
<td><span class="y">✓</span> Automations</td>
<td><span class="x">✗</span></td>
</tr>
<tr>
<td>Cloud / SSH</td>
<td class="me"><span class="p">●</span> server chung tự host</td>
<td><span class="y">✓</span> Cloud + SSH</td>
<td><span class="y">✓</span> Cloud</td>
<td><span class="y">✓</span> SSH</td>
</tr>
</table>
</section>
<!-- 7 -->
<section
class="slide"
data-t="Định vị"
data-n="Gom hai bảng lại thành một hình. Trục dọc là chạy được một hãng hay nhiều AI tool. Trục ngang là công cụ cho từng người trên từng máy, hay cho cả team trên một server. Claude Desktop và Codex app nằm góc dưới trái: chính hãng, mỗi người một máy. Orca, Conductor, Claude Squad nằm góc trên trái: nhiều agent nhưng vẫn mỗi người một máy. Góc trên phải - nhiều AI tool, dùng chung cho cả team - hiện chỉ có AgentHub. Vì vậy em không định vị AgentHub là đối thủ trực diện của Claude Desktop hay Orca về độ bóng bẩy, mà là thứ dùng song song, ở tầng team. Vị trí trong từng ô không mang ý nghĩa gì."
>
<div class="kicker">Định vị</div>
<h2>Chỉ AgentHub vừa nhiều agent, vừa cho cả team</h2>
<div class="quad">
<div class="ax"><span>Nhiều AI tool</span><span>Một hãng</span></div>
<div class="qc">
<div class="qt">Nhiều agent, mỗi người một máy</div>
<div class="it">Orca</div>
<div class="it">Conductor</div>
<div class="it">Claude Squad</div>
</div>
<div class="qc hot">
<div class="qt">Trạm điều khiển chung cho team</div>
<div class="it">AgentHub</div>
</div>
<div class="qc">
<div class="qt">App chính hãng, mỗi người một máy</div>
<div class="it">Claude Desktop</div>
<div class="it">Codex app</div>
</div>
<div class="qc">
<div class="qt">Một hãng, dùng chung</div>
<div class="empty">Chưa có công cụ nào trong danh sách</div>
</div>
<div class="axx"><span>Từng người, từng máy</span><span>Cả team trên một server →</span></div>
</div>
</section>
<!-- 8 -->
<section
class="slide"
data-t="6 điểm nổi bật"
data-n="Sáu điểm AgentHub nổi bật, và cả sáu đều đã có trong code hôm nay, không phải lời hứa. Một, một màn hình cho mọi agent mà vẫn là terminal gốc - mọi slash command, skill, plugin chạy y như trên máy. Hai, phiên không chết: chỉ lệnh Quit mới đóng, pane chết giữa chừng thì có hộp thoại gợi ý resume. Ba, nhìn thấy chi phí. Bốn, cả team dùng chung một server, dev chỉ cần trình duyệt. Năm, pool tài khoản và AI Proxy. Sáu, an toàn mặc định - và em nhấn mạnh chữ 'ở server': nút bị mờ trên giao diện chỉ là phép lịch sự, chỗ thật sự chặn là server."
>
<div class="kicker">Điểm mạnh</div>
<h2>6 điểm AgentHub nổi bật</h2>
<div class="grid3">
<div class="card acc">
<div class="t">1 · Mọi agent, đúng TUI gốc</div>
<div class="d">
5 AI tool trong tmux thật. Trình duyệt và <span class="mono">tmux attach</span> là hai cửa sổ
vào cùng một phiên
</div>
</div>
<div class="card acc">
<div class="t">2 · Phiên không chết</div>
<div class="d">
Đóng tab, restart, update đều giữ pane. Pane chết thì có hộp thoại <b>Resume interrupted
sessions</b>
</div>
</div>
<div class="card acc">
<div class="t">3 · Thấy chi phí</div>
<div class="d">Theo model, phiên, workspace, người · ngân sách · cảnh báo · quota theo người · Prometheus</div>
</div>
<div class="card acc">
<div class="t">4 · Một server cho cả team</div>
<div class="d">
Đăng nhập, vai trò admin / developer / analyst, audit log; mỗi người một tài khoản Linux
</div>
</div>
<div class="card acc">
<div class="t">5 · Pool tài khoản &amp; AI Proxy</div>
<div class="d">
Chia tài khoản Claude / Codex / Cursor theo nhóm (kéo thả), mỗi người tự chọn, gói Claude đúng như Anthropic báo, proxy theo phiên
</div>
</div>
<div class="card acc">
<div class="t">6 · An toàn, chặn ở server</div>
<div class="d">
<span class="mono">pull --ff-only</span>, không rebase / hard reset, không sửa commit đã push,
xoá file vào thùng rác 7 ngày
</div>
</div>
</div>
</section>
<!-- 9 -->
<section
class="slide"
data-t="Chi phí: lợi thế rõ nhất"
data-n="Em dành riêng một slide cho chi phí vì đây là lợi thế dễ thấy nhất với sếp. Phía Anthropic, muốn xem chi phí theo từng người thì phải ở gói Team hoặc Enterprise mới có spend report, hoặc tự dựng OpenTelemetry để đẩy số liệu về hệ thống giám sát của mình. Claude Desktop thì chỉ cho xem context và hạn mức gói. AgentHub có sẵn, ngay khi cài: đọc chính file transcript của Claude Code và Codex trên ổ đĩa, tính token và tiền theo bảng giá sửa được, chia theo người, theo dự án, theo model, có ngân sách theo ngày và cảnh báo bắn ra webhook. Mới nhất là quota theo người: admin đặt hạn mức tiền cho từng người, ai dùng hết thì không mở được phiên mới và prompt gửi vào bị từ chối - tức là không chỉ thấy, mà còn chặn được. Lưu ý: đây là chi phí ước tính theo bảng giá, giống chính Anthropic cũng ghi số trên console là ước tính - số thật vẫn là hoá đơn."
>
<div class="cols" style="align-items: start">
<div class="txtcol">
<div class="kicker">Lợi thế rõ nhất</div>
<h2>Biết tiền đi đâu, ngay khi cài</h2>
<ul>
<li>Token và tiền <b>theo người · dự án · model · phiên</b></li>
<li>Bảng giá <b>sửa được</b>, tính cả cache và fast mode</li>
<li><b>Ngân sách</b> theo kỳ, mỗi ngưỡng bắn cảnh báo một lần</li>
<li><b>Quota theo người</b>: hết hạn mức thì không mở phiên mới, prompt bị từ chối</li>
<li>Cảnh báo ra <b>feed, webhook, push</b> · số liệu ra Prometheus / Grafana</li>
<li>Import cả <b>lịch sử cũ</b>, không bao giờ đếm trùng token</li>
</ul>
</div>
<div>
<div class="plab">Các lựa chọn khác <span>để xem chi phí theo người</span></div>
<div class="card" style="margin-bottom: 12px">
<div class="t">Anthropic Team / Enterprise</div>
<div class="d">Spend report theo người (Team), Analytics API (Enterprise) - cần đúng gói</div>
</div>
<div class="card" style="margin-bottom: 12px">
<div class="t">OpenTelemetry tự dựng</div>
<div class="d">Làm được trên mọi gói, nhưng phải tự dựng collector và dashboard</div>
</div>
<div class="card">
<div class="t">Claude Desktop / Codex app / Orca</div>
<div class="d">Chỉ hạn mức gói của chính người dùng, không tổng hợp cho team</div>
</div>
</div>
</div>
<div class="note w">
Chi phí của AgentHub là <b>ước tính theo bảng giá</b> - như chính console của Anthropic. Số
thật vẫn là hoá đơn.
</div>
</section>
<!-- 10 -->
<section
class="slide"
data-t="Thua ở đâu"
data-n="Giờ đến phần em muốn nói thẳng: AgentHub thua ở đâu. Hai điểm lớn nhất là browser preview và PR với CI trong giao diện - Claude Desktop và Orca có vòng 'agent tự kiểm tra trên trình duyệt rồi tự mở PR', AgentHub thì dừng ở push, PR vẫn làm bằng gh trong terminal. Chạy theo lịch và cloud thì như em nói, một cái là cố ý, một cái server chung đã thay. Ít agent hơn Orca thì thêm một agent chỉ cần một file catalog. Cài đặt nặng hơn app desktop - nhưng nếu dùng server chung thì dev không phải cài gì. Và giao diện chưa bóng bẩy bằng sản phẩm thương mại - đổi lại là sửa theo góp ý của mọi người rất nhanh."
>
<div class="kicker">Nói thẳng</div>
<h2>AgentHub thua ở đâu</h2>
<table class="cmp">
<tr>
<th>Khoảng trống</th>
<th>Ai đã có</th>
<th>Ảnh hưởng</th>
<th>Cách trả lời</th>
</tr>
<tr>
<td>Browser preview cho agent</td>
<td>Claude Desktop, Orca</td>
<td><span class="x">Cao</span> <span class="sm">với frontend</span></td>
<td>Chưa có; agent vẫn dùng Playwright / MCP trong pane</td>
</tr>
<tr>
<td>PR &amp; CI trong giao diện</td>
<td>Claude Desktop, Orca</td>
<td><span class="x">Cao</span></td>
<td>Git dừng ở push; PR làm bằng <span class="mono">gh</span> trong pane</td>
</tr>
<tr>
<td>Chạy theo lịch, automation</td>
<td>Codex app, Claude Desktop</td>
<td><span class="p">Vừa</span></td>
<td>Cố ý: AgentHub ghi nhận, không điều phối</td>
</tr>
<tr>
<td>Cloud environment</td>
<td>Claude Desktop, Codex, Conductor</td>
<td><span class="y">Thấp</span></td>
<td>Server chung chính là cloud tự host của team</td>
</tr>
<tr>
<td>Ít agent hơn (5 so với 27+)</td>
<td>Orca</td>
<td><span class="y">Thấp</span></td>
<td>Thêm agent = một file catalog JSON</td>
</tr>
<tr>
<td>Cài nặng: Node, git, tmux; Windows qua WSL2</td>
<td>App desktop cài một cú</td>
<td><span class="p">Vừa</span></td>
<td>Dùng server chung: dev chỉ cần trình duyệt</td>
</tr>
<tr>
<td>Giao diện chưa bóng bẩy</td>
<td>Tất cả</td>
<td><span class="p">Vừa</span></td>
<td>Đổi lại: sửa theo góp ý nội bộ trong vài ngày</td>
</tr>
</table>
</section>
<!-- 11 -->
<section
class="slide"
data-t="Nên dùng cái nào"
data-n="Vậy kết luận thực tế cho team mình: không cần chọn một bỏ một. Làm frontend, cần agent tự mở trình duyệt kiểm tra, hay cần tạo PR rồi theo dõi CI ngay trong app - dùng Claude Desktop. Muốn chạy thật nhiều loại agent khác nhau trên laptop cá nhân - Orca là lựa chọn miễn phí tốt. Còn những gì cần ở tầng team - chạy trên server chung, biết chi phí của cả team, chia tài khoản, giữ lịch sử và phân quyền - đó là chỗ của AgentHub. Và vì AgentHub đọc transcript của chính Claude Code, phiên chạy bằng Claude Desktop trên server cũng vẫn được ghi lại."
>
<div class="kicker">Khuyến nghị</div>
<h2>Không phải chọn một bỏ một</h2>
<div class="grid3">
<div class="card">
<div class="t">🖥️ Claude Desktop</div>
<div class="d">
Khi cần <b>browser preview</b>, <b>PR + CI</b> trong app, hay cloud session của Anthropic.
Một người, một máy, chỉ Claude.
</div>
</div>
<div class="card">
<div class="t">🐋 Orca</div>
<div class="d">
Khi muốn chạy <b>nhiều loại agent</b> trên <b>laptop cá nhân</b>, miễn phí, có app điện
thoại.
</div>
</div>
<div class="card acc">
<div class="t">🛰️ AgentHub</div>
<div class="d">
Mọi thứ ở <b>tầng team</b>: server chung, chi phí cả team, pool tài khoản, lịch sử, phân
quyền, audit.
</div>
</div>
</div>
<div class="note g">
AgentHub đọc transcript của chính Claude Code, nên phiên chạy từ công cụ khác <b>trên cùng máy</b>
vẫn được ghi lại và tính chi phí.
</div>
</section>
<!-- 12 -->
<section
class="slide"
data-t="Demo"
data-n="Giờ em demo khoảng mười lăm phút theo đúng thứ tự này. Một, mở dashboard trên trình duyệt bằng tài khoản thành viên - không cài gì trên máy. Hai, tạo workspace, gõ prompt chạy Claude, mở thêm một tab chạy Codex trên cùng thư mục, chia hai pane. Ba, em đóng tab trình duyệt rồi mở lại - phiên vẫn chạy - rồi attach từ terminal để thấy cùng một pane. Bốn, mở panel Changes, comment vào một dòng diff để gửi cho agent, commit riêng một hunk. Năm, sang Analytics xem token và chi phí của chính phiên vừa chạy. Sáu, tạo một cảnh báo ngân sách. Bảy, Settings: plugin, skill, và Artifacts Hub để chia sẻ skill cho cả team."
>
<div class="kicker">Demo · ~15 phút</div>
<h2>Xem tận mắt</h2>
<div class="pipe full">
<span class="node c">Đăng nhập<small>không cài gì</small></span><span class="arr">&rarr;</span>
<span class="node">Claude + Codex<small>hai pane, một thư mục</small></span><span class="arr">&rarr;</span>
<span class="node">Đóng tab, mở lại<small>phiên vẫn chạy</small></span><span class="arr">&rarr;</span>
<span class="node">Diff &amp; commit<small>comment dòng, commit hunk</small></span><span class="arr">&rarr;</span>
<span class="node">Chi phí<small>của chính phiên vừa chạy</small></span><span class="arr">&rarr;</span>
<span class="node">Cảnh báo<small>ngân sách theo ngày</small></span><span class="arr">&rarr;</span>
<span class="node d">Settings<small>plugin, skill, Hub</small></span>
</div>
<div class="term">
<div class="bar"><i></i><i></i><i></i> &nbsp;terminal trên máy</div>
<div class="b">
<span class="m"># bước 3: cùng một pane với trình duyệt</span><br />
<span class="a">agenthub workspace shell</span><br />
<span class="m"># thoát mà không giết phiên: Ctrl-b d</span>
</div>
</div>
</section>
<!-- 13 -->
<section
class="slide"
data-t="Câu hỏi hay gặp"
data-n="Mấy câu em đoán sẽ có người hỏi, em trả lời trước. Sao không dùng Claude Desktop: vẫn dùng được song song, nhưng nó không chạy Codex, không cho xem chi phí cả team, và mỗi người cần một máy đủ mạnh. Orca miễn phí, chạy hai mươi bảy agent, sao không dùng: Orca là app cá nhân - không có tài khoản team, phân quyền, pool tài khoản hay báo cáo chi phí. AgentHub có tự chạy agent thay mình không: không, cố ý. Dữ liệu và key nằm đâu: trên server của team, key không bao giờ trả về trình duyệt. Agent làm hỏng repo thì sao: dashboard không có nút rebase hay hard reset, không sửa được commit đã push, file xoá vào thùng rác."
>
<div class="kicker">Hỏi đáp</div>
<h2>Câu hỏi hay gặp</h2>
<div class="qa">
<div class="card">
<div class="t">“Sao không dùng Claude Desktop?”</div>
<div class="d">
Dùng song song được. Nhưng nó không chạy Codex, không có chi phí cả team, mỗi người cần
một máy đủ mạnh.
</div>
</div>
<div class="card">
<div class="t">“Orca miễn phí, 27 agent - sao không dùng?”</div>
<div class="d">
App cá nhân: không tài khoản team, phân quyền, pool tài khoản hay báo cáo chi phí.
</div>
</div>
<div class="card">
<div class="t">“Nó có tự chạy agent thay mình không?”</div>
<div class="d">Không, cố ý. Ghi nhận và hiển thị; phiên đang chạy mới ra quyết định.</div>
</div>
<div class="card">
<div class="t">“Dữ liệu và key nằm đâu?”</div>
<div class="d">Trên server của team (SQLite). Key không bao giờ trả về trình duyệt.</div>
</div>
<div class="card" style="grid-column: span 2">
<div class="t">“Agent làm hỏng repo thì sao?”</div>
<div class="d">
Không có nút rebase / hard reset · không sửa được commit đã push · discard phải xác nhận
· file xoá vào thùng rác, khôi phục trong 7 ngày.
</div>
</div>
</div>
</section>
<!-- 14 -->
<section
class="slide center"
data-t="Kết &amp; Q&amp;A"
data-n="Tóm lại một câu: Claude Desktop và Codex app giúp một người lái một agent; AgentHub giúp cả team lái mọi agent trên một server chung, và biết mỗi agent tốn bao nhiêu. Hai điểm em sẽ ưu tiên làm tiếp là browser preview và PR, CI trong giao diện - mong mọi người góp ý xem cái nào cần trước. Em cảm ơn sếp và các anh chị, giờ mời mọi người đặt câu hỏi."
>
<div class="quote" style="max-width: 1100px">
Claude Desktop giúp <b>một người</b> lái <b>một agent</b>.<br />AgentHub giúp
<span style="color: var(--acc)">cả team</span> lái <span style="color: var(--acc)">mọi agent</span>.
</div>
<div class="sub" style="margin-top: 26px">
Ưu tiên tiếp theo: <b>browser preview</b> · <b>PR &amp; CI trong giao diện</b> - mong anh chị
góp ý cái nào cần trước.
</div>
<div class="tags" style="justify-content: center; margin-top: 34px">
<span class="tag on" style="font-size: clamp(14px, 1.6vw, 20px); padding: 11px 26px"
>Thảo luận &amp; Góp ý</span
>
</div>
</section>
<!-- 15 -->
<section
class="slide"
data-t="Nguồn"
data-n="Slide phụ, để mọi người tự kiểm tra. Số liệu về AgentHub em đo trực tiếp từ repo. Thông tin đối thủ lấy từ trang chính thức và bài đánh giá của bên thứ ba ngày 28 tháng 10; em chưa dùng thử trực tiếp các công cụ này, và những ô có dấu hỏi là chỗ nguồn không nói."
>
<div class="kicker">Phụ lục</div>
<h2>Nguồn và cách đo</h2>
<ul style="gap: 10px">
<li>
<b>AgentHub</b>: đo trực tiếp từ repo v2.8.32 (dòng code, file test, route, git log)
</li>
<li>
<b>Claude Desktop</b>:
<a class="mono hl" href="https://code.claude.com/docs/en/desktop">code.claude.com/docs/en/desktop</a>
· <a class="mono hl" href="https://code.claude.com/docs/en/analytics">…/analytics</a>
</li>
<li>
<b>Codex app</b>:
<a class="mono hl" href="https://developers.openai.com/codex/app">developers.openai.com/codex/app</a>
<span class="n">(chỉ từ kết quả tìm kiếm - trang OpenAI chặn truy cập tự động)</span>
</li>
<li>
<b>Orca</b>: <a class="mono hl" href="https://www.onorca.dev/">onorca.dev</a> ·
<a class="mono hl" href="https://github.com/stablyai/orca">github.com/stablyai/orca</a>
</li>
<li>
<b>Conductor, Claude Squad</b>:
<a class="mono hl" href="https://munderdiffl.in/blog/best-claude-code-multi-agent-tools/"
>munderdiffl.in - so sánh công cụ multi-agent</a
>
</li>
</ul>
<div class="note w">
Tra cứu ngày <b>28/10/2026</b>, chưa dùng thử trực tiếp đối thủ. Ô <span class="q">?</span> là
chỗ nguồn không nói - nên kiểm lại trước khi trích dẫn.
</div>
</section>
</div>
<div id="hud">
<button onclick="theme()" id="tbtn" title="Đổi nền sáng / tối">
&#9790; Nền tối <span style="opacity: 0.55">T</span>
</button>
<button onclick="tg('grid')">Lưới <span style="opacity: 0.55">O</span></button>
<button onclick="tg('notes')">Ghi chú <span style="opacity: 0.55">S</span></button>
<span id="num">1 / 15</span>
</div>
<div id="notes">
<h4 id="nt"></h4>
<p id="np"></p>
</div>
<div id="grid"></div>
<script>
const S = [...document.querySelectorAll(".slide")];
let i = 0;
const bar = document.getElementById("bar"),
num = document.getElementById("num"),
nt = document.getElementById("nt"),
np = document.getElementById("np"),
grid = document.getElementById("grid"),
notes = document.getElementById("notes");
S.forEach((s, k) => {
const d = document.createElement("div");
d.className = "gi";
d.innerHTML = `<div class="i">${String(k + 1).padStart(2, "0")} / ${S.length}</div><div class="tt">${s.dataset.t}</div>`;
d.onclick = () => {
go(k);
grid.classList.remove("on");
};
grid.appendChild(d);
});
function go(k) {
i = Math.max(0, Math.min(S.length - 1, k));
S.forEach((s, x) => s.classList.toggle("on", x === i));
bar.style.width = ((i + 1) / S.length) * 100 + "%";
num.textContent = `${i + 1} / ${S.length}`;
nt.textContent = `Slide ${String(i + 1).padStart(2, "0")} - ${S[i].dataset.t}`;
np.textContent = S[i].dataset.n || "-";
location.hash = i + 1;
}
function tg(id) {
document.getElementById(id).classList.toggle("on");
}
function paint() {
const d = document.body.classList.contains("dark");
document.getElementById("tbtn").innerHTML =
(d ? "\u2600 N\u1ec1n s\u00e1ng" : "\u263e N\u1ec1n t\u1ed1i") +
' <span style="opacity:.55">T</span>';
}
function theme() {
document.body.classList.toggle("dark");
try {
localStorage.setItem(
"ah-theme",
document.body.classList.contains("dark") ? "dark" : "light"
);
} catch (e) {}
paint();
}
try {
if (localStorage.getItem("ah-theme") === "dark") document.body.classList.add("dark");
} catch (e) {}
addEventListener("keydown", (e) => {
const k = e.key;
if (k === "ArrowRight" || k === "PageDown" || k === " ") {
e.preventDefault();
go(i + 1);
} else if (k === "ArrowLeft" || k === "PageUp") {
e.preventDefault();
go(i - 1);
} else if (k === "Home") go(0);
else if (k === "End") go(S.length - 1);
else if (k === "o" || k === "O") tg("grid");
else if (k === "s" || k === "S") tg("notes");
else if (k === "t" || k === "T") theme();
else if (k === "Escape") {
grid.classList.remove("on");
}
});
addEventListener("click", (e) => {
if (e.target.closest("#hud") || e.target.closest("#grid") || e.target.closest("#notes"))
return;
go(e.clientX > innerWidth / 2 ? i + 1 : i - 1);
});
let x0 = null;
addEventListener("touchstart", (e) => (x0 = e.touches[0].clientX), { passive: true });
addEventListener(
"touchend",
(e) => {
if (x0 === null) return;
const d = e.changedTouches[0].clientX - x0;
if (Math.abs(d) > 50) go(d < 0 ? i + 1 : i - 1);
x0 = null;
},
{ passive: true }
);
paint();
go(parseInt(location.hash.slice(1)) - 1 || 0);
</script>
</body>
</html>