制如何驅(qū)動(dòng) Skill 自動(dòng)進(jìn)化)
1. 從一次 K8s 部署翻車說起Hermes Agent 的 Self-Improving 到底在解決什么如果你用過 OpenClaw 這類 Agent 框架大概率經(jīng)歷過這樣的場(chǎng)景第一次讓它部署一個(gè) Flask 應(yīng)用到 K8s它踩了 ImagePullBackOff 的坑你手動(dòng)糾正了第二次換個(gè)項(xiàng)目再部署它把同樣的坑又踩了一遍。Skill 是手寫的 Markdown 文件你不寫它就不會(huì)你寫了它也不會(huì)自己更新。Hermes Agent 在 OpenRouter 排行榜上增速 204%Top Coding Agents 排第一GitHub 從 0 到 106k Star靠的不是功能堆疊而是設(shè)計(jì)哲學(xué)上的分水嶺——它讓 Agent 干完活之后自動(dòng)把踩坑經(jīng)驗(yàn)提煉成可復(fù)用的 Skill下次遇到同類問題直接調(diào)用。用得越久能力越強(qiáng)。這篇文章拆解 Hermes Agent 源碼中 Self-Improving 與 Skill 模塊的協(xié)作鏈路給出可復(fù)制的源碼閱讀路徑和關(guān)鍵函數(shù)調(diào)用鏈并演示一次完整的 Skill 迭代驗(yàn)證動(dòng)作。適合想理解 Agent 自進(jìn)化原理的開發(fā)者也適合正在選型 Agent 框架的技術(shù)負(fù)責(zé)人。三個(gè)子系統(tǒng)撐起一個(gè)閉環(huán)Memory 是助手隨身帶的小本子記著老板喜歡喝美式這些事實(shí)Skill 是助手積累的操作手冊(cè)——部署 K8s 第 2 步一定要先推鏡像Nudge Engine 是定時(shí)響的鬧鐘提醒助手回頭想想有沒有什么值得記的。三者協(xié)作構(gòu)成一個(gè)完整的反饋回路。源碼倉(cāng)庫(kù)地址github.com/NousResearch/hermes-agent。下面按模塊拆解每一步都給出文件路徑和行號(hào)區(qū)間你可以直接對(duì)照閱讀。2. Memory 系統(tǒng)源碼拆解兩個(gè)文件如何定義 Agent 對(duì)你的全部認(rèn)知Memory 系統(tǒng)設(shè)計(jì)得很克制——兩個(gè)純文本文件用§分隔條目~/.hermes/memories/ ├── MEMORY.md # Agent 的個(gè)人筆記環(huán)境事實(shí)、項(xiàng)目約定、工具怪癖 └── USER.md # Agent 對(duì)用戶的認(rèn)知偏好、溝通風(fēng)格、工作習(xí)慣字符上限故意設(shè)得很緊MEMORY 限 2200 charsUSER 限 1375 chars。容量有限就迫使 Agent 挑重要的記不重要的自然被擠掉。對(duì)比 OpenClaw——它的 MEMORY.md 是純追加模式用幾個(gè)月就膨脹成幾萬行的怪獸文件找?guī)讉€(gè)月前的一句話只能笨拙地通讀全文。Hermes 的做法反過來容量有限就倒逼 Agent 做信息壓縮過時(shí)的自然被擠掉留下的都是高密度事實(shí)。具體實(shí)現(xiàn)上MemoryStore維護(hù)兩組平行狀態(tài)——實(shí)時(shí)可寫的條目列表和會(huì)話開始時(shí)凍結(jié)的快照# tools/memory_tool.py:116-122 class MemoryStore: def __init__(self, memory_char_limit2200, user_char_limit1375): self.memory_entries: List[str] [] self.user_entries: List[str] [] self.memory_char_limit memory_char_limit self.user_char_limit user_char_limit self._system_prompt_snapshot: Dict[str, str] {memory: , user: }但設(shè)了上限只是第一步關(guān)鍵是超限之后怎么處理。Hermes 不會(huì)靜默丟棄舊條目也不會(huì)自動(dòng)壓縮——它選擇讓add直接失敗然后把當(dāng)前所有條目返回給模型# tools/memory_tool.py:248-259 if new_total limit: current self._char_count(target) return { success: False, error: ( fMemory at {current:,}/{limit:,} chars. fAdding this entry ({len(content)} chars) would exceed the limit. fReplace or remove existing entries first. ), current_entries: entries, usage: f{current:,}/{limit:,}, }錯(cuò)誤信息里一句 Replace or remove existing entries first 就把模型引導(dǎo)到了replace和remove操作上。同時(shí)返回current_entries讓模型能看到現(xiàn)有的所有條目自己決定哪些過時(shí)了該刪、哪些可以合并壓縮。模型不是被動(dòng)地執(zhí)行淘汰規(guī)則而是主動(dòng)做信息整理——這本身就是一次自我反思。凍結(jié)快照機(jī)制也值得注意。每次會(huì)話啟動(dòng)時(shí)Memory 加載后立刻捕獲一份快照之后系統(tǒng)提示詞里用的都是這份快照# tools/memory_tool.py:124-140 def load_from_disk(self): mem_dir get_memory_dir() self.memory_entries self._read_file(mem_dir / MEMORY.md) self.user_entries self._read_file(mem_dir / USER.md) # 會(huì)話開始時(shí)凍結(jié)快照之后不再變動(dòng) self._system_prompt_snapshot { memory: self._render_block(memory, self.memory_entries), user: self._render_block(user, self.user_entries), }快照注入系統(tǒng)提示詞后Agent 還沒看到用戶消息就已經(jīng)知道你的環(huán)境和偏好了。為什么凍結(jié)而不是實(shí)時(shí)更新因?yàn)橄到y(tǒng)提示詞會(huì)話內(nèi)不變就能共享前綴緩存Prefix Cache省掉重復(fù)計(jì)費(fèi)。新寫入的內(nèi)容只改磁盤下一個(gè)會(huì)話才刷新進(jìn)來。提示詞引導(dǎo)方面系統(tǒng)提示詞中的MEMORY_GUIDANCE明確了什么該記、什么不該記# agent/prompt_builder.py:144-162 MEMORY_GUIDANCE ( You have persistent memory across sessions. Save durable facts using the memory tool: user preferences, environment details, tool quirks, and stable conventions.\n Prioritize what reduces future user steering — the most valuable memory is one that prevents the user from having to correct or remind you again.\n Write memories as declarative facts, not instructions to yourself. User prefers concise responses ? — Always respond concisely ?. Project uses pytest with xdist ? — Run tests with pytest -n 4 ?. )注意這里的區(qū)別Memory 要求寫成聲明式事實(shí)User prefers concise responses而不是命令式指令A(yù)lways respond concisely。前者是偏好可以被當(dāng)前上下文覆蓋后者是死命令會(huì)限制 Agent 的靈活性。Tool Schema 里還有一句關(guān)鍵的邊界規(guī)則If youve discovered a new way to do something, save it as a skill. —— Memory 不存操作步驟操作步驟歸 Skill 管。這一句話把兩個(gè)系統(tǒng)的分工畫清了。3. Skill 模塊源碼拆解從 SKILL.md 結(jié)構(gòu)到自動(dòng)創(chuàng)建觸發(fā)條件Memory 是我知道什么Skill 是我會(huì)做什么。每個(gè) Skill 是一個(gè)目錄核心是 SKILL.md 文件~/.hermes/skills/ ├── devops/ │ └── flask-k8s-deploy/ │ ├── SKILL.md # 主指令 │ ├── references/ # 參考文檔 │ └── templates/ # 模板文件 └── software-development/ └── fix-pytest-fixtures/ └── SKILL.md一個(gè)典型的 SKILL.md--- name: flask-k8s-deploy description: Deploy a Flask app to Kubernetes with health checks version: 1.0.0 --- # Flask K8s Deployment ## When to use - User wants to deploy a Flask/Python app to Kubernetes - User mentions K8s, kubectl, or container deployment ## Steps 1. Create Dockerfile with gunicorn (not dev server) 2. Build and push image to registry BEFORE creating deployment 3. Write deployment.yaml with livenessProbe pointing to /health 4. Write service.yaml with correct port mapping 5. kubectl apply both files 6. Verify with kubectl get pods and kubectl logs ## Pitfalls - MUST push image to registry before kubectl apply, otherwise ImagePullBackOff - Flask 默認(rèn)沒有 /health 端點(diǎn)需要手動(dòng)添加 - Django 需要額外設(shè)置 ALLOWED_HOSTS 環(huán)境變量 - livenessProbe path 必須返回 200不能用需要認(rèn)證的路徑Pitfalls 這一節(jié)不是預(yù)先寫好的而是 Agent 踩坑后追加的——這就是 Skill 層面的self-improving。Agent 不需要用戶說幫我創(chuàng)建一個(gè) Skill。驅(qū)動(dòng)力來自skill_manage工具的 schema# tools/skill_manager_tool.py:681-701 SKILL_MANAGE_SCHEMA { name: skill_manage, description: ( Manage skills (create, update, delete). Skills are your procedural memory — reusable approaches for recurring task types.\n\n Create when: complex task succeeded (5 calls), errors overcome, user-corrected approach worked, non-trivial workflow discovered, or user asks you to remember a procedure.\n Update when: instructions stale/wrong, OS-specific failures, missing steps or pitfalls found during use. If you used a skill and hit issues not covered by it, patch it immediately with skill_manage(actionpatch) — dont wait to be asked.\n\n After difficult/iterative tasks, offer to save as a skill. Skip for simple one-offs. ), }創(chuàng)建的門檻設(shè)得比較清晰工具調(diào)用超過 5 次才值得創(chuàng)建簡(jiǎn)單任務(wù)不記、踩過坑再修復(fù)的經(jīng)驗(yàn)才有價(jià)值、用戶糾正過的做法要銘記。OpenClaw 也有 Skill 系統(tǒng)也是 SKILL.md YAML frontmatter但 Skill 要么是你手寫的要么是從社區(qū)裝的。手寫的成本高懶得維護(hù)社區(qū)裝的不是針對(duì)你的環(huán)境。關(guān)鍵問題是Agent 本身不會(huì)從工作中學(xué)到任何東西——干了一百次部署第一百零一次犯的錯(cuò)跟第一次一模一樣。HN 上有個(gè)帖子叫 Data Is the Final Moat——當(dāng)模型智能被商品化、Agent 框架被開源真正的護(hù)城河是 Agent 在工作中積累的領(lǐng)域知識(shí)。OpenClaw 的 Skill 是手寫的配置文件用了一年還是那份手寫的配置文件Hermes 的 Skill 是越用越厚的經(jīng)驗(yàn)資產(chǎn)——每一次踩坑都在加固護(hù)城河。這不是 OpenClaw 團(tuán)隊(duì)不想做而是它的架構(gòu)沒有為Agent 自主學(xué)習(xí)預(yù)留通路——沒有創(chuàng)建觸發(fā)、沒有 patch 機(jī)制、沒有 review agent。要補(bǔ)這一課是要重寫核心架構(gòu)。Hermes 這邊Agent 踩了坑、修了 bug、用了 12 次工具調(diào)用才搞定一個(gè)部署——這些經(jīng)驗(yàn)被自動(dòng)提煉成 Skill下次再遇到同類任務(wù)就是 6 次調(diào)用零錯(cuò)誤。系統(tǒng)提示詞里還有一句 Skills that arent maintained become liabilities——通過提示詞給 Agent 灌輸責(zé)任感防止它只管創(chuàng)建不管維護(hù)。當(dāng) Agent 按照已有 Skill 執(zhí)行但中途發(fā)現(xiàn)步驟有遺漏或者踩了新坑時(shí)它會(huì)在完成任務(wù)后回頭修補(bǔ) Skill。不是全量重寫而是做精確的局部 patch# tools/skill_manager_tool.py:397-485 def _patch_skill(name, old_string, new_string, file_pathNone, replace_allFalse): Targeted find-and-replace within a skill file. from tools.fuzzy_match import fuzzy_find_and_replace new_content, match_count, _strategy, match_error fuzzy_find_and_replace( content, old_string, new_string, replace_all ) if match_error: return {success: False, error: match_error, file_preview: content[:500]} # ...省略 _validate_content_size、_validate_frontmatter 等校驗(yàn) # 修改前備份原內(nèi)容 original_content content _atomic_write_text(target, new_content) # 修改后重新做安全掃描 scan_error _security_scan_skill(skill_dir) if scan_error: _atomic_write_text(target, original_content) # 不通過就回滾 return {success: False, error: scan_error}這里用了fuzzy_find_and_replace做模糊匹配——Agent 給出的old_string可能跟原文有格式差異模糊匹配能容忍這些差異。每次修改后還要跑一遍_security_scan_skill()不通過就自動(dòng)回滾。Agent 在踩完坑的當(dāng)場(chǎng)就把 Pitfalls 補(bǔ)上了下次同事遇到同樣的場(chǎng)景直接繞過去。Skill 多了以后不能全塞進(jìn)系統(tǒng)提示詞——這也是 OpenClaw 的一個(gè)痛點(diǎn)它采用全量背包模式每次會(huì)話把 SOUL.md、IDENTITY.md 和各種設(shè)定一股腦塞進(jìn)上下文設(shè)定越多背包越沉Token 浪費(fèi)嚴(yán)重模型注意力也被稀釋。Hermes 更像一座動(dòng)態(tài)圖書館默認(rèn)上下文極其輕量只放一個(gè)輕量索引——每個(gè) Skill 的名字和一句描述Available skills: devops: - flask-k8s-deploy: Deploy a Flask app to Kubernetes with health checks - nginx-reverse-proxy: Configure Nginx reverse proxy with SSL software-development: - fix-pytest-fixtures: Debug and fix pytest fixture scope issuesAgent 判斷某個(gè) Skill 跟當(dāng)前任務(wù)相關(guān)時(shí)才通過skill_view加載完整內(nèi)容。先看目錄再翻全文按需加載。4. Nudge Engine 與后臺(tái) fork反饋回路如何自動(dòng)觸發(fā) Skill 迭代Memory 和 Skill 都是存儲(chǔ)系統(tǒng)寫入需要有人觸發(fā)。Nudge Engine 就是這個(gè)觸發(fā)器——運(yùn)行時(shí)維護(hù)兩個(gè)計(jì)數(shù)器定時(shí)提醒 Agent 該停下來想想了。兩個(gè)計(jì)數(shù)器兩種粒度# run_agent.py:1328-1331 — Memory 計(jì)數(shù)器 self._memory_nudge_interval 10 # 每 10 個(gè)用戶回合觸發(fā)一次 self._turns_since_memory 0 # run_agent.py:1428-1431 — Skill 計(jì)數(shù)器從配置讀取默認(rèn) 10 self._skill_nudge_interval int(skills_config.get(creation_nudge_interval, 10)) self._iters_since_skill 0粒度不同是有道理的Memory 的信息來自用戶輸入按回合計(jì)Skill 的經(jīng)驗(yàn)來自工具使用過程按迭代計(jì)。計(jì)數(shù)器到閾值就觸發(fā)審查Agent 主動(dòng)調(diào)用了 memory 或 skill_manage 則重置——已經(jīng)在做了就不用催。Nudge 觸發(fā)后怎么處理它不會(huì)在主對(duì)話中插一條讓我想想有沒有什么該記的——那樣太打擾用戶了。而是在后臺(tái) fork 一個(gè)獨(dú)立的 Agent 實(shí)例拿著主對(duì)話的快照去做審查# run_agent.py:2665-2711 def _spawn_background_review(self, messages_snapshot, review_memoryFalse, review_skillsFalse): def _run_review(): with open(os.devnull, w) as _devnull, \ contextlib.redirect_stdout(_devnull), \ contextlib.redirect_stderr(_devnull): review_agent AIAgent( modelself.model, max_iterations8, quiet_modeTrue, ) review_agent._memory_store self._memory_store review_agent._memory_enabled self._memory_enabled review_agent._user_profile_enabled self._user_profile_enabled # 禁用 review agent 自身的 nudge否則會(huì)無限遞歸 review_agent._memory_nudge_interval 0 review_agent._skill_nudge_interval 0 review_agent.run_conversation( user_messageprompt, conversation_historymessages_snapshot, ) thread threading.Thread(target_run_review, daemonTrue) thread.start()幾個(gè)細(xì)節(jié)輸出重定向到/dev/null用戶完全無感知最多 8 次工具調(diào)用不會(huì)無限消耗 APIreview agent 自身的 nudge 被禁用避免無限遞歸和主 agent 共享同一份 Memory寫入直接生效。干活和反思拆成兩個(gè)實(shí)例互不干擾。Review Agent 靠?jī)商讓彶樘崾驹~決定做什么Memory Review 關(guān)注用戶偏好和個(gè)人信息Skill Review 關(guān)注非平凡的解題過程。每個(gè) prompt 都以 If nothing is worth saving, just say Nothing to save. and stop. 收尾——防止 review agent 每次都往里塞東西來交差。審查在響應(yīng)發(fā)送給用戶之前才觸發(fā)用戶收到回復(fù)后該干嘛干嘛Agent 在后臺(tái)默默復(fù)盤。完整案例從不會(huì)到精通的三次會(huì)話。用一個(gè) K8s 部署場(chǎng)景串一下三個(gè)子系統(tǒng)的協(xié)同。第 1 次會(huì)話冷啟動(dòng)。用戶說幫我把這個(gè) Flask 應(yīng)用部署到 K8s 集群。Memory 和 Skills 都是空的Agent 靠基座知識(shí)摸索12 次工具調(diào)用踩了兩個(gè)坑iter1: terminal(kubectl version) → 確認(rèn)集群版本 iter2: read_file(app.py) → 讀取應(yīng)用代碼 iter3: write_file(Dockerfile) → 創(chuàng)建 Dockerfile iter4: terminal(docker build -t myapp .) → 構(gòu)建鏡像 iter5: write_file(deployment.yaml) → 編寫 K8s 部署文件 iter6: terminal(kubectl apply -f deployment.yaml) → ImagePullBackOff忘記推鏡像到 registry iter7: terminal(docker push myregistry.azurecr.io/myapp) iter8: terminal(kubectl apply -f deployment.yaml) → 重新部署 iter9: write_file(service.yaml) → 編寫 Service iter10: terminal(kubectl apply -f service.yaml) iter11: terminal(kubectl get pods) → CrashLoopBackOfflivenessProbe 路徑不對(duì) iter12: 修改 deployment.yaml → 重新部署 → 成功12 次迭代觸發(fā) Skill ReviewReview Agent 看到兩次報(bào)錯(cuò)和修復(fù)過程創(chuàng)建了一個(gè) SkillReview Agent 執(zhí)行: → skill_manage(actioncreate, nameflask-k8s-deploy, categorydevops, content --- name: flask-k8s-deploy description: Deploy a Flask app to Kubernetes with health checks --- ## Steps 1. Create Dockerfile with gunicorn 2. Build and push image to registry BEFORE kubectl apply 3. Write deployment.yaml with livenessProbe → /health ... ## Pitfalls - MUST push image to registry first, otherwise ImagePullBackOff - Flask 默認(rèn)沒有 /health 端點(diǎn)需手動(dòng)添加 - livenessProbe path 必須返回 200 )安全掃描通過后寫入磁盤用戶對(duì)這一切毫不知情。第 2 次會(huì)話Skill 復(fù)用 自我修補(bǔ)。用戶說幫我再部署一個(gè) Django 應(yīng)用到 K8s。系統(tǒng)提示詞里多了 Skills 索引Agent 加載flask-k8s-deploy后照著步驟做iter1: skill_view(flask-k8s-deploy) → 加載完整 Skill iter2: read_file(manage.py) → 確認(rèn) Django 項(xiàng)目結(jié)構(gòu) iter3: write_file(Dockerfile) → 用 gunicornSkill 指示 iter4: 添加 /health 端點(diǎn)Skill Pitfalls 提醒 iter5: terminal(docker build docker push) → 先 push 再 applySkill Steps 第2步 iter6: write_file(deployment.yaml) → livenessProbe → /health iter7: terminal(kubectl apply) → DisallowedHost 錯(cuò)誤Django 特有的問題Skill 沒覆蓋 iter8: 修改 deployment.yaml 添加 ALLOWED_HOSTS env iter9: terminal(kubectl apply) → 成功從 12 次調(diào)用降到 9 次已知坑被繞過但遇到 Django 特有的新坑。Review Agent 一口氣做了三件事寫入用戶畫像、記住 registry 地址、patch Skill 補(bǔ)上 ALLOWED_HOSTS 坑。第 3 次會(huì)話零錯(cuò)誤一次搞定。用戶說幫我部署一個(gè)新的 FastAPI 微服務(wù)。Agent 已經(jīng)知道你是誰、registry 在哪、集群在哪Skill 里也包含了 ALLOWED_HOSTS 的坑——6 次調(diào)用零錯(cuò)誤。三次對(duì)比維度會(huì)話 1 (冷啟動(dòng))會(huì)話 2 (Skill 復(fù)用)會(huì)話 3 (全自愈)工具調(diào)用12 次9 次6 次錯(cuò)誤數(shù)210Memory無觸發(fā)寫入系統(tǒng)提示詞注入Skill觸發(fā)創(chuàng)建復(fù)用 自我修補(bǔ)復(fù)用已修補(bǔ)版本在開源 Hermes 中這些經(jīng)驗(yàn)積累在單個(gè)用戶的~/.hermes/目錄下。RDSHermes 把 Skill 存儲(chǔ)從本地磁盤搬到了云端——一個(gè) DBA 踩過的坑團(tuán)隊(duì)里所有人的 Agent 都能繞過。自我進(jìn)化不再是單點(diǎn)的而是組織級(jí)的。5. 常見報(bào)錯(cuò)排查401、local proxy failed、reading choices 與 OAuth 失效在跑通 Hermes Agent 的 Self-Improving 鏈路之前接入層的問題往往先卡住你。下面按真實(shí)報(bào)錯(cuò)對(duì)照排查。401 Unauthorized / invalid_api_key。最常見的原因是 Base URL 和 Key 不匹配。如果你用的是 TaoToken 的 API 網(wǎng)關(guān)Base URL 必須寫成https://taotoken.net/apiKey 從控制臺(tái)的 API Keys 頁(yè)面生成。檢查配置文件里base_url和api_key是否成對(duì)出現(xiàn)以及 Key 是否帶了多余空格。用 curl 快速驗(yàn)證curl https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d {model:claude-sonnet-4-20250514,messages:[{role:user,content:ping}]}返回 200 且 choices 數(shù)組非空說明 Key 和 Base URL 都沒問題。local proxy failed / connection refused。這個(gè)報(bào)錯(cuò)通常出現(xiàn)在你配置了本地代理端口但代理進(jìn)程沒起來。檢查config.yaml里是否殘留了proxy: http://127.0.0.1:xxxx這類配置。如果你不需要本地代理直接刪掉這一行。Hermes 默認(rèn)走直連不需要額外代理層。reading choices 報(bào)錯(cuò) / KeyError: choices。這通常意味著上游返回的不是標(biāo)準(zhǔn) OpenAI 格式的響應(yīng)??赡茉蚰P?ID 寫錯(cuò)了網(wǎng)關(guān)返回了錯(cuò)誤 JSON或者 Base URL 少了/v1路徑。確認(rèn)你的 Model ID 跟網(wǎng)關(guān)支持的列表一致比如claude-sonnet-4-20250514、gpt-4o這類。用模型對(duì)話頁(yè)面先手動(dòng)測(cè)一次確認(rèn)模型可用再寫進(jìn)配置。OAuth token expired / Claude Code 認(rèn)證失敗。如果你在用 Claude Code 接入認(rèn)證走的是 Anthropic 的 OAuth 流程。token 過期后需要重新走一遍授權(quán)。檢查~/.claude/下的憑證文件是否還在有效期內(nèi)。如果頻繁過期考慮改用 API Key 方式接入穩(wěn)定性更好。CC Switch / Cline MCP / Codex auth.json 三件套配置。如果你在 Hermes 里掛 MCP Server 或者用 CC Switch 管理多套配置記住每個(gè)接入點(diǎn)都需要三樣?xùn)|西Base URL、API Key、Model ID。以 Codex 的auth.json為例{ base_url: https://taotoken.net/api, api_key: sk-xxxxxxxx, model: claude-sonnet-4-20250514 }Cline 的 MCP 配置在settings.json里{ mcpServers: { hermes: { command: npx, args: [-y, hermes/mcp-server], env: { HERMES_BASE_URL: https://taotoken.net/api, HERMES_API_KEY: sk-xxxxxxxx, HERMES_MODEL: claude-sonnet-4-20250514 } } } }CC Switch 的配置文件里同樣需要這三項(xiàng)對(duì)齊。任何一項(xiàng)缺失或?qū)戝e(cuò)都會(huì)導(dǎo)致 401 或 reading choices 報(bào)錯(cuò)。Skill 創(chuàng)建后不生效。檢查~/.hermes/skills/目錄下是否有對(duì)應(yīng)的 SKILL.md 文件以及 YAML frontmatter 里的name和description是否完整。如果安全掃描沒通過文件會(huì)被回滾磁盤上不會(huì)留下痕跡。查看日志里有沒有Security scan blocked this skill的輸出。Nudge 不觸發(fā)。確認(rèn)config.yaml里creation_nudge_interval的值默認(rèn)是 10。如果你把值設(shè)得太大比如 100短時(shí)間內(nèi)不會(huì)觸發(fā)審查。另外如果 Agent 在會(huì)話中已經(jīng)主動(dòng)調(diào)用了skill_manage計(jì)數(shù)器會(huì)重置不會(huì)重復(fù)觸發(fā)。6. 把 Self-Improving 能力接進(jìn)你的工作流Hermes Agent 的 Self-Improving 就是三件事的配合Memory 記住你是誰Skill 記住怎么做Nudge Engine 保證這個(gè)循環(huán)不停轉(zhuǎn)。用得越久Agent 幫你干活就越快、踩坑就越少。如果你想在自己的項(xiàng)目里復(fù)現(xiàn)這套機(jī)制源碼閱讀路徑建議按這個(gè)順序先看tools/memory_tool.py理解存儲(chǔ)和上限控制再看tools/skill_manager_tool.py理解創(chuàng)建和 patch 流程最后看run_agent.py里的 nudge 計(jì)數(shù)器和后臺(tái) fork 邏輯。三個(gè)文件加起來不到 2000 行一個(gè)下午能讀完。接入層用 TaoToken 的 API 網(wǎng)關(guān)Base URL 寫https://taotoken.net/apiKey 在控制臺(tái)的 API Keys 頁(yè)面生成。模型 ID 根據(jù)你的任務(wù)選編碼類任務(wù)用claude-sonnet-4-20250514通用任務(wù)用gpt-4o。配置寫好后先用模型對(duì)話頁(yè)面手動(dòng)驗(yàn)證一次確認(rèn)返回正常再寫進(jìn) Hermes 的config.yaml。如果你需要長(zhǎng)期跑編碼 Agent 或者多 Agent 協(xié)作Coding Plan 的額度更劃算適合持續(xù)迭代的場(chǎng)景。接入文檔里有完整的配置示例和排錯(cuò)指南遇到 401 或 reading choices 報(bào)錯(cuò)先對(duì)照文檔檢查 Base URL、Key、Model ID 三件套是否對(duì)齊。自我進(jìn)化不是魔法是一套設(shè)計(jì)良好的反饋回路在持續(xù)運(yùn)轉(zhuǎn)。理解了這個(gè)回路你就能在自己的 Agent 項(xiàng)目里復(fù)現(xiàn)它。