Utopia 教學最值得做的,不是再問一次「目前的 API 上限是多少」,而是追問:四月二十日當時有效的規則是什麼?五月更正通知進來以前,我們又以為答案是什麼?這兩題看似相同,其實分別在問現實發生的時間與知識庫得知消息的時間。
本文專為第一次接觸時序知識圖譜的讀者寫。我會用三份虛構規格、Utopia 的 MCP 工具與一張驗收清單,帶你在本機建立一條可重播的更正鏈。研究邊界先說清楚:截至 2026 年 9 月 22 日,最新 source tag 是 v0.1.0-rc6;本文依該 tag 的官方文件、原始碼與設計紀錄設計測例,但寫作環境沒有 Docker,因此不宣稱 AlphaLab 已跑出成功率、延遲或模型成本。你會拿到的是能親手判定通過或失敗的 lab,而不是虛構結果。
先記住核心公式:雙時間答案=at(那時世界如何)× as_of/before(那時系統知道什麼)。少掉任何一軸,你看到的都只是一張「今天版本」的快照。
Utopia 教學先說結論:它能重播事實史,不等於完整決策史
Utopia 把每個事實放在兩條時間軸上,這種做法叫 bitemporal modeling(雙時間建模)。你可以把它想成醫院病歷:症狀在 4 月 15 日就存在,醫師卻到 5 月 10 日才確診。前者是 valid time(世界時間),後者是 transaction/record time(紀錄時間)。
rc6 的 MCP 文件已提供 entity_facts、changes、at、as_of 與 before,足以驗證「當時有效什麼」與「更正前記得什麼」。人工處理衝突時填入的 rationale 也會進決策台帳;但官方 README 仍把完整的 decision reasoning 與事後重播列在 roadmap。因此,這篇承諾的是重播事實、來源與更正順序;只有當你真的留下理由時,才能再用台帳材料重建「為什麼」。

Utopia 教學第 1 步:固定 rc6,從 source build 啟動
痛點是「checkout 新 tag,Compose 卻可能仍拉到舊映像」。v0.1.0-rc6 內的 docker-compose.yml 預設映像仍是 rc5,所以這個 lab 不走預建映像,而用官方的 source-build 疊加檔。先確認 Docker 與 Compose 可用,再執行:
git clone --branch v0.1.0-rc6 --depth 1 https://github.com/deeplethe/utopia.git
cd utopia
cp .env.example .env
# 先編輯 .env,至少更換 UTOPIA_DB_PASSWORD
docker compose -f docker-compose.yml -f docker-compose.build.yml \
--profile app up -d --build
docker compose ps
開啟 http://localhost:1516,註冊第一個管理者帳號;再到 Administration → Models 設定 chat 與 embedding 端點。官方說兩者都走 OpenAI-compatible API,因此可以接 hosted endpoint,也可接 Ollama、vLLM 等本機服務;但「API 形狀相容」不代表你的模型上下文、VRAM 與抽取品質一定足夠,後面會專門驗收。
先把環境留在隔離 lab。官方安全文件指出資料庫預設密碼是 utopia,資料庫埠預設只綁 127.0.0.1:1517;若改成對外綁定,必須先改密碼。應用也不要直接暴露到公網,正式上線前另做 TLS、代理、權限與資料來源最小授權。想補齊通用 RAG 安全與治理框架,可先讀企業 AI 知識庫完整指南。
第 2 步:建立空 ontology 的測試庫
建立一個獨立 knowledge base,名稱可用 utopia-bitemporal-lab,不要放公司真實文件。rc6 在建立新庫時預設不勾 ontology pack;本次就維持空白,讓測試只聚焦 Project Atlas、配額與日期。等三份文件穩定通過後,再逐一加入 schema.org 或 PROV-O,而不是一開始把所有詞彙塞進 prompt。
這個選擇有實際背景。GitHub issue #519記錄了一個 rc5 個案:一份 9 KB Markdown、10 個 chunks、LM Studio 的 gpt-oss-20b,因預設 schema.org 讓單次 system prompt 約達 104,890 tokens,超過該次 32,768-token 設定。這只是單一模型、單一 pack、單一文件的社群測量,不能外推成所有本機部署都失敗。rc6 已包含兩項對應變更:新庫預設不裝 pack,且 per-chunk ontology 清單受 24,000 字元預算約束。安全做法仍是從零或最小詞彙開始,觀察抽取錯誤,再擴大。
第 3 步:依序匯入三版規格,故意製造更正
不要先用 PDF。先把下面三段各自存成 UTF-8 Markdown,檔名依序為 atlas-v1.md、atlas-correction-v2.md、atlas-v3.md。內容故意把「文件發布日」和「規則生效日」分開,這正是兩條時間軸的材料。
# Atlas API 配額規格 v1
文件發布日期:2026-04-01
自 2026-04-15 起,Project Atlas 每一租戶每分鐘 API 上限為 100 次。
決定依據:容量規劃表 A。
# Atlas API 配額更正 v2
文件發布日期:2026-05-10
更正:Project Atlas 自 2026-04-15 起的上限應為每分鐘 200 次,不是 100 次。
原因:容量規劃表 A 先前少算一個節點群組。
# Atlas API 配額規格 v3
文件發布日期:2026-06-20
自 2026-07-01 起,Project Atlas 上限調整為每一租戶每分鐘 150 次。
原因:優先保留尖峰時段互動流量。
一次只上傳一份,等該文件解析與抽取完成才繼續。v1 完成後先在 graph 找到 Project Atlas;v2 若進入衝突 Review,選擇「close old」而不是保留兩個同時有效的值,並在 rationale 寫下「v2 明確更正節點群組漏算,生效日仍為 2026-04-15」。v3 是 7 月 1 日起的新規則;若系統要求處理區間衝突,讓 200 的區間在 6 月 30 日結束,再讓 150 從 7 月 1 日開始。
這一步不是追求模型一次猜對。若實體被拆成兩個、predicate 不一致、日期沒抽到或衝突沒有出現,都要記成 failure,回到來源句子、Review 與 ontology 修正。先把一條小鏈做對,比丟入一百份文件後再猜錯在哪裡更有效。若你還不熟悉 RAG 和知識圖譜的分工,可先看RAG 新手指南與Context Graph 教學。
第 4 步:建立唯讀 MCP token,先看工具清單
到 Account → Agents & tokens → Personal access tokens 建立 token:scope 選 read,knowledge bases 只勾本次 lab,設定有效期限。token 只顯示一次,不要貼進文章、截圖或 Git。從瀏覽器網址 /kb/{kb_id}/… 取得 KB ID,然後在暫時的 shell 設定三個值:
UTOPIA_URL='http://localhost:1516'
KB_ID='換成網址裡的 UUID'
TOKEN='換成只顯示一次的 utp_pat_…'
先向每個 knowledge base 專屬的 MCP endpoint 要工具清單。rc6 使用 JSON-RPC 2.0、MCP protocol 2025-06-18 與 stateless HTTP;每次呼叫都會重新驗證 token。
curl -s -X POST "$UTOPIA_URL/api/v1/kbs/$KB_ID/mcp" \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
驗收重點不是肉眼看到一長串 JSON,而是確認清單裡有 changes 與 entity_facts。read token 不應出現需要 write scope 與 editor 角色的 remember。如果你準備把 MCP 接到桌面 agent,先讀MCP 上線前驗收指南,把 token 範圍、停止規則與撤銷測試一起做完。
第 5 步:用 changes 找到更正時刻,再用 before 倒帶
先查這次 lab 在「紀錄時間」發生了什麼。把 since 改成你實際匯入 v1 的日期;小型測試庫通常不會碰到 40 筆上限,但仍要檢查回傳的 limit_reached。
curl -s -X POST "$UTOPIA_URL/api/v1/kbs/$KB_ID/mcp" \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"changes","arguments":{"since":"2026-09-22","kinds":["corrected"]}}}'
在 result.structuredContent.changes[] 找到 Project Atlas 的更正事件,抄下完整的 at,包含小數秒與時區,例如 2026-09-22T03:14:15.926381Z。接著做三次查詢。第一題問「以今天的知識看,4 月 20 日世界上的上限」:
curl -s -X POST "$UTOPIA_URL/api/v1/kbs/$KB_ID/mcp" \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"entity_facts","arguments":{"entity_id":"Project Atlas","at":"2026-04-20"}}}'
第二題保留相同世界日期,卻把紀錄軸倒回更正落地之前。把下方 placeholder 換成剛才 changes[].at 的完整值,不能自己減一秒;伺服器會以台帳精度讀取該事件前一微秒的狀態。
curl -s -X POST "$UTOPIA_URL/api/v1/kbs/$KB_ID/mcp" \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"entity_facts","arguments":{"entity_id":"Project Atlas","at":"2026-04-20","before":"換成 changes[].at 的完整時間戳"}}}'
第三題回到今天的知識,但把世界軸移到 7 月 5 日:
curl -s -X POST "$UTOPIA_URL/api/v1/kbs/$KB_ID/mcp" \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":5,"method":"tools/call","params":{"name":"entity_facts","arguments":{"entity_id":"Project Atlas","at":"2026-07-05"}}}'
如果抽取與 Review 都照預期,三張「驗收收據」應分別指向 200、100、150,且每筆有正確的 valid_from、來源文件與 quote。這些是預期條件,不是本文宣稱已跑出的結果;任何一項不同都先判 fail,再檢查 entity 是否選錯、日期是否漏抽、衝突是否未裁決,以及更正事件是否真的進入 graph。

changes 找到事件,再把精確時戳交給 before;不要靠人手猜「更正前一秒」。第 6 步:分清 as_of、before 與「為何決定」
at:選世界日期。例如 2026-04-20 當天哪個上限有效。as_of:選你站在哪個紀錄時間看世界。適合你已保存 checkpoint 時使用。before:接收changes事件的精確時戳,回答「這份更正進來前,系統記得什麼」。它會覆蓋as_of。- rationale:是人處理 Review 時留下的理由。沒填就沒有理由可重建;時間軸不會憑空替你發明決策脈絡。
截至 rc6,公開 MCP 清單可以查 facts、changes、timeline、rules 與 paths,但沒有提供一般用途的 ledger rationale 搜尋工具;rationale 可在產品的 Decisions/台帳路徑中看見。這就是本篇標題使用「當時知道什麼」,而不誇大成「完整重播每次決策思考」的原因。若你的需求是把每次政策調整都變成可審計決策,最低資料模型應同時保存:決策結果、有效區間、紀錄時刻、來源、rationale、操作者與後續更正。
第 7 步:把 PDF 表格與本機 context 當失敗測例
PDF 表格不要直接當基準答案來源。rc6 的官方設計紀錄 0039明確寫出:當時 PDF parser 尚未產生 table 結構,PDF 表格會以 prose 進入後續 block reader;外部 layout parser、表格儲存格級 evidence 仍是後續工作。
驗法很簡單:把三列配額做成一份 Markdown 表格與一份視覺相同的 PDF,各問「4 月 20 日」「7 月 5 日」「v2 更正前」三題,逐題保存 search_chunks 的片段、欄名、值與來源。Markdown 全對而 PDF 丟欄名,就把 PDF 標為 unsupported-for-this-corpus,先保留原 PDF 作證據,再另存經人工核對的結構化版本;不要因 chatbot 猜對一次就宣告解析通過。這和WeKnora Auto-Wiki 驗收的差別在於:那篇檢查來源更新能否傳到回答,這篇檢查兩個時間座標能否分別重播。
本機模型也用相同原則:保存模型名稱、context 設定、ontology pack、文件大小、chunk 數、失敗訊息與處理時間。若抽取失敗,先確認新庫是否真的沒有預選 pack,再看 ontology prompt 預算與上游錯誤;不要只用「Test connection 成功」當成文件抽取可行的證據。
第 8 步:備份資料庫+data,再談升級與重建
官方 README 把 Utopia 標為 v0.1,資料庫 migration 只往前、沒有 rollback;內建 backup/restore commands 也仍在 roadmap。升級前至少要一起保留 PostgreSQL 與專案的 data/。後者含原始檔、全文索引與首次啟動產生的 secret.key;遺失金鑰,已加密的模型 API key 與連線憑證就無法讀回。
mkdir -p ../utopia-backup-20260922
docker compose --profile app stop app
docker compose exec -T db \
pg_dump -U utopia -d utopia -Fc \
> ../utopia-backup-20260922/utopia.dump
tar -czf ../utopia-backup-20260922/utopia-data.tgz -C . data
shasum -a 256 ../utopia-backup-20260922/utopia.dump \
../utopia-backup-20260922/utopia-data.tgz
docker compose --profile app start app
PostgreSQL 官方文件說明 -Fc 會建立供 pg_restore 使用的 custom archive。真正的 restore 驗收要在另一個隔離目錄與不同埠進行:固定同一 tag,還原 dump 與 data/,確認三份文件、Project Atlas entity、changes 事件與三張查詢收據都能重建。只看到容器啟動不算成功。需要把來源、設定與 fixture 一起版本化時,可延伸看Context Repo 教學。
Utopia 教學的通過標準
- 版本:repository 固定在
v0.1.0-rc6,實際 app 由該 source build,不混用 rc5 映像。 - 世界軸:
at=2026-04-20與at=2026-07-05能分出不同有效規則。 - 紀錄軸:相同
at=2026-04-20,加入更正事件的before後能回到更正前狀態。 - 證據:每張收據都有來源文件、quote、valid range 與完整 record timestamp,不只一個答案數字。
- 理由:人工 Review 的 rationale 有填寫;未填的項目明確標為無法重建理由。
- 失敗面:PDF 表格與本機模型分開留測試紀錄,沒有把一次猜對包裝成支援保證。
- 復原:資料庫 dump、
data/、tag、模型設定與 fixtures 能在隔離環境重建同一條更正鏈。
Utopia 雙時間知識圖譜 FAQ
at 和 as_of 可以互換嗎?
不能。at 問某天世界上什麼有效;as_of 問站在某個紀錄時刻,系統當時持有哪些事實。兩者可以同時存在。
為什麼更正前查詢要用 before,不自己減一秒?
因為同一秒可能有多筆更正。changes 保留 RFC3339 小數秒,before 會依台帳精度回到事件前一微秒,避免人手截斷造成排序錯誤。
Utopia 現在能完整回答「當時為何這樣決定」嗎?
只能回答你有留下證據的部分。rc6 可重播 facts、changes、validity 與來源,也會保存人工 Review rationale;完整 decision reasoning/事後 decision replay 仍列在官方 roadmap。沒寫下的理由,系統不應替你補寫。
PDF 裡的表格可以直接信任嗎?
rc6 不應直接當成已通過。官方紀錄說 PDF parser 當時沒有 table 結構;請用同內容 Markdown 對照、逐格核對來源,再決定你的 corpus 是否可用。
本機 OpenAI-compatible model 接得上,就代表抽取得動嗎?
不代表。連線測試、embedding、ontology prompt 與逐 chunk 抽取是不同負載。從空 ontology、三份小文件開始,保存上游錯誤與 context 設定。
MCP token 是唯讀的嗎?
看 scope 與角色的交集。read token 提供查詢工具;remember 只有 write token 加上該 KB 的 editor 權限才會出現,而且它提出的 facts 仍要等人確認。這個 lab 只使用 read token。
時間軸與 revision 可以取代備份嗎?
不能。它們和資料庫、原始檔、索引及加密金鑰同處一個部署;整體損壞時不會自動變成異地副本。升級前備份,並在另一套環境做 restore drill。
給新手的 5 個重點
- 先固定 source tag 與實際執行版本,再談功能。
at是世界時間;as_of/before是紀錄時間。- 先用三份 Markdown 做出可證偽的小鏈,再測 PDF 與大型 ontology。
- changes 的完整時戳就是倒帶把手,不要自己猜前一秒。
- 重播事實不等於重播理由;rationale 必須在決策當下留下。
接著閱讀
左右滑動查看更多推薦
結語:真正的倒帶鍵,是兩個時間座標
Utopia 最有價值的教學材料,不是 graph 畫面,而是你能把同一個 Project Atlas 問題放到不同座標:今天看 4 月 20 日,答案應是更正後的 200;站在更正事件之前看同一天,才會回到當時記錄的 100;把世界日期移到 7 月 5 日,又應讀到新政策 150。這三張收據能同時保留來源與時間,雙時間才不是口號。
最後回到核心公式:雙時間答案=at × as_of/before。先完成這個三文件 lab、保留失敗清單、做一次隔離還原,再決定是否擴大到真實文件。你也可以到AlphaLab AI 專區繼續補齊基礎,或用完整課程把驗收方法做成自己的 AI 工作流。






