<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>QM on YennJ12 Engineering Blog</title><link>https://yennj12.js.org/yennj12_blog_V4/tags/qm/</link><description>Recent content in QM on YennJ12 Engineering Blog</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Fri, 07 Aug 2026 18:00:00 +0800</lastBuildDate><atom:link href="https://yennj12.js.org/yennj12_blog_V4/tags/qm/feed.xml" rel="self" type="application/rss+xml"/><item><title>QM 深度解析（一）：多人協作 Agent 平台的架構全景</title><link>https://yennj12.js.org/yennj12_blog_V4/posts/qm-multiplayer-agent-part1-architecture-zh/</link><pubDate>Fri, 07 Aug 2026 14:00:00 +0800</pubDate><guid>https://yennj12.js.org/yennj12_blog_V4/posts/qm-multiplayer-agent-part1-architecture-zh/</guid><description>大部分 Agent 產品的設計起點是「一個使用者」。 你可以把它塞給整間公司用，然後很快會發現： 記憶混在一起、憑證共用、A 在頻道問的問題被 B 的 context 污染。 QM 的起點反過來 —— 它先假設有很多人，再問「他們怎麼共用同一個 Agent」。
本系列共五篇，逐層拆解 yc-software/qm： 它解決什麼問題、Scope 模型怎麼撐起多人隔離、Harness 抽象怎麼同時驅動四種 Agent 引擎、 安全模型怎麼分層，以及沙箱 / Skills / Cron 這些持久化能力怎麼組裝。
本篇是第一篇：架構全景。
一、核心命題：single-player 與 multiplayer 的分野 1.1 README 的第一段就是設計聲明 Most agents are designed like personal assistants. You can make one work for a whole company, but it quickly gets complex. QM is designed for startups. Employees each get their own isolated workspace and work independently without affecting each other, and they can also collaborate with the agent in channels, group messages, and projects.</description></item><item><title>QM 深度解析（二）：Scope 與 Resolution — 一次對話如何解析出身分、權限與工作區</title><link>https://yennj12.js.org/yennj12_blog_V4/posts/qm-multiplayer-agent-part2-scope-resolution-zh/</link><pubDate>Fri, 07 Aug 2026 15:00:00 +0800</pubDate><guid>https://yennj12.js.org/yennj12_blog_V4/posts/qm-multiplayer-agent-part2-scope-resolution-zh/</guid><description>多租戶最危險的地方不是資料庫查詢忘了加 WHERE tenant_id = ?。 那種 bug 會被 code review 抓到。 真正危險的是：Agent 在頻道裡回答問題時，引用了只有提問者有權讀的檔案。 沒有 SQL 出錯，沒有權限檢查失敗 —— 是模型自己把資料唸出來的。
本篇是 QM 深度解析系列 的第二篇，主角是 src/resolution/（1,593 行）、src/acl/（354 行） 與 src/sessions/（1,936 行）。
一、ScopeId：一個字串撐起整個系統 1.1 定義只有 30 行 1const SCOPE_KINDS = [&amp;#34;personal&amp;#34;, &amp;#34;channel&amp;#34;, &amp;#34;team&amp;#34;, &amp;#34;org&amp;#34;, &amp;#34;group&amp;#34;] as const; 2export type ScopeKind = (typeof SCOPE_KINDS)[number]; 3 4export type ScopeId = string; 5 6export function scopeId(kind: ScopeKind, ref: string): ScopeId { 7 return `${kind}:${ref}`; 8} 9 10export function personalScope(principalId: string): ScopeId { 11 return scopeId(&amp;#34;personal&amp;#34;, principalId); 12} 13 14export function parseScopeId(id: ScopeId): { kind: ScopeKind | null; ref: string } { 15 const sep = id.</description></item><item><title>QM 深度解析（三）：Harness 抽象 — 一套核心驅動四種 Agent 引擎</title><link>https://yennj12.js.org/yennj12_blog_V4/posts/qm-multiplayer-agent-part3-harness-abstraction-zh/</link><pubDate>Fri, 07 Aug 2026 16:00:00 +0800</pubDate><guid>https://yennj12.js.org/yennj12_blog_V4/posts/qm-multiplayer-agent-part3-harness-abstraction-zh/</guid><description>「支援多種 Agent 引擎」聽起來像是寫幾個 adapter。 但 Pi 跑在同進程裡、OpenCode 是一個 HTTP sidecar、 Codex 講 JSON-RPC、Claude Code 用 SDK 加 in-process MCP。 它們的工具怎麼註冊、怎麼中斷、能不能收圖片，四家四個答案。 抽象的難點不是「共同介面」，是「差異怎麼被誠實地表達出來」。
本篇是 QM 深度解析系列 的第三篇，主角是 src/harness/（10,022 行）與 src/core/orchestrator.ts（2,863 行）。
一、四個引擎，四種完全不同的接法 先看結論。defineHarness() 的第一個參數就是各引擎的自我宣告：
1// pi-harness.ts 2{ id: &amp;#34;pi&amp;#34;, controlTransport: &amp;#34;in-process&amp;#34;, toolTransport: &amp;#34;in-process&amp;#34;, 3 transcriptFormat: &amp;#34;pi&amp;#34;, 4 capabilities: new Set([&amp;#34;abort&amp;#34;,&amp;#34;steer&amp;#34;,&amp;#34;images&amp;#34;,&amp;#34;thinking-level&amp;#34;,&amp;#34;fast-mode&amp;#34;,&amp;#34;provider-sessions&amp;#34;]) } 5 6// claude-harness.ts 7{ id: &amp;#34;claude&amp;#34;, controlTransport: &amp;#34;sdk&amp;#34;, toolTransport: &amp;#34;in-process-mcp&amp;#34;, 8 transcriptFormat: &amp;#34;claude-agent-sdk&amp;#34;, 9 capabilities: new Set([&amp;#34;abort&amp;#34;,&amp;#34;steer&amp;#34;,&amp;#34;images&amp;#34;,&amp;#34;thinking-level&amp;#34;,&amp;#34;fast-mode&amp;#34;]) } 10 11// opencode-harness.</description></item><item><title>QM 深度解析（四）：安全模型 — 三種 Posture、命令政策與誠實的威脅模型</title><link>https://yennj12.js.org/yennj12_blog_V4/posts/qm-multiplayer-agent-part4-security-model-zh/</link><pubDate>Fri, 07 Aug 2026 17:00:00 +0800</pubDate><guid>https://yennj12.js.org/yennj12_blog_V4/posts/qm-multiplayer-agent-part4-security-model-zh/</guid><description>大多數 Agent 專案的安全章節長這樣：「我們有沙箱、有審批、有稽核。」 QM 的安全章節有一節叫 Known limitations，列了 12 條， 第一條是「命令政策是可以繞過的」。 能寫出這一節的專案，通常比宣稱完整安全的專案安全得多。
本篇是 QM 深度解析系列 的第四篇，涵蓋 src/security/（455 行）、src/policy/command-policy.ts（816 行） 與 SECURITY.md（11KB）。
本文為技術架構分析，所有討論皆針對開源專案的公開設計，供防禦性學習使用。
一、防禦分層：哪一層擋什麼 在看細節之前，先建立全圖。QM 的防禦不是一道牆，是五層各有明確職責的閘門：
┌──────────────────────────────────────────────────────────────────────────────┐ │ L5 · 沙箱隔離（作業系統 / VM 層） ★ 真正的邊界 │ │ 每個 scope 一台獨立的電腦；microVM / Fly sprite / 本機容器 │ │ → 擋：跨 scope 讀取、宿主機存取 │ ├──────────────────────────────────────────────────────────────────────────────┤ │ L4 · Egress 政策（網路層，視後端能力而定） │ │ allowedHosts 取受眾交集、deniedHosts 取聯集 │ │ → 擋：資料外送到未授權主機 │ ├──────────────────────────────────────────────────────────────────────────────┤ │ L3 · 命令政策（程式層，決定性） ★ 減速帶，非邊界 │ │ evaluateCommand → allow / deny / require_approval │ │ → 擋：誤操作與最常見的注入形式 │ ├──────────────────────────────────────────────────────────────────────────────┤ │ L2 · Security posture（程式層，決定要不要人介入） │ │ strict：每個工具都暫停等人 / auto：分類器篩外部內容 / dangerous：都不做 │ │ → 擋：模型自主做出不該做的事 │ ├──────────────────────────────────────────────────────────────────────────────┤ │ L1 · 內容篩檢分類器（模型層，機率性） ★ 啟發式，不是保證 │ │ 對有來源標籤的外部文字與工具結果分類 auto / strict │ │ → 擋：prompt injection 的顯性形式 │ └──────────────────────────────────────────────────────────────────────────────┘ ★ 貫穿所有層：身分解析、scope 授權、grant 檢查、稽核紀錄 （這些不是「防禦層」，是系統的骨架 —— 見 Part 2） SECURITY.</description></item><item><title>QM 深度解析（五）：Sandbox、Skills、Cron 與部署 — 讓 Agent 擁有一台持久的電腦</title><link>https://yennj12.js.org/yennj12_blog_V4/posts/qm-multiplayer-agent-part5-sandbox-skills-cron-zh/</link><pubDate>Fri, 07 Aug 2026 18:00:00 +0800</pubDate><guid>https://yennj12.js.org/yennj12_blog_V4/posts/qm-multiplayer-agent-part5-sandbox-skills-cron-zh/</guid><description>大部分 Agent 的執行環境是「每次任務開一個乾淨容器」。 乾淨很好，直到你發現每一次任務的前三分鐘都在 pip install。 QM 反過來：每個 scope 一台持久的電腦 —— 裝過的工具還在，登入過的服務還登著。 代價是：那台電腦裡有可用的憑證，而且它會一直在那裡。
本篇是 QM 深度解析系列 的最後一篇，涵蓋 src/sandbox/（3,226 行）、src/skills/（1,904 行）、 src/cron/（699 行）、src/memory/（1,247 行）與部署層。
一、Agent Computer：不是容器，是電腦 1.1 命名本身就是設計 QM 沒有把它叫 Container 或 Runtime，而是 AgentComputer：
1export interface AgentComputerSpec { 2 os?: string; 3 runtimes?: string[]; 4 tools?: string[]; 5 notInstalled?: string[]; // ★ 「沒裝什麼」也是規格的一部分 6 cpus?: number; 7 memoryMb?: number; 8 diskGb?: number; 9 homeDir?: string; 10 workdir?: string; 11} 12 13export interface AgentComputerProfile { 14 backend: string; 15 writablePersistence: &amp;#34;snapshot_to_workspace&amp;#34; | &amp;#34;resident_disk&amp;#34;; 16 processSessions: boolean; 17 egressEnforcement?</description></item></channel></rss>