大腦中樞:AI Agent狀態(tài)與成本監(jiān)控實(shí)踐)
1. 一個(gè)人干一個(gè)公司的活OpenClaw到底能幫我分擔(dān)什么我現(xiàn)在的狀態(tài)說出來很多同行應(yīng)該都有共鳴創(chuàng)業(yè)第四年名義上是個(gè)公司實(shí)際上就是我自己。產(chǎn)品、運(yùn)營(yíng)、客服、文案、財(cái)務(wù)、售后全部一個(gè)人扛。招人舍不得外包不放心于是我把目光盯到了OpenClaw這種個(gè)人AI助理框架上希望它真的能當(dāng)半個(gè)員工用。折騰了一段時(shí)間之后我發(fā)現(xiàn)OpenClaw本身確實(shí)能干活但它像個(gè)蒙眼干活的員工——你根本不知道它此刻在忙什么、今天燒了多少token、哪個(gè)任務(wù)掛了、哪條渠道又掉線了。所以我動(dòng)手給它加了一套大腦中樞一個(gè)專門盯住OpenClaw的儀表盤把Agent的狀態(tài)、成本、任務(wù)流、知識(shí)沉淀全部可視化出來。這篇文章就是完整記錄我怎么做的。OpenClaw是個(gè)開源的Agent運(yùn)行時(shí)類似一個(gè)虛擬員工的軀殼消息渠道是感官LLM是大腦工具是手腳。而儀表盤就是給這個(gè)虛擬員工裝上的行車記錄儀和指揮臺(tái)。適合誰看兩類人一類是正在部署OpenClaw但卡在環(huán)境、渠道、模型各種問題上的新手另一類是已經(jīng)跑起來了但和我一樣覺得看不見Agent在干嘛的進(jìn)階用戶。全文不涉及改OpenClaw內(nèi)核所有監(jiān)控都是旁路采集失敗了也不影響主線服務(wù)。1.1 OpenClaw是什么先給沒接觸過的朋友交代背景簡(jiǎn)單說OpenClaw是一個(gè)可以自托管的AI助手運(yùn)行框架。它本身不含特別強(qiáng)的智力智力來自你給它接的LLM——Claude、GPT、或者國(guó)產(chǎn)的Qwen都行它真正強(qiáng)的地方在于連接能力能接入Microsoft Teams、Obsidian這類工作環(huán)境能調(diào)用外部工具能執(zhí)行定時(shí)任務(wù)也能處理消息流。你把它部署在一臺(tái)服務(wù)器上它就是你的7×24小時(shí)數(shù)字員工。我打個(gè)比方。OpenClaw像一個(gè)人的身體渠道是眼睛和耳朵模型是大腦工具是手和嘴。我給它配的是阿里云服務(wù)器上跑的Ubuntu模型默認(rèn)接Qwen系列渠道接了Teams和Obsidian。這個(gè)組合跑起來之后它每天能幫我處理消息、查資料、整理筆記、記賬、寫周報(bào)草稿。聽著挺美對(duì)吧但問題馬上就來了它到底有沒有在認(rèn)真干活你沒法知道。1.2 一人公司真正缺的不是更多AI而是看得見AI在干嘛一個(gè)人的公司最尷尬的地方是沒有中層管理。大公司有項(xiàng)目經(jīng)理盯進(jìn)度有財(cái)務(wù)盯預(yù)算有運(yùn)維盯系統(tǒng)。我什么都沒有。AI員工跑起來了我沒有辦法給它打績(jī)效不知道它今天值不值回票價(jià)。具體痛點(diǎn)有三個(gè)狀態(tài)不可見它是不是卡死了是不是某條渠道斷了是不是在某個(gè)死循環(huán)里反復(fù)調(diào)用工具沒有儀表盤之前我只能靠日志文件猜。成本不可控LLM是按token收錢的。OpenClaw每天進(jìn)進(jìn)出出那么多消息有的走快模型有的走強(qiáng)模型月底賬單出來才知道花了多少根本來不及止損。產(chǎn)出不可追蹤它處理了多少任務(wù)哪些成功了哪些失敗了知識(shí)沉淀到Obsidian里的東西有多少全都是一筆糊涂賬。對(duì)比一下就清楚了場(chǎng)景沒有儀表盤有了儀表盤判斷Agent是否存活手動(dòng)翻日志靠猜心跳曲線一目了然控制成本月底看賬單晚了按天按模型實(shí)時(shí)分?jǐn)倧?fù)盤單個(gè)任務(wù)從零散日志里拼時(shí)間線按task_id一鍵追溯評(píng)估產(chǎn)出感覺好像干了不少數(shù)據(jù)說話量化到章節(jié)1.3 我給大腦中樞定的目標(biāo)這個(gè)儀表盤不是花架子我給自己定了四個(gè)硬指標(biāo)做不出來就算失敗知道它還活著心跳在線率、錯(cuò)誤率、響應(yīng)延遲超過閾值就告警。知道它花了多少錢按模型、按渠道、按天統(tǒng)計(jì)token消耗成本趨勢(shì)一眼看清。知道它在處理什么任務(wù)從指令進(jìn)來、模型選擇、工具調(diào)用、到最終回復(fù)整條鏈路可回溯。知道它沉淀了什么知識(shí)Obsidian里的新筆記、行動(dòng)項(xiàng)、被翻過的舊知識(shí)全部量化。總原則只有一條不改OpenClaw本體代碼所有數(shù)據(jù)靠旁路采集。這樣OpenClaw升級(jí)了我不慌采集器掛了也不影響Agent干活。2. 部署這一關(guān)從WSL2的報(bào)錯(cuò)到阿里云ECS的最終選擇聊儀表盤之前得先把OpenClaw本身部署這件事說清楚因?yàn)槲以谶@一步卡了整整一天。如果你們是在Windows上玩大概率會(huì)碰到同一個(gè)坑。2.1 我在Windows上碰到的無法安全驗(yàn)證WSL2環(huán)境當(dāng)時(shí)我想先在本地Windows機(jī)器上試跑圖個(gè)省事。結(jié)果在PowerShell里執(zhí)行一條命令時(shí)直接彈出來一段報(bào)錯(cuò)大意是無法安全驗(yàn)證WSL2環(huán)境請(qǐng)?jiān)赑owerShell中運(yùn)行wsl --status。我一開始還以為是OpenClaw的問題反復(fù)重新安裝折騰到半夜。后來冷靜下來排查發(fā)現(xiàn)根因跟OpenClaw一點(diǎn)關(guān)系都沒有是WSL2本身沒就緒。排查命令就這三條wsl --status wsl --update wsl --shutdownwsl --status會(huì)告訴你內(nèi)核狀態(tài)wsl --update把內(nèi)核補(bǔ)到最新最后wsl --shutdown重啟WSL。如果還不行去啟用或關(guān)閉Windows功能里確認(rèn)適用于Linux的Windows子系統(tǒng)和虛擬機(jī)平臺(tái)兩個(gè)開關(guān)都打開了然后重啟電腦。這一套下來那個(gè)報(bào)錯(cuò)就消失了。這個(gè)坑我寫出來是想提醒大家看到OpenClaw相關(guān)的報(bào)錯(cuò)先懷疑基礎(chǔ)設(shè)施別一上來就懷疑工具本身。WSL2環(huán)境問題在Windows上概率很高但基本都是更新內(nèi)核、開虛擬化、重啟三板斧的事。2.2 為什么最終還是換到了阿里云ECS本地跑通了之后我又做了個(gè)決定把正式環(huán)境搬到云服務(wù)器上。對(duì)比下來云方案優(yōu)勢(shì)太明顯了對(duì)比項(xiàng)Windows WSL2阿里云ECS Ubuntu在線時(shí)間電腦得一直開著息屏可能斷7×24小時(shí)在線Teams接入回調(diào)公網(wǎng)地址麻煩公網(wǎng)IP天然合適Windows更新隨時(shí)可能重啟Agent跟著遭殃不受影響日志穩(wěn)定性文件句柄、休眠都容易出幺蛾子Linux下行為穩(wěn)定成本電費(fèi)帶寬按量付費(fèi)小實(shí)例很便宜我用的是免費(fèi)試用名額開的2核2G的ECSUbuntu 22.04配置好安全組之后OpenClaw部署在上面非常穩(wěn)。云服務(wù)器還有一個(gè)好處以后想擴(kuò)加個(gè)彈性公網(wǎng)IP就能把儀表盤頁面暴露出來手機(jī)隨時(shí)看。2.3 環(huán)境準(zhǔn)備與安裝清單云服務(wù)器到手后第一批命令如下sudo apt update sudo apt upgrade -y # 安裝 Node.js 20建議用 nvm 管理版本 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash source ~/.bashrc nvm install 20 node -v # 安裝 Git sudo apt install -y gitOpenClaw的安裝我當(dāng)時(shí)是clone官方倉(cāng)庫(kù)然后npm install也可以直接用npm全局安裝對(duì)應(yīng)CLI包。不管哪種方式Node.js版本別低于20太老的版本跑起來會(huì)有各種莫名其妙的依賴報(bào)錯(cuò)。這里多說一句有人搜node.js官網(wǎng)下載openclaw以為OpenClaw是Node.js官方的東西其實(shí)不是Node.js只是它依賴的運(yùn)行時(shí)OpenClaw是獨(dú)立的開源項(xiàng)目。安裝完成之后在/opt/openclaw目錄下初始化配置然后先手動(dòng)跑一次確認(rèn)Agent能起來、能連接模型再做后面的儀表盤。2.4 配置骨架渠道、模型、數(shù)據(jù)目錄OpenClaw的配置是YAML文件我這份是精簡(jiǎn)后的關(guān)鍵骨架agent: name: one-person-company-bot timezone: Asia/Shanghai model: provider: dashscope fast: qwen2.5-3b-instruct # 高頻低風(fēng)險(xiǎn)任務(wù)便宜 strong: qwen-plus # 復(fù)雜任務(wù)質(zhì)量?jī)?yōu)先 channels: teams: enabled: true clientId: your_client_id clientSecret: your_secret tenantId: your_tenant_id obsidian: enabled: true vault: /home/ubuntu/obsidian-vault restApiPort: 27123 apiKey: your_obsidian_api_key data: dir: /opt/openclaw/data每個(gè)字段為什么這么配我說下思路。模型那塊我用的是阿里云百煉平臺(tái)的Qwen系列因?yàn)樽邍?guó)內(nèi)API穩(wěn)定性和延遲都有保障也不用考慮網(wǎng)絡(luò)問題。fast和strong分開配是后面省錢策略的基礎(chǔ)——簡(jiǎn)單消息用3B小模型復(fù)雜任務(wù)才切大模型。渠道的teams是為了把OpenClaw接到我日常用的辦公群里obsidian是為知識(shí)庫(kù)聯(lián)動(dòng)準(zhǔn)備的后面第七章會(huì)展開。數(shù)據(jù)目錄單獨(dú)放是為了讓日志、狀態(tài)文件集中管理。后面做日志采集、心跳探測(cè)全都圍繞/opt/openclaw/data這個(gè)目錄展開。3. 大腦中樞的總體架構(gòu)旁觀者模式不碰OpenClaw內(nèi)核儀表盤最核心的設(shè)計(jì)決策是采用旁觀者模式。有朋友問我為啥不直接改OpenClaw源碼加個(gè)內(nèi)置監(jiān)控模塊不是更完美嗎事情沒那么簡(jiǎn)單。3.1 為什么選擇旁觀者模式動(dòng)手之前我考慮過三種方案方案優(yōu)勢(shì)致命傷直接改OpenClaw源碼數(shù)據(jù)最準(zhǔn)確升級(jí)就沖突維護(hù)成本高通過SDK/SDK鉤子嵌入事件完整依賴API穩(wěn)定侵入性強(qiáng)旁路采集外部數(shù)據(jù)零侵入升級(jí)不慌需要自己處理數(shù)據(jù)對(duì)齊我選了第三種。旁路采集的意思是我不碰OpenClaw進(jìn)程內(nèi)部而是從它必然會(huì)產(chǎn)生的外部痕跡里偷數(shù)據(jù)——日志文件、HTTP回調(diào)、網(wǎng)絡(luò)探活。OpenClaw只要正常運(yùn)行一定往日志里寫東西我只要有一個(gè)守護(hù)進(jìn)程盯著日志文件就能還原出它干了什么。這個(gè)模式最大的好處是故障不傳染。采集器寫得再爛最多也就是儀表盤沒數(shù)據(jù)絕不會(huì)讓Agent本身掛掉。我后面升級(jí)過兩次OpenClaw一次都沒跟儀表盤沖突過這就是旁觀者模式的價(jià)值。3.2 三條數(shù)據(jù)通路整個(gè)儀表盤的數(shù)據(jù)來源有三條各司其職通路一日志文件采集。OpenClaw會(huì)把任務(wù)事件以JSON行格式寫到日志目錄我寫了一個(gè)Node.js采集器用類似tail -f的方式讀新增行解析出結(jié)構(gòu)化事件。這條通路負(fù)責(zé)追蹤任務(wù)流。通路二Webhook事件上報(bào)。日志能覆蓋大部分情況但有些業(yè)務(wù)級(jí)事件比如這個(gè)任務(wù)用了哪個(gè)模型工具返回了什么)日志里字段不全。我在OpenClaw里注冊(cè)了一個(gè)自定義工具report_event讓它在關(guān)鍵節(jié)點(diǎn)主動(dòng)POST結(jié)構(gòu)化事件到我儀表盤的/api/events接口。這條通路負(fù)責(zé)補(bǔ)齊業(yè)務(wù)細(xì)節(jié)。通路三定時(shí)心跳探測(cè)。日志只能證明它曾經(jīng)干過活證明不了它現(xiàn)在活著。所以我每60秒主動(dòng)探測(cè)一次OpenClaw的健康接口和端口連通性連續(xù)失敗3次就標(biāo)記為degraded或offline。這條通路負(fù)責(zé)健康度監(jiān)控。三條通路的數(shù)據(jù)最終匯到一個(gè)SQLite數(shù)據(jù)庫(kù)里再由一個(gè)輕量API服務(wù)提供給前端儀表盤。3.3 組件清單與部署拓?fù)湔紫到y(tǒng)跑在同一臺(tái)2核2G的ECS上組件就五個(gè)OpenClaw本體systemd守護(hù)采集器Node.js寫的常駐進(jìn)程盯日志和端口SQLite數(shù)據(jù)庫(kù)存事件、用量、心跳儀表盤API服務(wù)Express提供/api/summary等接口前端頁面原生HTMLECharts負(fù)責(zé)畫圖。數(shù)據(jù)流是這樣走的OpenClaw產(chǎn)生日志→采集器解析入庫(kù)OpenClaw調(diào)用工具→HTTP POST到Webhook接收器→入庫(kù)OpenClaw維持運(yùn)行→心跳探針定時(shí)探測(cè)→入庫(kù)。三條通道的終點(diǎn)都是SQLite再往上就是API和頁面。這樣一套組合沒有引入任何重量級(jí)組件2G內(nèi)存跑得很輕松也方便遷移。4. 采集層三件套日志解析、Webhook、心跳探針的具體實(shí)現(xiàn)采集層是整個(gè)儀表盤的地基。地基打不好上面畫什么都白搭。我把三個(gè)模塊的關(guān)鍵代碼和思路都展開講一遍。4.1 日志解析模塊用Node.js寫一個(gè)tail -fOpenClaw把運(yùn)行日志寫在/opt/openclaw/data/logs/agent.log格式是JSON Lines每行一條結(jié)構(gòu)化事件。我寫了一個(gè)日志采集器核心思路是記錄上次讀取的文件位置只處理新增部分const fs require(fs); const readline require(readline); const logPath /opt/openclaw/data/logs/agent.log; let position 0; function tailLog() { const stat fs.statSync(logPath); if (stat.size position) { // 日志被輪轉(zhuǎn)或截?cái)嘀刂米x取位置 console.error([collector] log rotated, reset position); position 0; } const stream fs.createReadStream(logPath, { start: position }); position stat.size; const rl readline.createInterface({ input: stream }); rl.on(line, (line) { try { const event JSON.parse(line); handleEvent(event); } catch (e) { // 跳過非JSON行比如啟動(dòng)橫幅 } }); } setInterval(tailLog, 2000);這段代碼里最容易被忽略的是日志輪轉(zhuǎn)。OpenClaw重啟或者日志文件達(dá)到一定大小后文件會(huì)被截?cái)嗷蛑孛绻阒簧瞪档亟又x就會(huì)永久丟失后半段數(shù)據(jù)。所以我每次讀取前都會(huì)檢查文件size是否比上次記錄的位置還小如果小說明文件被重置過就把position歸零。這個(gè)細(xì)節(jié)是我第一版沒處理第二天發(fā)現(xiàn)數(shù)據(jù)斷檔時(shí)才補(bǔ)上的。解析到事件之后handleEvent做的事就是統(tǒng)一轉(zhuǎn)成我定義的事件結(jié)構(gòu)再寫進(jìn)SQLite的events表。不同的日志類型消息收到、模型調(diào)用、工具執(zhí)行、回復(fù)發(fā)出分別映射成不同type方便后面按類型聚合。4.2 Webhook接收器讓OpenClaw主動(dòng)匯報(bào)業(yè)務(wù)細(xì)節(jié)日志采集只能拿到OpenClaw自己寫的內(nèi)容拿不到我自定義的業(yè)務(wù)上下文。所以我在OpenClaw的工具系統(tǒng)里注冊(cè)了一個(gè)自定義工具名字叫report_event用途是讓Agent在任務(wù)的關(guān)鍵節(jié)點(diǎn)主動(dòng)向儀表盤上報(bào)結(jié)構(gòu)化數(shù)據(jù)。OpenClaw側(cè)的自定義工具配置思路大致是這樣的版本不同寫法可能略有差異但邏輯一致async function reportEvent({ task_id, type, payload }) { const res await fetch(http://localhost:3080/api/events, { method: POST, headers: { Content-Type: application/json, x-collector-token: process.env.COLLECTOR_TOKEN }, body: JSON.stringify({ task_id, type, payload }) }); return res.ok ? ok : failed; }接收端是一個(gè)Express服務(wù)校驗(yàn)token后落庫(kù)const express require(express); const app express(); app.use(express.json({ limit: 256kb })); app.post(/api/events, (req, res) { const token req.headers[x-collector-token]; if (token ! process.env.COLLECTOR_TOKEN) { return res.status(401).json({ error: invalid token }); } const { task_id, type, payload } req.body; insertEvent(task_id, type, JSON.stringify(payload)); res.json({ ok: true }); }); app.listen(3080, () { console.log(collector webhook listening on 3080); });為什么日志夠用了還要Webhook因?yàn)槿罩纠餂]有模型選擇的完整鏈路。比如一條任務(wù)日志里只記錄收到了消息和發(fā)送了回復(fù)中間用的哪個(gè)模型、調(diào)了哪些工具、每個(gè)工具花了多久全靠Webhook補(bǔ)充。有了這個(gè)通道我就能按task_id把一條完整的事件鏈拼出來。4.3 心跳探針判斷Agent是真的活著還是裝了死日志和Webhook都只能證明它歷史上有動(dòng)作不能證明它此刻沒掛。所以我加了一個(gè)最樸素的探活機(jī)制每60秒做一次TCP連接檢查并請(qǐng)求一下OpenClaw的健康檢查接口統(tǒng)計(jì)響應(yīng)耗時(shí)。#!/bin/bash # /opt/openclaw/healthcheck.sh if curl -s -o /dev/null -w %{http_code} %{time_total} \ http://127.0.0.1:3070/health | grep -q ^200; then echo ok else echo fail fi這個(gè)腳本的返回結(jié)果會(huì)寫進(jìn)heartbeats表帶上響應(yīng)耗時(shí)和狀態(tài)。前端儀表盤按小時(shí)聚合算出在線率。我設(shè)定的告警規(guī)則是連續(xù)3次探測(cè)失敗狀態(tài)從online變?yōu)閐egraded連續(xù)10次失敗直接標(biāo)offline并通過OpenClaw本體的通道往Teams里發(fā)一條告警。探針還有一個(gè)作用記錄延遲曲線。你別說OpenClaw啟動(dòng)初期因?yàn)槟P屠浼虞d響應(yīng)能飆到十幾秒看延遲曲線能明顯看到溫度變化。這些數(shù)據(jù)對(duì)后面調(diào)優(yōu)很有幫助。5. 數(shù)據(jù)落庫(kù)與儀表盤頁面SQLite ECharts的輕量組合采集層拿到數(shù)據(jù)之后得有個(gè)地方存更得有個(gè)地方看。這一章講存儲(chǔ)選型和前端實(shí)現(xiàn)。5.1 為什么選SQLite而不是上一套數(shù)據(jù)庫(kù)有人可能覺得做數(shù)據(jù)可視化至少得上個(gè)PostgreSQL吧我的理由很簡(jiǎn)單單機(jī)、單進(jìn)程、數(shù)據(jù)量不大一天幾萬條事件頂天了、需要快速讀。SQLite完全夠用還省去一個(gè)數(shù)據(jù)庫(kù)服務(wù)的運(yùn)維成本。方案優(yōu)點(diǎn)缺點(diǎn)我選不選SQLite零運(yùn)維、單文件備份并發(fā)寫弱、不適合分布式選單機(jī)完全夠PostgreSQL功能強(qiáng)、并發(fā)好多一個(gè)服務(wù)要維護(hù)不選殺雞用牛刀直接掃描日志零存儲(chǔ)代價(jià)每次查詢?nèi)繏呙杪贿x查詢體驗(yàn)太差SQLite還有一個(gè)好處備份極簡(jiǎn)單直接把.db文件復(fù)制一份就到別的機(jī)器恢復(fù)了。我每周日凌晨用cron把數(shù)據(jù)庫(kù)文件備份到對(duì)象存儲(chǔ)成本幾乎為零。5.2 三張核心表設(shè)計(jì)我把數(shù)據(jù)建模為三張表對(duì)應(yīng)三條采集通路CREATE TABLE events ( id INTEGER PRIMARY KEY AUTOINCREMENT, task_id TEXT, type TEXT, channel TEXT, model TEXT, created_at TEXT, payload TEXT ); CREATE TABLE usage ( day TEXT, hour INTEGER, model TEXT, input_tokens INTEGER, output_tokens INTEGER, cost_cny REAL ); CREATE TABLE heartbeats ( ts TEXT, ok INTEGER, latency_ms INTEGER );events表是最核心的它能回答今天處理了什么任務(wù)、結(jié)果如何usage表專門記錄token消耗和成本按(day, hour, model)粒度聚合heartbeats表記錄每一次探活結(jié)果用于計(jì)算在線率。這里有個(gè)設(shè)計(jì)細(xì)節(jié)usage表和events表會(huì)有數(shù)據(jù)重疊因?yàn)閠oken信息既可能在日志里也可能在Webhook里。所以在寫入usage時(shí)我用(task_id, model, created_at)做了唯一性約束確保同一筆token消耗不會(huì)被重復(fù)統(tǒng)計(jì)。這個(gè)坑我在第七章還會(huì)詳細(xì)講前期沒去重成本虛高了一倍。5.3 儀表盤頁面與關(guān)鍵圖表前端我沒有用重框架就是原生HTML加ECharts。為什么要這樣因?yàn)閮x表盤這個(gè)場(chǎng)景本質(zhì)是定時(shí)拉數(shù)據(jù)畫圖用Vue/React是自找麻煩。頁面結(jié)構(gòu)分四塊頂部總覽卡片、中間任務(wù)時(shí)間線、下方成本趨勢(shì)、右側(cè)渠道分布。刷新策略是前端每30秒輪詢一次/api/summary完全夠用沒必要上WebSocket。成本趨勢(shì)圖的核心配置長(zhǎng)這樣const option { tooltip: { trigger: axis }, xAxis: { type: time }, yAxis: { type: value, name: tokenk }, series: [{ name: 輸入token, type: line, areaStyle: {}, data: inputTokens }, { name: 輸出token, type: line, smooth: true, data: outputTokens }] };總覽卡片那四個(gè)數(shù)字是今日任務(wù)數(shù)、今日token消耗、今日成本、當(dāng)前在線狀態(tài)。這四樣是我每天早上睜開眼第一個(gè)看的。任務(wù)時(shí)間線則用了一個(gè)很簡(jiǎn)單的列表按時(shí)間倒序排列最近20條事件帶顏色標(biāo)簽區(qū)分成功和失敗。5.4 用systemd把整條鏈路守護(hù)起來采集器和儀表盤API都是常駐進(jìn)程掛在終端里跑早晚會(huì)死。我用systemd把整條鏈路守護(hù)起來一共三個(gè)服務(wù)OpenClaw本體、采集器、儀表盤API。以O(shè)penClaw為例[Unit] DescriptionOpenClaw Agent Afternetwork-online.target [Service] Userubuntu WorkingDirectory/opt/openclaw ExecStart/usr/bin/npx openclaw start Restartalways RestartSec5 EnvironmentNODE_ENVproduction EnvironmentDASHSCOPE_API_KEYxxx [Install] WantedBymulti-user.target采集器和儀表盤API的unit文件結(jié)構(gòu)一模一樣只是ExecStart換成對(duì)應(yīng)的Node.js入口。Restartalways是關(guān)鍵——只要進(jìn)程意外退出systemd在5秒后就幫你拉起來。我用這個(gè)方法之后整套系統(tǒng)的可用率從看運(yùn)氣變成了99.9%。6. 一人公司該盯的四類指標(biāo)健康度、成本、任務(wù)流、知識(shí)資產(chǎn)儀表盤不是把數(shù)據(jù)堆上去就完事了得想清楚每個(gè)指標(biāo)解決什么問題。我按照自己作為一人公司老板的需求把界面分成了四個(gè)維度每個(gè)維度都對(duì)應(yīng)一個(gè)實(shí)際的經(jīng)營(yíng)問題。6.1 健康度先確認(rèn)員工沒在裝死指標(biāo)含義我的告警閾值在線率心跳正常比例低于99%告警任務(wù)失敗率任務(wù)級(jí)失敗占比高于10%告警p95處理時(shí)長(zhǎng)95%的任務(wù)在多少秒內(nèi)完成超過60秒告警每次我覺得OpenClaw好像不干活了打開儀表盤一看十有八九是模型API超時(shí)導(dǎo)致的失敗率飆漲或者Teams通道斷了導(dǎo)致消息根本沒進(jìn)來。沒有告警之前我可能要等用戶發(fā)消息抱怨才知道出了問題有了心跳曲線之后通道斷開的第一時(shí)間儀表盤就標(biāo)紅了。6.2 成本賬本AI員工也要發(fā)工資LLM的花銷是實(shí)打?qū)嵙鞒鋈サ默F(xiàn)金。我把usage表按天聚合就能回答三個(gè)問題今天花了多少哪個(gè)模型花得最多哪個(gè)渠道最燒錢我的模型路由策略是快模型處理高頻消息、強(qiáng)模型處理復(fù)雜任務(wù)成本結(jié)構(gòu)大概是這樣的模型用量占比成本占比qwen2.5-3b-instruct70%15%qwen-plus30%85%這個(gè)數(shù)據(jù)是儀表盤跑了一周后我才意識(shí)到的3B小模型承擔(dān)了大多數(shù)簡(jiǎn)單任務(wù)成本占比卻只有15%。這讓我更堅(jiān)定了路由策略。月度預(yù)算上限是100元儀表盤會(huì)在用量到80%時(shí)告警避免月底失控。6.3 任務(wù)流從指令到產(chǎn)出每一環(huán)都能回溯任務(wù)流追蹤是我最滿意的功能。每條任務(wù)都會(huì)生成一個(gè)task_id從收到消息到模型選擇到調(diào)用工具到回復(fù)發(fā)出整條事件鏈都能在儀表盤里按時(shí)間線展開。我復(fù)盤一次失敗任務(wù)的典型路徑是這樣的messages.received - model.routed - tool.started(web_search) - tool.failed(timeout) - model.retry - tool.started(web_search) - tool.finished - agent.replied看到?jīng)]第一次工具調(diào)用超時(shí)了OpenClaw自動(dòng)重試了一次才成功。這種細(xì)節(jié)在沒有儀表盤之前我是完全不可能知道的——日志里雖然有但沒人會(huì)為了查一次個(gè)案去翻幾個(gè)小時(shí)的文件。6.4 知識(shí)資產(chǎn)Obsidian里的東西要不要被量化這個(gè)維度我糾結(jié)了很久。知識(shí)沉淀這種東西量化不好就是虛榮指標(biāo)。我最終的方案是記錄兩個(gè)數(shù)字每日新增筆記數(shù)、行動(dòng)項(xiàng)完成數(shù)。這兩個(gè)數(shù)字的意義在于可被執(zhí)行。OpenClaw每天會(huì)把處理過的值得留存的資料寫成Obsidian筆記并生成明日待辦行動(dòng)項(xiàng)。第二天我打開Obsidian看到的不是AI隨便摘錄的碎片而是儀表盤確認(rèn)過的、和真實(shí)任務(wù)掛鉤的知識(shí)產(chǎn)出。我甚至給OpenClaw加了一道人話規(guī)則寧可少記三篇也不要湊數(shù)記一篇。因?yàn)閮x表盤會(huì)暴露湊數(shù)的行為。7. 給儀表盤裝上手腳Teams與Obsidian的雙向打通儀表盤一開始只是被動(dòng)展示我慢慢發(fā)現(xiàn)它可以更主動(dòng)——讓OpenClaw在Teams里被時(shí)直接查儀表盤的數(shù)據(jù)庫(kù)回答我的問題。這才是大腦中樞真正的意義。7.1 Teams接入讓虛擬員工出現(xiàn)在公司群里Teams接入OpenClaw核心是Azure上的Bot注冊(cè)。你需要?jiǎng)?chuàng)建一個(gè)Bot應(yīng)用拿到clientId、clientSecret和tenantId然后在OpenClaw的channels配置里填進(jìn)去。這塊有個(gè)容易踩的坑Teams要求回調(diào)地址必須是公網(wǎng)可訪問的HTTPS地址所以我前面才堅(jiān)持要把OpenClaw部署在云服務(wù)器上本地Windows根本搞不定這個(gè)。Teams接好之后OpenClaw就光明正大地出現(xiàn)在我的工作群里了。我在群里它它就能響應(yīng)。這個(gè)能力本身不是新東西但配上儀表盤效果完全不同——因?yàn)樗F(xiàn)在能查自己的運(yùn)營(yíng)數(shù)據(jù)了。7.2 Obsidian接入知識(shí)庫(kù)與Agent聯(lián)動(dòng)Obsidian接入我選了Local REST API插件方案。這個(gè)插件會(huì)在Obsidian本地開一個(gè)REST接口OpenClaw可以通過API讀寫vault里的筆記。這樣設(shè)計(jì)的好處是筆記仍然存在我自己的倉(cāng)庫(kù)里沒有經(jīng)過第三方云數(shù)據(jù)完全可控。OpenClaw側(cè)注冊(cè)了兩個(gè)自定義工具read_note和write_note。read_note用于查詢已有筆記write_note用于把新知識(shí)寫入指定目錄。我給OpenClaw定了一個(gè)工作流每天下午六點(diǎn)把當(dāng)天處理過的有價(jià)值信息整理成一篇日記筆記放到Daily/目錄下標(biāo)題是當(dāng)天的日期。這個(gè)操作本身由OpenClaw的定時(shí)任務(wù)觸發(fā)而執(zhí)行結(jié)果會(huì)通過Webhook上報(bào)給儀表盤。7.3 用自然語言查儀表盤儀表盤API有了數(shù)據(jù)庫(kù)有了OpenClaw本身又是LLM天然能理解自然語言。所以我把儀表盤查詢也封裝成了一個(gè)自定義工具query_dashboard接受一個(gè)SQL查詢字符串或語義化問句返回圖表數(shù)據(jù)。調(diào)用鏈?zhǔn)沁@樣的我在Teams里發(fā)這個(gè)周末OpenClaw花了多少tokenOpenClaw收到后自動(dòng)調(diào)用query_dashboard把問題轉(zhuǎn)成SQL去查usage表再把結(jié)果組織成一句人話回復(fù)我。整個(gè)過程我在儀表盤的任務(wù)時(shí)間線上都能看到——它自己查了自己的賬本然后向我匯報(bào)。這條鏈路打通的那一刻我才覺得大腦中樞這個(gè)名字名副其實(shí)儀表盤不只是給人看的它還能被Agent自己調(diào)用形成一個(gè)人機(jī)共用的操作臺(tái)。8. 連續(xù)跑了一周之后數(shù)據(jù)長(zhǎng)這樣坑也踩了不少理論說再多不如實(shí)跑。我的OpenClaw加儀表盤系統(tǒng)連續(xù)運(yùn)行了一周以下是真實(shí)記錄下來的數(shù)據(jù)以及我踩過的坑。這些經(jīng)驗(yàn)手冊(cè)上真不會(huì)寫。8.1 一周運(yùn)行數(shù)據(jù)樣本指標(biāo)數(shù)值總?cè)蝿?wù)數(shù)327個(gè)任務(wù)成功率93.9%平均處理時(shí)長(zhǎng)22.4秒總token消耗約310萬總成本約36元在線率99.7%主動(dòng)告警次數(shù)2次327個(gè)任務(wù)里有大量是消息分類、信息查詢、筆記整理這類輕量任務(wù)成本大頭集中在幾個(gè)復(fù)雜任務(wù)上——比如我做競(jìng)品分析時(shí)一個(gè)任務(wù)就燒掉了整周成本的20%。這些數(shù)據(jù)讓我做了兩個(gè)調(diào)整一是把每天凌晨的重型定時(shí)任務(wù)改到下午避免和白天高峰搶模型資源二是把連續(xù)多個(gè)小任務(wù)合并成批量任務(wù)減少重復(fù)調(diào)度開銷。8.2 我踩過的坑第一個(gè)坑是時(shí)區(qū)。OpenClaw默認(rèn)按UTC記錄時(shí)間儀表盤前端按本地時(shí)間顯示。結(jié)果頭兩天我看到成本曲線在凌晨4點(diǎn)出現(xiàn)高峰還以為是半夜有爬蟲在刷排查了半天最后發(fā)現(xiàn)是時(shí)區(qū)偏移——UTC的晚上8點(diǎn)換算成北京時(shí)間就是凌晨4點(diǎn)。解決方案是在日志解析階段統(tǒng)一轉(zhuǎn)成Asia/Shanghai時(shí)間再入庫(kù)。第二個(gè)坑是日志輪轉(zhuǎn)。我第一版采集器沒有處理文件截?cái)郞penClaw重啟一次之后采集器就悶聲不響地卡在舊文件的文件描述符上看起來還在跑實(shí)際上一條數(shù)據(jù)都不進(jìn)庫(kù)了。這個(gè)問題是我第二天看儀表盤數(shù)據(jù)一夜沒增長(zhǎng)才發(fā)現(xiàn)的。解決方案就是第4.1節(jié)寫的文件size比較邏輯。第三個(gè)坑是token重復(fù)統(tǒng)計(jì)。日志里有一份token記錄Webhook里又報(bào)了一份兩邊沒去重導(dǎo)致成本虛高接近一倍。后來我在usage表的寫入邏輯里加了唯一鍵約束重復(fù)數(shù)據(jù)直接忽略。教訓(xùn)是多通路采集必須有冪等設(shè)計(jì)否則聚合數(shù)據(jù)會(huì)失真。第四個(gè)坑更蠢——阿里云安全組忘了開放儀表盤端口。我在本地curl儀表盤接口一切正常換手機(jī)在外面就訪問不了排查了一陣才發(fā)現(xiàn)是云控制臺(tái)的安全組規(guī)則只開了22和3070端口沒開3080。提醒大家云服務(wù)器的網(wǎng)絡(luò)策略和Linux本地的iptables是兩層關(guān)卡都得檢查。8.3 模型路由省錢技巧小模型當(dāng)守門員大模型當(dāng)攻堅(jiān)手最后分享一個(gè)和儀表盤深度綁定的省錢技巧模型路由。我的規(guī)則很簡(jiǎn)單消息長(zhǎng)度 200字 且 無附件 - qwen2.5-3b-instruct 消息含分析對(duì)比方案 - qwen-plus 消息來自指定客戶群 - qwen-plus 其余 - qwen2.5-3b-instruct這套路由規(guī)則讓每周成本從原本的全走大模型的81元降到了36元降幅超過50%。關(guān)鍵是儀表盤能按模型維度驗(yàn)證效果——我可以清楚地看到3B小模型的失敗率只比大模型高了2個(gè)百分點(diǎn)但成本只有1/6。這種性價(jià)比差異沒有儀表盤你根本不會(huì)知道。我個(gè)人這套組合跑到現(xiàn)在最大的體會(huì)是給OpenClaw加儀表盤這件事不是給一個(gè)玩具裝上RGB燈而是給一個(gè)虛擬員工建立最基本的經(jīng)營(yíng)臺(tái)賬。我現(xiàn)在每天早上雷打不動(dòng)做三件事看在線率、看昨天成本、看失敗任務(wù)明細(xì)。確定它一切正常之后才開始一天的工作。這個(gè)最懂一人公司的儀表盤懂的不是AI技術(shù)而是一個(gè)人管理一個(gè)系統(tǒng)這件事本身——你要能看見才能管理你要能量化才能優(yōu)化。