昨天已經跑通:
CLI
↓
OpenClaw Gateway
↓
Agent
↓
Ollama
Agent 可以正常回答問題。
但這只能證明:
模型能透過 OpenClaw 回答。
還不能證明:
它真的知道這個專案裡的程式碼。
所以今天把 Day 19 留下來的安全版 devbench MCP Server 接回去。
還是問同一個問題:
主力模型設定在哪裡?
只是今天多一個要求:
答案必須來自真正的 Tool Call。
不是模型猜到,也不是它在回答裡說「我已經讀過檔案」。
OpenClaw 裡會看到幾個很容易混在一起的詞。
可以先這樣理解:
| 名詞 | 用途 |
|---|---|
| Tool | Agent 真正可以呼叫的能力 |
| Skill | 告訴 Agent 某類工作應該怎麼做的指引 |
| Plugin | 用來提供或整合額外能力 |
今天真正會執行、也會留下 runtime 軌跡的是:
Tool
+
MCP
Skill 今天先只講定位。
不會因為某份 Skill 寫著:
請讀取 config.py
Agent 就突然獲得讀檔權限。
它最後還是需要一個真正能執行:
read_file
的 Tool。
所以可以先記:
Skill 告訴 Agent 怎麼做
Tool 決定 Agent 能不能真的做
今天不把 Skill 發現或 SKILL.md 啟用寫成已完成實測,避免把概念介紹和實際驗證混在一起。
這次設定:
make_config(mcp=True)
會註冊一個 stdio MCP Server。
用的不是 Day 10 最早那個版本,而是 Day 19 已經加上安全限制的 devbench。
所以 Agent 目前能看到的只有:
read_file
list_files
Research Agent 的 Tool allowlist 也只允許這兩個能力。
整條路會變成:

注意模型與 MCP 還是兩條不同的路。
Ollama
→ 負責模型推論
MCP
→ 負責真正讀取專案資料
OpenClaw 負責把兩邊串進同一個 Agent Runtime。
這次使用的 OpenClaw 版本裡,MCP Server 設定放在:
mcp.servers
Tool 篩選則使用:
toolFilter.include
這跟其他桌面工具常看到的:
mcpServers
不是同一套設定格式。
雖然底下接的都是 MCP,但:
MCP Protocol
和:
某個 Host 的 Config Schema
是兩件事。
所以不能看到別人的:
{
"mcpServers": {
...
}
}
就直接整段貼進 OpenClaw。
設定名稱還是要看目前鎖定版本的 Schema。
真正執行的入口:
from ironman.openclaw_lab import OpenClawLab
def main() -> None:
lab = OpenClawLab()
lab.setup(
mcp=True,
)
with lab.gateway():
answer = lab.ask(
"請讀取設定檔,"
"指出主力模型的設定位置與行號。"
)
events = lab.tool_events(
answer["session"]
)
used_read_file = any(
event["name"] == "devbench__read_file"
and event["success"]
for event in events
)
assert used_read_file, (
"沒有取得 MCP 讀檔證據,"
"交回人工檢查"
)
if __name__ == "__main__":
main()
這次會看兩種結果。
第一個是:
最後答案有來源
第二個更重要:
runtime events 裡真的有成功的
devbench__read_file
因為下面這種回答:
我使用 read_file 查看了設定檔……
本身不算證據。
Tool 名稱出現在普通文字裡,也不代表 Tool 真的跑過。
真正要確認的是:
Agent 產生 Tool Call
↓
OpenClaw 執行
↓
MCP Client 送到 Server
↓
Server 真的讀檔
↓
回傳 Observation
這條軌跡存在,才算串接完成。
這次還碰到一個滿實際的問題。
一開始按照舊範例去找某個:
JSONL transcript
結果根本找不到。
不是 Agent 沒有執行 Tool。
而是本次版本的 Session 儲存方式已經改成 SQLite。
所以後來改成使用官方提供的 Session CLI 匯出軌跡:
sessions export-trajectory
再從匯出的資料讀取 runtime event。
這也再次提醒:
Runtime 行為沒變
≠
內部儲存格式永遠不會變
如果框架本身提供正式的:
CLI
API
Export
優先使用這些穩定介面。
不要把:
某個版本內部剛好存在哪個檔案
當成永久規格。
從軌跡裡還會看到另一個容易誤判的地方。
同一次工具操作,可能同時出現在:
runtime event
transcript
tool_search
tool_call
不能看到兩筆紀錄就直接算:
Agent 呼叫了兩次 Tool
這些有些只是同一次操作在不同層留下的事件。
特別是延遲載入 Tool 時,可能先看到:
tool_search
接著才是真正:
tool_call
所以評估 Tool 使用量時,要先定義:
哪一種 Event 才算一次真正的工具執行?
不然很容易把 Framework 的包裝事件一起加總。
第一次實測還看到一個很有意思的情況。
模型先送出了一次:
缺少必要參數的 Tool Call
執行失敗後,下一輪才修正參數,再成功呼叫。
如果只看最後答案,完全看不出中間發生過這件事。
但軌跡會留下:
第一次 Tool Call
→ 參數錯誤
Observation
→ 失敗
第二次 Tool Call
→ 修正參數
Observation
→ 成功
這比貼一段漂亮的最終答案更有價值。
因為它證明前面一直做的:
Schema Validation
Error Observation
Stop / Retry Policy
真的不是多餘的。
模型第一次就有可能叫錯。
Agent 能不能正常工作,很多時候看的不是:
它會不會犯錯?
而是:
犯錯之後,系統能不能留下足夠資訊讓它修正?
今天雖然把 MCP 接進 OpenClaw,但權限沒有跟著放大。
Research Agent 目前仍然只有:
read_file
list_files
沒有:
write_file
shell
delete
browser automation
network send
今天產生的摘要也只作為回答回傳。
不會讓 Agent 自己直接寫進專案目錄。
這是這個系列目前的安全設計選擇,不代表 OpenClaw 本身沒有寫檔能力。
Day 19、20 的原則繼續保留:
Framework 換了
≠
最小權限重置
需要更高權限時,再明確新增。
不是因為新的 Runtime 能做,就全部開給它。
昨天我們驗證的是:
OpenClaw
↓
Agent
↓
Ollama
今天把工具補回來:
OpenClaw Agent
/ \
/ \
Ollama MCP
↓
devbench Server
↓
專案檔案
而且這次成功標準不再只是:
有回答
而是:
有 Tool Call
+
有成功 Observation
+
有來源
+
有 Runtime Trace
到這裡,OpenClaw Agent 才真的從:
會聊天
變成:
可以取得專案證據再回答
明天要處理的則不是 Tool。
而是另一個很容易混在一起的問題:
Gateway 重啟之後,剛才的對話還在嗎?
以及:
Session、Workspace、Memory 到底各自在保存什麼?
Day 26:
OpenClaw 如何保存狀態?Session、Workspace 與 Memory。
OpenClaw Gateway Config Extensions
https://docs.openclaw.ai/gateway/config-extensions
OpenClaw Sessions CLI
https://docs.openclaw.ai/cli/sessions