呼叫 Bot 電腦上的 Pi Agent
Pi 是裝在 Bot 電腦上的命令列編碼 Agent,預設模型 DeepSeek Flash、思考層級 high,能讀寫檔案、執行命令和聯網搜尋。詳細安裝與設定請見倉庫中的 docs/setup-guide.md。腳本裝在 ~/tools/pi-call/(倉庫的 bin/ 目錄)。
用量策略
Bot 自身的模型用量有限,Pi 跑的是使用者自己的模型帳號(預設 DeepSeek),額度與 Bot 分開計算。所以重活預設交給 Pi,Bot 只做排程和把關。
交給 Pi:
- 批次檔案處理:批次改檔案、整理資料、格式轉換。
- 寫程式碼:腳本、小工具、測試、除錯。
- 長篇調研和聯網搜尋。
- 長文初稿:文件、報告、文章的第一版。
- 使用者點名要 Pi 做、要第二意見或同題對比。
Bot 自己做:
- 簡短對話和能一兩步答完的問題。
- 連接器操作(Gmail、X、GitHub 等),Pi 沒有這些連接。
- 傳送、發布、推送、部署前的確認,以及向使用者回報。
做法:
- 指令要短:寫清目標、輸入在哪、輸出寫到哪個檔案、完成標準,幾行就夠,不要把大段原文貼進提示詞,讓 Pi 自己讀檔案。
- 結果直接存成檔案:在提示詞裡指定輸出路徑,讓 Pi 寫檔案;Bot 核查後直接交付這個檔案,不再自己重寫一遍。需要改就帶同一對話讓 Pi 改。
- 關鍵結論要落地:任務得出的重要結論、決定或資料,由 Bot 主動寫進記憶或相關文件,不要只留在 Pi 的對話裡。
步驟
- 確定工作目錄:只給 Pi 完成任務需要的那個目錄(倉庫或
/tmp/<任務>),不要給/或整個家目錄。 - 起對話名稱:簡短的英文 kebab-case,一個任務一個名稱(如
news-i18n)。同一任務的後續修改沿用同名;想從頭開始就換新名稱。 - 定輸出位置:沒有更合適的目標位置時,用
/tmp/pi-out/<對話名稱>/;要留存或同步的成果,直接寫到它該去的地方(對應倉庫、文件或筆記目錄)。 - 寫提示詞:短而完整,講清目標、約束、輸出檔案路徑、完成標準,最後讓它回報寫了哪些檔案和一句話結論。Pi 看不到聊天記錄,必要背景用一兩句交代,長材料給檔案路徑。
- 呼叫。超過一兩分鐘的任務一律用
pi-task,它會給任務編號並記錄狀態和過程,結果存成檔案:~/tools/pi-call/pi-task run <工作目錄> "<提示詞>" --session <對話名稱> --owner <your-agent-id> [--timeout 秒] [--no-write] [--no-web]--owner必須寫:它把任務標給派活的 Bot,完成通知才找得到人,pending/ack也靠它防止不同 Bot 互相搶回報、替別人的任務 ack。不寫雖然照樣跑(owner 記null,stderr 給一句警告),但通知就轉不回來了。(也可以由環境變數PI_TASK_OWNER提供預設值,但顯式傳更穩。)自己的 agent id 在自己的 profile 路徑裡(形如/home/box/agent-data/agents/<your-agent-id>/profile.json)。 用 Shell 工具自帶的背景執行(不阻塞),不要用nohup、&或setsid。輸出第一行是TASK <任務ID>;結束時列印狀態和result.md路徑。退出碼:0 完成,1 失敗,124 逾時,130 取消。 其他子命令:status <ID>(狀態、owner、耗時、最近事件)、log <ID> [-n 30]、list [--all] [--owner <id>|none]、cancel <ID>、pending [--owner <id>|none](已結束但還沒回報的任務)、ack <ID> [--owner <id>|none](標記已回報;owner 不匹配的拒絕,退出碼 1)。 任務資料在~/.pi/tasks/<任務ID>/:status.json、events.jsonl、result.md、prompt-<n>.txt。Bot 電腦重啟後,還在跑的任務會被標成interrupted,問使用者要不要重跑。 完成通知: 環境裡有PI_NOTIFY_URL和PI_NOTIFY_SECRET時(存成 Bot 電腦的環境變數,不寫進檔案),pi-task每跑完一個任務就向這個 Webhook 發一條{source, id, owner, state, exit_code},不帶任務內容。接收它的例行任務被喚醒後跑pending --owner <自己的 id>,核查、回報、ack --owner <自己的 id>。只處理 owner 是自己的任務;別的 Bot 的任務不核查不 ack,用 SendToAgent(priority true)轉給 owner 那個 Bot,例行任務環境發不了訊息就交回 Bot 本體轉發;無 owner 的只提醒使用者,不 ack。別的 Bot 轉來的、owner 是自己的任務,自己核查、回報並ack。沒有設定就自動跳過,傳送結果記在events.jsonl的notify事件裡;設定PI_NOTIFY_OFF=1可以暫時關閉。 兜底回報: 完成通知可能收不到。所以每次被喚醒(使用者發訊息、例行任務等)且有派給 Pi 的任務時,先跑一次pi-task pending --owner <自己的 id>,只看自己派的任務,把結束了但還沒回報的任務核查後交付,然後ack <ID> --owner <自己的 id>;只 ack 自己的,別人的任務留給派活的那個 Bot。 幾十秒內能完成的短問答,可以直接前景呼叫:需要唯讀或換模型時用底層腳本:~/tools/pi-call/pi-run <工作目錄> "<提示詞>" --session <對話名稱> [--timeout 秒]~/tools/pi-call/pi-call.mjs <工作目錄> deepseek/deepseek-flash "<提示詞>" --thinking high [--allow-write] [--no-web] [--session <對話名稱>] [--timeout 秒]pi-run和pi-call.mjs:標準輸出只有 Pi 的最後一段回覆;預設逾時 300 秒;退出碼 0 成功,1 出錯,124 逾時,127 找不到 pi。 權限:pi-task run和pi-run預設開放全部工具(讀、搜尋、執行命令、寫檔案、聯網搜尋);pi-call.mjs不帶--allow-write時只有唯讀工具。 - 核查結果:Pi 的回覆只是它的說法。用
git diff、跑測試或讀檔案確認它真的做了,再向使用者轉述;不要把未經核實的結論當事實。 - 繼續修改:
pi-task的任務用pi-task reply <任務ID> "<要改什麼>"(同一對話、同一目錄、沿用原任務的 owner,任務還在跑時會被拒絕);pi-run的任務帶同一個--session再調一次。兩者的對話分開存放,不能互相續接。
規則
- 用的是使用者自己的模型額度(聯網搜尋走使用者自己的搜尋服務額度),按需呼叫,不做無意義的重複或大批量空跑。
- 推送程式碼、部署、改 DNS 或線上服務、發訊息或郵件、刪除重要檔案,都不交給 Pi;這些由 Bot 自己做,並先徵得使用者同意。
- 不讓 Pi 讀取或輸出
~/.pi/agent/auth.json、金鑰檔案或環境變數裡的 key。 - 不 ack 別人的任務:
pending/ack都帶--owner <自己的 id>,owner 不匹配就交給派活的 Bot。 - 使用者可見的回覆裡說「讓 Pi 做了 X」,說明結果和你核查過什麼。
排錯
pi: command not found:先export PATH=$HOME/.local/bin:$HOME/.node22/bin:$PATH。- 提示沒有可用模型:DeepSeek 登入失效,需要使用者在桌面終端執行
pi並/login重新登入;Bot 不能替使用者登入。 - 逾時:拆小任務,或加大
--timeout。 - 出錯或結果不對:先看退出碼和
--verbose日誌;任務本身做錯了就帶同一對話指出問題讓 Pi 重做,最多重試一兩次。仍不行就由 Bot 自己接手,並告訴使用者 Pi 哪裡沒做好,不要反覆空跑。