制:空閑輪詢、任務(wù)自動(dòng)認(rèn)領(lǐng)與身份重注入的完整實(shí)現(xiàn)解析)
learn-claude-code 自主 Agent 機(jī)制空閑輪詢、任務(wù)自動(dòng)認(rèn)領(lǐng)與身份重注入的完整實(shí)現(xiàn)解析【免費(fèi)下載鏈接】learn-claude-codeBash is all you need - A nano claude code–like 「agent harness」, built from 0 to 1項(xiàng)目地址: https://gitcode.com/GitHub_Trending/an/learn-claude-code在 learn-claude-code 的課程體系中s11Legacy 12 課時(shí)軌道解決一個(gè)多智能體協(xié)作中的規(guī)模化瓶頸讓 teammate 不再等待 lead 逐個(gè)分派工作而是自己掃描任務(wù)板、認(rèn)領(lǐng)無(wú)主任務(wù)、做完后繼續(xù)尋找下一份工作。本文基于 docs/en/s11-autonomous-agents.md 與可運(yùn)行實(shí)現(xiàn) agents/s11_autonomous_agents.py完整講清 WORK/IDLE 雙階段生命周期、空閑輪詢參數(shù)、原子任務(wù)認(rèn)領(lǐng)與上下文壓縮后的身份重注入并結(jié)合當(dāng)前 17 課時(shí)軌道 s13_agent_teams/code.py 中的演進(jìn)實(shí)現(xiàn)幫助讀者掌握一套可直接落地的自治 Agent運(yùn)行時(shí)設(shè)計(jì)。問(wèn)題Lead 逐一分派工作無(wú)法規(guī)?;?s09–s10 的實(shí)現(xiàn)中teammate 只有被明確指派時(shí)才工作lead 必須為每個(gè) teammate 生成一個(gè)帶具體 prompt 的 spawn 調(diào)用。假設(shè)任務(wù)板上有 10 個(gè)無(wú)主任務(wù)lead 就要手動(dòng)逐一分派——這在多 Agent 場(chǎng)景下不可擴(kuò)展。s11 引入的真自治模式是teammate 主動(dòng)掃描任務(wù)板task board認(rèn)領(lǐng)無(wú)主unclaimed任務(wù)處理完后繼續(xù)尋找下一份任務(wù)而不是直接退出一個(gè)微妙問(wèn)題經(jīng)歷上下文壓縮s06 課程的主題后agent 可能忘記自己是誰(shuí)。s11 用**身份重注入identity re-injection**修復(fù)這一點(diǎn)。解決方案帶空閑周期的 teammate 生命周期文檔給出的核心生命周期是一個(gè) spawn → WORK → IDLE →循環(huán)回 WORK 或 SHUTDOWN的狀態(tài)機(jī)Teammate lifecycle with idle cycle: ------- | spawn | ------ | v ------- tool_use ------- | WORK | ------------- | LLM | ------ ------- | | stop_reason ! tool_use (or idle tool called) v -------- | IDLE | poll every 5s for up to 60s ------- | --- check inbox -- message? ---------- WORK | --- scan .tasks/ -- unclaimed? ------- claim - WORK | --- 60s timeout ---------------------- SHUTDOWN Identity re-injection after compression: if len(messages) 3: messages.insert(0, identity_block)狀態(tài)機(jī)的四個(gè)關(guān)鍵轉(zhuǎn)移條件WORK → IDLELLM 的stop_reason ! tool_use自然停止或 teammate 顯式調(diào)用idle工具IDLE → WORK消息恢復(fù)輪詢期間發(fā)現(xiàn)收件箱inbox有消息IDLE → WORK自動(dòng)認(rèn)領(lǐng)掃描.tasks/發(fā)現(xiàn)無(wú)主任務(wù)認(rèn)領(lǐng)后進(jìn)入工作IDLE → SHUTDOWN60 秒超時(shí)期間既無(wú)消息也無(wú)任務(wù)。兩個(gè)可調(diào)參數(shù)在源碼中定義于 agents/s11_autonomous_agents.pyPOLL_INTERVAL 5 # 空閑輪詢間隔秒 IDLE_TIMEOUT 60 # 空閑超時(shí)秒超時(shí)后自動(dòng) shutdown輪詢次數(shù)由IDLE_TIMEOUT // POLL_INTERVAL計(jì)算即 60s / 5s 12 次輪詢機(jī)會(huì)。工作機(jī)制一雙階段 teammate 主循環(huán)源碼中 teammate 的循環(huán)TeammateManager._loop嚴(yán)格對(duì)應(yīng)文檔描述的兩個(gè)階段見(jiàn) agents/s11_autonomous_agents.pydef _loop(self, name, role, prompt): while True: # -- WORK PHASE -- messages [{role: user, content: prompt}] for _ in range(50): response client.messages.create(...) if response.stop_reason ! tool_use: break # execute tools... if idle_requested: break # -- IDLE PHASE -- self._set_status(name, idle) resume self._idle_poll(name, messages) if not resume: self._set_status(name, shutdown) return self._set_status(name, working)實(shí)現(xiàn)上有幾個(gè)值得注意的工程細(xì)節(jié)對(duì)照 源碼 L224-L302WORK 階段每次迭代都先排空收件箱調(diào)用 LLM 前先執(zhí)行BUS.read_inbox(name)若發(fā)現(xiàn)shutdown_request消息則立即置為shutdown狀態(tài)并返回保證關(guān)閉握手s10 引入的協(xié)議在忙碌時(shí)也能被及時(shí)響應(yīng)idle工具的特殊處理idle不是一個(gè)真實(shí)執(zhí)行的工具而是在工具分發(fā)時(shí)設(shè)置idle_requested True標(biāo)志并返回固定文本Entering idle phase. Will poll for new tasks.L251-L253異常降級(jí)LLM 調(diào)用拋異常時(shí)teammate 被置為idle并安全返回而不是讓整個(gè)團(tuán)隊(duì)進(jìn)程崩潰L241-L243WORK 階段有 50 輪工具調(diào)用上限防止單任務(wù)無(wú)限循環(huán)燒 token。teammate 的系統(tǒng)提示詞L217-L220明確告訴模型自治行為契約sys_prompt ( fYou are {name}, role: {role}, team: {team_name}, at {WORKDIR}. fUse idle tool when you have no more work. You will auto-claim new tasks. )工作機(jī)制二空閑輪詢 inbox 與任務(wù)板IDLE 階段的輪詢邏輯對(duì)應(yīng)文檔第 2 點(diǎn)的_idle_poll實(shí)現(xiàn)見(jiàn) 源碼 L266-L301def _idle_poll(self, name, messages): for _ in range(IDLE_TIMEOUT // POLL_INTERVAL): # 60s / 5s 12 time.sleep(POLL_INTERVAL) inbox BUS.read_inbox(name) if inbox: messages.append({role: user, content: finbox{inbox}/inbox}) return True unclaimed scan_unclaimed_tasks() if unclaimed: claim_task(unclaimed[0][id], name) messages.append({role: user, content: fauto-claimedTask #{unclaimed[0][id]}: f{unclaimed[0][subject]}/auto-claimed}) return True return False # timeout - shutdown從源碼實(shí)現(xiàn)看輪詢順序是先 inbox、后任務(wù)板消息來(lái)自 lead 或隊(duì)友的協(xié)作信息優(yōu)先級(jí)高于自取任務(wù)且每次輪詢失敗認(rèn)領(lǐng)沖突等會(huì)continue繼續(xù)下一輪直到 12 輪耗盡才真正 shutdown。inbox 的底層存儲(chǔ)是 MessageBusL81-L121每個(gè) teammate 對(duì)應(yīng).team/inbox/{name}.jsonl一個(gè) JSONL 文件send追加一行、read_inbox讀取后清空drain 語(yǔ)義合法消息類型包括message、broadcast、shutdown_request、shutdown_response、plan_approval_responseL65-L71。這種基于文件郵箱的異步通信是 s09/s10 建立的協(xié)議層在 s11 中的直接復(fù)用。工作機(jī)制三任務(wù)板掃描與原子認(rèn)領(lǐng)任務(wù)板以.tasks/task_*.json文件為持久化載體。掃描函數(shù)返回滿足三個(gè)條件的任務(wù)L128-L137def scan_unclaimed_tasks() - list: unclaimed [] for f in sorted(TASKS_DIR.glob(task_*.json)): task json.loads(f.read_text()) if (task.get(status) pending and not task.get(owner) and not task.get(blockedBy)): unclaimed.append(task) return unclaimed三個(gè)條件分別保證任務(wù)未開(kāi)始pending、無(wú)主owner為空、且沒(méi)有被依賴任務(wù)阻塞blockedBy為空——這意味著 teammate 會(huì)自動(dòng)尊重任務(wù) DAG 的依賴順序這是文檔Try It第 3 條創(chuàng)建帶依賴的任務(wù)觀察 teammate 遵守阻塞順序的行為來(lái)源。認(rèn)領(lǐng)函數(shù)claim_task則通過(guò)全局_claim_lock線程鎖實(shí)現(xiàn)臨界區(qū)保護(hù)L140-L155def claim_task(task_id: int, owner: str) - str: with _claim_lock: path TASKS_DIR / ftask_{task_id}.json if not path.exists(): return fError: Task {task_id} not found task json.loads(path.read_text()) if existing_owner : task.get(owner): return fError: Task {task_id} has already been claimed by {existing_owner} if (status : task.get(status)) ! pending: return fError: Task {task_id} cannot be claimed because its status is {status} if task.get(blockedBy): return fError: Task {task_id} is blocked by other task(s) and cannot be claimed yet task[owner] owner task[status] in_progress path.write_text(json.dumps(task, indent2)) return fClaimed task #{task_id} for {owner}注意它是讀—校驗(yàn)—寫在同一把鎖內(nèi)完成多個(gè) teammate 同時(shí)輪詢到同一個(gè)無(wú)主任務(wù)時(shí)只有第一個(gè)寫入owner的成功其余拿到 already been claimed by ... 錯(cuò)誤。IDLE 輪詢中若認(rèn)領(lǐng)返回Error:前綴會(huì)continue重試下一輪L284-L286從而平滑處理認(rèn)領(lǐng)競(jìng)爭(zhēng)。這個(gè)原子性契約在當(dāng)前軌道的測(cè)試套件 tests/test_agent_teams_runtime.py 中有專門驗(yàn)證例如并發(fā)認(rèn)領(lǐng)同一任務(wù)時(shí)只有一個(gè) owner 成功test_inbox_delivery_is_runtime_owned、claim_task相關(guān)斷言。工作機(jī)制四上下文壓縮后的身份重注入這是 s11 獨(dú)有的一個(gè)防御性機(jī)制。當(dāng)上下文壓縮發(fā)生后messages列表會(huì)縮短teammate 可能丟失我是誰(shuí)、我的角色是什么的認(rèn)知。s11 的判據(jù)非常樸素消息數(shù)小于等于 3 條即認(rèn)為發(fā)生過(guò)壓縮此時(shí)在消息列表頭部插入身份塊if len(messages) 3: messages.insert(0, identity_block)身份塊構(gòu)造邏輯見(jiàn) make_identity_blockL159-L163def make_identity_block(name: str, role: str, team_name: str) - dict: return { role: user, content: fidentityYou are {name}, role: {role}, team: {team_name}. Continue your work./identity, }在實(shí)際調(diào)用點(diǎn)自動(dòng)認(rèn)領(lǐng)任務(wù)恢復(fù) WORK 時(shí)L291-L295注入的是一問(wèn)一答兩條消息讓角色設(shè)定以對(duì)話形式成立messages.insert(0, make_identity_block(name, role, team_name)) messages.insert(1, {role: assistant, content: fI am {name}. Continuing.})這個(gè)手法可以推廣為通用經(jīng)驗(yàn)長(zhǎng)生命周期 agent 的關(guān)鍵狀態(tài)身份、角色約束不應(yīng)只存在于 system prompt 或?qū)υ掗_(kāi)頭而應(yīng)在上下文被重寫后主動(dòng)重新錨定。相對(duì) s10 的變更清單文檔中的對(duì)照表完整如下是理解 s11 增量邊界的最快方式ComponentBefore (s10)After (s11)Tools1214 (idle, claim_task)AutonomyLead-directedSelf-organizingIdle phaseNonePoll inbox task boardTask claimingManual onlyAuto-claim unclaimed tasksIdentitySystem prompt re-injection after compressTimeoutNone60s idle - auto shutdown工具增量在源碼中可精確核對(duì)teammate 側(cè)工具池_teammate_toolsL342-L365在 s02 的四個(gè)基礎(chǔ)文件/終端工具bash、read_file、write_file、edit_file與 s09/s10 的協(xié)作工具send_message、read_inbox、shutdown_response、plan_approval之上新增idle與claim_task兩個(gè)工具lead 側(cè)分發(fā)表TOOL_HANDLERSL469-L484共 14 個(gè)條目其中 lead 調(diào)用idle會(huì)返回 Lead does not idle.lead 常駐不空閑lead 調(diào)用claim_task則把自己當(dāng)作 owner 認(rèn)領(lǐng)。新增工具輸入?yún)?shù)語(yǔ)義idle無(wú)聲明我手頭沒(méi)有工作了觸發(fā)進(jìn)入 IDLE 輪詢階段claim_tasktask_id: integer必填按 ID 原子認(rèn)領(lǐng)任務(wù)板上的任務(wù)運(yùn)行與驗(yàn)證運(yùn)行方式需先配置MODEL_ID等環(huán)境變量參見(jiàn) requirements.txt 與 README 的 Quick Startcd learn-claude-code python agents/s11_autonomous_agents.py進(jìn)入交互 REPL 后文檔給出的 5 條驗(yàn)證路徑Create 3 tasks on the board, then spawn alice and bob. Watch them auto-claim.—— 驗(yàn)證空閑輪詢 自動(dòng)認(rèn)領(lǐng)Spawn a coder teammate and let it find work from the task board itself—— 驗(yàn)證 spawn 時(shí)只給角色、不給具體任務(wù)Create tasks with dependencies. Watch teammates respect the blocked order.—— 驗(yàn)證blockedBy過(guò)濾輸入/tasks查看任務(wù)板含 owner 標(biāo)記輸入/team監(jiān)控各 teammate 處于 working 還是 idle。兩個(gè)斜杠命令的實(shí)現(xiàn)可直接閱讀/team打印TEAM.list_all()團(tuán)隊(duì)名 每個(gè)成員的名字/角色/狀態(tài)L564-L566/tasks遍歷.tasks/task_*.json用[ ]/[]/[x]標(biāo)記 pending/in_progress/completed 并附帶ownerL570-L577。團(tuán)隊(duì)狀態(tài)持久化在.team/config.json_set_status每次狀態(tài)遷移都會(huì)落盤因此進(jìn)程外也能觀察 teammate 生命周期。演進(jìn)視角當(dāng)前 17 課時(shí)軌道中的自治認(rèn)領(lǐng)需要說(shuō)明的適用前提README 指出本倉(cāng)庫(kù)存在兩條軌道——docs/與agents/是保留舊鏈接的Legacy 12 課時(shí)軌道根級(jí)s01_*–s17_*目錄是當(dāng)前軌道。按 Legacy-to-Current 映射表舊 s11 的autonomous task claiming并入新s13 Agent Teams。當(dāng)前實(shí)現(xiàn) s13_agent_teams/code.py 將同樣的 WORK/IDLE 思想工程化得更完整可作為進(jìn)階參照空閑掃描間隔縮短為IDLE_SCAN_INTERVAL 2.0秒L1053wait_for_work用阻塞式BUS.wait_for_messages等待消息無(wú)消息時(shí)調(diào)用claim_next_task原子認(rèn)領(lǐng)L1252-L1276認(rèn)領(lǐng)成功即以[Auto-claimed task ...]消息注入對(duì)話并附帶該任務(wù)綁定的工作目錄claim_next_task在task_lock下額外保證一個(gè) teammate同時(shí)只持有一個(gè)任務(wù)teammate_assignments已有分配則直接返回 NoneL1070-L1079并疊加了can_start依賴檢查與 worktree 可用性校驗(yàn)L1056-L1067。從源碼結(jié)構(gòu)看兩條軌道共享同一套核心契約——scan_unclaimed_taskspending、無(wú)主、未阻塞 鎖保護(hù)的claim_task 空閑輪詢恢復(fù)——差異主要在超時(shí)策略s11 硬編碼 60s 后 shutdown新軌道把生命周期交給 lead/用戶管理和并發(fā)語(yǔ)義的加固。設(shè)計(jì)要點(diǎn)回顧自治不來(lái)自新工具來(lái)自循環(huán)結(jié)構(gòu)idle和claim_task只是兩個(gè)小工具真正的機(jī)制是 IDLE 階段的輪詢 → 恢復(fù)/超時(shí)狀態(tài)機(jī)文件即協(xié)調(diào)介質(zhì).tasks/*.json與.team/inbox/*.jsonl讓多個(gè)線程未來(lái)甚至多進(jìn)程通過(guò)共享磁盤狀態(tài)協(xié)作_claim_lock保證單進(jìn)程內(nèi)原子性認(rèn)領(lǐng)必須冪等且可失敗認(rèn)領(lǐng)函數(shù)返回Error:前綴的軟錯(cuò)誤輪詢方以continue消化競(jìng)爭(zhēng)失敗而不是拋異常身份是需要在壓縮后重新注入的狀態(tài)len(messages) 3是一個(gè)低成本、可解釋的壓縮探測(cè)啟發(fā)式。延伸閱讀前序文檔 s10 團(tuán)隊(duì)協(xié)議 解釋了 shutdown/plan 兩種 request-response 握手s11 的 IDLE 輪詢中同樣會(huì)響應(yīng)shutdown_request以及 s09 Agent Teams 中 MessageBus 與 teammate 持久化的基礎(chǔ)設(shè)計(jì)?!久赓M(fèi)下載鏈接】learn-claude-codeBash is all you need - A nano claude code–like 「agent harness」, built from 0 to 1項(xiàng)目地址: https://gitcode.com/GitHub_Trending/an/learn-claude-code創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考