目 04 實(shí)戰(zhàn):以運(yùn)行時(shí)反饋與架構(gòu)約束修正 Agent 行為——增量索引的可觀測(cè)性工程)
【免費(fèi)下載鏈接】learn-harness-engineeringHarness engineering beginner tutorial, from 0 to 1項(xiàng)目地址https://gitcode.com/gh_mirrors/le/learn-harness-engineering點(diǎn)擊查看免費(fèi)下載本篇是 learn-harness-engineering 教程中「Project 04: Runtime Feedback and Structural Control」的完整實(shí)戰(zhàn)指南對(duì)應(yīng)日文版 docs/ja/projects/project-04-incremental-indexing/index.md中文版 projects/project-04/README-CN.md。它承接 Project 03 的知識(shí)庫(kù)應(yīng)用教你為 Agent 補(bǔ)齊運(yùn)行時(shí)可觀測(cè)性啟動(dòng)日志、導(dǎo)入/索引日志、錯(cuò)誤狀態(tài)與層級(jí)邊界約束防越界架構(gòu)檢查并在一個(gè)被刻意植入缺陷的索引服務(wù)上完成「診斷 → 修復(fù) → 驗(yàn)證」的完整閉環(huán)。讀完本文你將掌握結(jié)構(gòu)化日志、分層架構(gòu)護(hù)欄腳本、增量索引機(jī)制以及一套可復(fù)現(xiàn)的「同一任務(wù)跑兩遍」的 Harness 實(shí)驗(yàn)方法。為什么 Agent 需要運(yùn)行時(shí)反饋本項(xiàng)目的核心命題在 Project 0103 中我們已經(jīng)驗(yàn)證了能力再?gòu)?qiáng)的 Agent 也會(huì)失敗它看不見(jiàn)自己程序的運(yùn)行時(shí)狀態(tài)只能靠猜測(cè)。Project 04 直接把這個(gè)痛點(diǎn)做成了一門(mén)調(diào)試課——給 Agent 配上眼睛結(jié)構(gòu)化日志和邊界架構(gòu)檢查腳本再讓它去修復(fù)一個(gè)被植入的運(yùn)行時(shí)缺陷。相關(guān)講義的論證是Agent 的失敗常常源于任務(wù)邊界模糊講義 07與缺乏約束的工作范圍講義 08。Project 04 把這兩條教訓(xùn)落成具體產(chǎn)物運(yùn)行時(shí)反饋Runtime Feedback服務(wù)啟動(dòng)、文檔導(dǎo)入、增量索引、QA 問(wèn)答每個(gè)環(huán)節(jié)都輸出機(jī)器可解析的 JSON 日志Agent 不再盲修范圍控制Scope Control用check-architecture.sh強(qiáng)制 renderer / preload / main / services 四層各守其責(zé)Agent 的改動(dòng)無(wú)法越界增量索引Incremental Indexing索引服務(wù)按文檔粒度增量推進(jìn)配合index-meta.json記錄已索引狀態(tài)讓長(zhǎng)任務(wù)可以分段收斂。這套組合正是本項(xiàng)目的Harness 機(jī)制ランタイムフィードバック スコープ制御 増分インデックス運(yùn)行時(shí)反饋 范圍控制 增量索引。任務(wù)總覽同一份工作跑兩遍原文檔給出的任務(wù)非常明確——同一份工作執(zhí)行兩次第一遍對(duì)照組在沒(méi)有任何日志與架構(gòu)約束的環(huán)境下讓 Agent 完成修復(fù)觀察它要花多久才能抵達(dá)根本原因第二遍實(shí)驗(yàn)組在配有結(jié)構(gòu)化日志、架構(gòu)邊界文檔與檢查腳本的環(huán)境下讓同一 Agent 完成修復(fù)對(duì)比 logs 與 boundary checks 是否讓修復(fù)更快、影響范圍更小。這種A/B 對(duì)照正是 Harness 工程的核心方法論不靠口號(hào)判斷工具鏈價(jià)值而是用可重復(fù)的實(shí)驗(yàn)數(shù)據(jù)說(shuō)話。合格的解法必須有診斷證據(jù)日志輸出、檢查腳本通過(guò)記錄而不只是口頭聲稱修好了。動(dòng)手前需要準(zhǔn)備的環(huán)境原文檔ツール一節(jié)工具用途Claude Code 或 Codex作為被測(cè)的編碼 AgentGit記錄變更、回滾實(shí)驗(yàn)、對(duì)比兩遍結(jié)果Node.js Electron運(yùn)行 Electron 知識(shí)庫(kù)應(yīng)用依賴見(jiàn) solution/package.json含 react 18、electron 33、vite 6、vitest 2starter 與 solution一個(gè)弱信號(hào)起點(diǎn) vs 一個(gè)護(hù)欄完備的參考實(shí)現(xiàn)倉(cāng)庫(kù)中項(xiàng)目位于 projects/project-04/包含兩個(gè)可運(yùn)行的完整切片目錄包含什么實(shí)驗(yàn)要對(duì)比的量starter/基于 Project 03 的代碼診斷信號(hào)弱IndexingService中被植入了 indexing 缺陷超過(guò) 1000 字符的大文件 chunking 會(huì)被破壞沒(méi)有架構(gòu)檢查腳本在沒(méi)有運(yùn)行時(shí)信號(hào)的情況下Agent 抵達(dá)根本原因所需的時(shí)間solution/結(jié)構(gòu)化 logger、架構(gòu)邊界文檔與檢查腳本、已修復(fù)的 chunking 邏輯、clean-state-checklist.mdlogs 與 boundary checks 是否讓修復(fù)更快、影響范圍更小兩者的差異可以精確對(duì)應(yīng)到具體文件對(duì)照 README-CN.md 的任務(wù)對(duì)應(yīng)表功能 / 產(chǎn)物starter 狀態(tài)solution 證據(jù)結(jié)構(gòu)化日志無(wú)共享 logger 服務(wù)僅零散console.logsrc/services/logger.ts 及 main、ipc-handlers、各 services 中的日志調(diào)用導(dǎo)入/索引診斷運(yùn)行輸出難以定位失敗導(dǎo)入、索引開(kāi)始/完成、QA 失敗路徑的結(jié)構(gòu)化日志架構(gòu)邊界無(wú)腳本檢查 renderer/main/service 越界scripts/check-architecture.sh、docs/ARCHITECTURE.md、AGENTS 邊界規(guī)則植入的 chunking bug大文件可能產(chǎn)生空 chunk修復(fù)后的 src/services/indexing-service.ts干凈交接無(wú)最終檢查清單clean-state-checklist.md提示solution 刻意保持比后續(xù)項(xiàng)目更精簡(jiǎn)的 Harness。按 AGENTS.md 的說(shuō)明本項(xiàng)目不包含feature_list.json、claude-progress.md、init.sh、session-handoff.md——那些產(chǎn)物在更后面的項(xiàng)目階段才引入。做本項(xiàng)目時(shí)不要臆造這些文件存在。運(yùn)行時(shí)可觀測(cè)性落地解剖結(jié)構(gòu)化 Logger原文檔點(diǎn)名要重點(diǎn)研讀 projects/project-04/solution/src/services/logger.ts。它是本項(xiàng)目運(yùn)行時(shí)反饋的基石把原來(lái)不可解析的散亂輸出統(tǒng)一為帶時(shí)間戳、分級(jí)、可 JSON 解析的日志條目。核心設(shè)計(jì)如下對(duì)照源碼逐段解讀四個(gè)日志級(jí)別DEBUG、INFO、WARN、ERRORLogLevel枚舉源碼 L9-L14并按LEVEL_ORDER定義優(yōu)先級(jí)順序L26-L31日志條目結(jié)構(gòu)LogEntryL16-L22timestampISO 8601、level、service服務(wù)名、message、可選data任意結(jié)構(gòu)化字段Recordstring, unknown級(jí)別過(guò)濾shouldLog()用級(jí)別序號(hào)比較低于最小級(jí)別默認(rèn)DEBUG的日志直接丟棄避免噪音淹沒(méi)信號(hào)L37-L41按級(jí)別分流輸出emit()中ERROR走console.error、WARN走console.warn、其余走console.log且全部輸出 JSON 字符串L43-L56保證 stdout/stderr 都能被工具鏈如grep、jq繼續(xù)消費(fèi)服務(wù)級(jí)子 loggerforService(name)返回ServiceLogger讓每個(gè)服務(wù)只傳消息與數(shù)據(jù)、自動(dòng)帶上服務(wù)名L91-L121例如IndexingService內(nèi)部持有l(wèi)ogger.forService(IndexingService)可配置最小級(jí)別單例logger從環(huán)境變量LOG_LEVEL讀取最小級(jí)別缺省DEBUGL123-L126意味著可以用LOG_LEVELERROR npm run dev一鍵壓噪或LOG_LEVELDEBUG全量觀測(cè)。// 實(shí)際調(diào)用形態(tài)摘自 solution 各服務(wù) this.log.info(Indexing document, { docId: doc.id, title: doc.title, contentLength: content.length }); this.log.error(Document content not found, { documentId });這種每條日志都自帶 service 結(jié)構(gòu)化 data的做法直接服務(wù)于 AGENTS.md 的調(diào)試指引排查時(shí)檢查服務(wù)初始化事件、IPC 調(diào)用及其參數(shù)、索引 chunk 數(shù)與內(nèi)容長(zhǎng)度、QA 置信度與 citation 數(shù)量。架構(gòu)約束四層邊界與 check-architecture.sh 源碼拆解ARCHITECTURE.md 定義的四層模型docs/ARCHITECTURE.md 把 Electron 應(yīng)用明確劃分為四層自頂向下Renderer (React UI) → Preload (contextBridge) → Main Process (IPC Handlers) → Services (Business Logic) → Persistence (Filesystem)每層職責(zé)與紅線不可越界層職責(zé)約束MUST NOTRenderersrc/renderer/渲染 React 組件、處理用戶輸入、通過(guò)window.knowledgeBaseAPI 與主進(jìn)程通信不得 importfs/path/os/child_process等 Node 核心模塊不得直接訪問(wèn) Electron API不得承載業(yè)務(wù)邏輯Preloadsrc/preload/用contextBridge.exposeInMainWorld暴露類(lèi)型化 API映射 IPC 通道名不得包含業(yè)務(wù)邏輯不得直接 import services只用ipcRenderer.invokeMain Processsrc/main/創(chuàng)建管理 BrowserWindow、注冊(cè) IPC handler 并委托給 services不得承載路由之外的業(yè)務(wù)邏輯不直接訪問(wèn)持久化層Servicessrc/services/實(shí)現(xiàn)全部業(yè)務(wù)邏輯文檔管理、索引、QA不得 import Electron APIipcMain、BrowserWindow等不得 import React所有文件系統(tǒng)訪問(wèn)必須經(jīng)PersistenceService所有 IPC 通信的通道名收斂在 src/shared/types.ts 的IPC_CHANNELS常量單一事實(shí)來(lái)源例如documents:list、documents:import、indexing:start、indexing:chunks、qa:ask等。數(shù)據(jù)流方向固定Renderer 調(diào)用window.knowledgeBase.*→ Preload 轉(zhuǎn)成ipcRenderer.invoke(channel, ...)→ Main 的 IPC handler 委托給 service → service 經(jīng)PersistenceService落盤(pán) → 結(jié)果沿 IPC 返回渲染層。check-architecture.sh 的三種越界檢查scripts/check-architecture.sh 用純 bash 實(shí)現(xiàn)了架構(gòu)護(hù)欄set -euo pipefail保證失敗即退出退出碼 0 全部通過(guò)1 存在違規(guī)。它做三件事檢查 renderer 是否 import Node 核心模塊遍歷src/renderer下所有.ts/.tsx用grep -qE import.*\b(fs|path|os|child_process)\b命中即記為違規(guī)L21-L33檢查 services 是否觸碰 Electron遍歷src/services下.ts既查import ... from electron也查ipcMain、ipcRenderer、BrowserWindow關(guān)鍵字L36-L56檢查 services/main 是否 import React遍歷src/services src/main下的.ts命中import ... from react即違規(guī)L59-L74。腳本末尾匯總違規(guī)數(shù)并按結(jié)果exit 0/1L78-L85因此它可以無(wú)縫掛進(jìn) CI 或 Agent 的 pre-commit 流程。這正好把 ARCHITECTURE.md 文檔化的規(guī)則變成了可執(zhí)行、可證偽的檢查——Agent 想偷偷越界腳本會(huì)當(dāng)場(chǎng)攔下。bash scripts/check-architecture.sh # 期望輸出PASS: All architecture boundary checks passed退出碼 0植入缺陷分析1000 字符魔咒與增量索引的修復(fù)對(duì)比starter 中被植入的 bug對(duì)比 starter/src/services/indexing-service.ts 與 solution 版本缺陷藏得很自然chunk 生成邏輯里悄悄加了一個(gè)條件——當(dāng)content.length 1000時(shí)把 chunk 內(nèi)容置為空字符串// starter 版本中的缺陷L106-L119 const chunkContent content.length 1000 ? : buffer.trim();后果是任何超過(guò) 1000 字符的文件索引后產(chǎn)出的 chunk 全是空內(nèi)容???chunk 會(huì)沿檢索鏈向下傳導(dǎo)——QA 的關(guān)鍵詞匹配拿不到任何命中、citation excerpt 為空、答案置信度驟降。而 starter 只有零散的console.log日志中chunkDocument produced N chunks看起來(lái)一切正常Agent 若無(wú)運(yùn)行時(shí)信號(hào)極難定位到問(wèn)題出在大文件的分塊內(nèi)容被清空。solution 的修復(fù)與增量索引機(jī)制solution/src/services/indexing-service.ts 的修復(fù)版刪除了那個(gè)三元條件chunk 內(nèi)容始終取真實(shí)文本分塊策略CHUNK_SIZE 500約 500 字符先按/\n\s*\n/空行拆成段落、過(guò)濾空白段落再貪心合并段落直至接近 500 字符邊界L110-L146每個(gè) chunk 攜帶元數(shù)據(jù)createChunk記錄charCount與wordCountL148-L159日志里也輸出totalChars總和用于校驗(yàn)分塊完整性L139-L143增量索引startIndexing()支持按單個(gè)documentId增量索引批量模式讀取documents-meta.json與index-meta.json只處理尚未記錄在chunksMeta中的文檔if (chunksMeta[doc.id]) continue;L53-L54索引結(jié)果寫(xiě)入chunks/docId.json并把 chunk id 列表登記回index-meta.json——這樣重復(fù)運(yùn)行不會(huì)重復(fù)消費(fèi)已索引文檔長(zhǎng)任務(wù)天然可斷點(diǎn)續(xù)跑狀態(tài)機(jī)getStatus()依據(jù)已索引數(shù) 文檔總數(shù)推導(dǎo)idle | indexing | ready | error四種狀態(tài)供 UI 與日志同步展示L75-L89。修復(fù)版還在每個(gè)關(guān)鍵節(jié)點(diǎn)埋了結(jié)構(gòu)化日志批量開(kāi)始記錄 totalDocs / alreadyIndexed、單文檔索引記錄 contentLength / chunkCount、內(nèi)容缺失跳過(guò)WARN 級(jí)讓 Agent 從日志就能判斷這個(gè)文檔到底有沒(méi)有被正確分塊。QA 側(cè)的可觀測(cè)錨點(diǎn)qa-service.ts 是缺陷的受害方也提供了診斷信號(hào)檢索時(shí)按查詢?cè)~與 chunk 內(nèi)容的包含關(guān)系打分、取 Top 2 作為 citationL66-L98每次回答都記錄confidence、citationCount、answerLength到結(jié)構(gòu)化日志L111-L115。當(dāng)答案置信度低、citation 數(shù)量為 0 時(shí)日志會(huì)直接指向索引層產(chǎn)出異?!@正是運(yùn)行時(shí)反饋驅(qū)動(dòng)定位的完整演示鏈路。完整復(fù)現(xiàn)步驟把兩遍實(shí)驗(yàn)跑起來(lái)按照 README-CN.md 與 AGENTS.md 的啟動(dòng)工作流# 第一遍弱信號(hào)環(huán)境 cd starter npm install npm run dev # 觀察Agent 能否僅憑 console.log 定位 chunking bug # 導(dǎo)入一個(gè)大文件1000 字符觀察分塊結(jié)果異???chunk # 第二遍帶護(hù)欄環(huán)境 cd ../solution npm install npm run dev # 對(duì)比結(jié)構(gòu)化日志如何加速診斷每個(gè)會(huì)話的標(biāo)準(zhǔn)驗(yàn)證命令solution 內(nèi)npm run check # tsc 雙 tsconfig 類(lèi)型檢查 npm run build # tsc -p tsconfig.node.json vite build bash scripts/check-architecture.sh # 架構(gòu)邊界護(hù)欄必須 PASS npm run dev # 啟動(dòng)應(yīng)用確認(rèn)結(jié)構(gòu)化日志出現(xiàn)在控制臺(tái)復(fù)現(xiàn)要求修復(fù)前后都用長(zhǎng)文檔各復(fù)現(xiàn)一次保留日志證據(jù)導(dǎo)入事件、索引 chunk 數(shù)、QA 置信度證明診斷證據(jù)存在而不只是聲稱修復(fù)通過(guò)。干凈的交接clean-state-checklist 與 AGENTS 工作流本項(xiàng)目強(qiáng)調(diào)Session 結(jié)束時(shí)倉(cāng)庫(kù)必須可重啟、可交接。清單 clean-state-checklist.md 按五組核對(duì)構(gòu)建npm run check無(wú)類(lèi)型錯(cuò)誤、npm run build成功架構(gòu)bash scripts/check-architecture.sh零違規(guī)、renderer 無(wú) Node 核心模塊 import、services 無(wú) Electron IPC、services/main 無(wú) React import運(yùn)行時(shí)應(yīng)用無(wú)錯(cuò)啟動(dòng)、啟動(dòng)時(shí)出現(xiàn)結(jié)構(gòu)化日志、文檔導(dǎo)入正常日志含 IMPORT_DOCUMENT 事件、各種大小的文檔索引正常、QA 返回帶 citation 的答案日志含 ASK_QUESTION 事件數(shù)據(jù)完整性已索引文檔無(wú)空 chunk用 GET_CHUNKS 驗(yàn)證、QA 歷史跨重啟持久化、文檔元數(shù)據(jù)與實(shí)際文件一致倉(cāng)庫(kù)git status 無(wú)意外文件、無(wú)敏感數(shù)據(jù)入庫(kù)、最終總結(jié)記錄當(dāng)前狀態(tài)/驗(yàn)證記錄/未決風(fēng)險(xiǎn)、AGENTS.md / ARCHITECTURE.md / 本清單與實(shí)際文件保持一致。配套的 AGENTS.md 還定義了長(zhǎng)期運(yùn)行 Agent 的操作紀(jì)律動(dòng)手前先跑啟動(dòng)工作流pwd→ 讀 ARCHITECTURE.md →git log --oneline -5→npm install→npm run check→ 架構(gòu)檢查一次只做一個(gè)功能不靜默改動(dòng)驗(yàn)證規(guī)則優(yōu)先把結(jié)論沉淀為倉(cāng)庫(kù)內(nèi)持久產(chǎn)物而非聊天摘要。其Definition of Done明確要求目標(biāo)行為已實(shí)現(xiàn) 驗(yàn)證確實(shí)運(yùn)行過(guò) 證據(jù)已記錄 倉(cāng)庫(kù)可從標(biāo)準(zhǔn)路徑重啟 架構(gòu)檢查通過(guò)這正是避免 Agent 過(guò)早宣布勝利對(duì)應(yīng) 講義 09 的主題的工程化落地。關(guān)鍵文件速查關(guān)注點(diǎn)路徑項(xiàng)目說(shuō)明與 A/B 任務(wù)projects/project-04/README-CN.md結(jié)構(gòu)化日志實(shí)現(xiàn)projects/project-04/solution/src/services/logger.ts架構(gòu)邊界文檔projects/project-04/solution/docs/ARCHITECTURE.md架構(gòu)檢查腳本projects/project-04/solution/scripts/check-architecture.sh已修復(fù)的增量索引projects/project-04/solution/src/services/indexing-service.ts植入缺陷的對(duì)照組projects/project-04/starter/src/services/indexing-service.ts檢索與 citation 日志錨點(diǎn)projects/project-04/solution/src/services/qa-service.tsIPC 通道與共享類(lèi)型projects/project-04/solution/src/shared/types.ts會(huì)話交接清單projects/project-04/solution/clean-state-checklist.mdAgent 運(yùn)行紀(jì)律projects/project-04/solution/AGENTS.md關(guān)聯(lián)講義講義 07エージェントのタスク境界を明確に引く · 講義 08機(jī)能リストでエージェントの作業(yè)を制約する。小結(jié)Project 04 用一次可重復(fù)的 A/B 實(shí)驗(yàn)證明了 Harness 的核心主張——Agent 的修復(fù)速度與準(zhǔn)確度取決于它能否看見(jiàn)運(yùn)行時(shí)真相、能否被邊界約束住。結(jié)構(gòu)化日志提供反饋架構(gòu)腳本提供約束增量索引提供可控的推進(jìn)粒度三者合一才是讓長(zhǎng)運(yùn)行 Agent 從猜測(cè)式編碼走向證據(jù)驅(qū)動(dòng)修復(fù)的最小閉環(huán)。贊分享【免費(fèi)下載鏈接】learn-harness-engineeringHarness engineering beginner tutorial, from 0 to 1項(xiàng)目地址https://gitcode.com/gh_mirrors/le/learn-harness-engineering點(diǎn)擊查看免費(fèi)下載相關(guān)推薦learn-harness-engineering Project 04 實(shí)戰(zhàn)用運(yùn)行時(shí)反饋與架構(gòu)約束修正 Agent 行為learn harness engineering Project 04 實(shí)戰(zhàn)用運(yùn)行時(shí)反饋與架構(gòu)約束修正 Agent 行為 本項(xiàng)目Project 04 ·learn-harness-engineering 項(xiàng)目 04用運(yùn)行時(shí)反饋修正 Agent 行為——結(jié)構(gòu)化日志、架構(gòu)約束與增量索引實(shí)戰(zhàn)learn harness engineering 項(xiàng)目 04用運(yùn)行時(shí)反饋修正 Agent 行為——結(jié)構(gòu)化日志、架構(gòu)約束與增量索引實(shí)戰(zhàn) 本篇技術(shù)指南以倉(cāng)庫(kù) dHarness 實(shí)戰(zhàn)用運(yùn)行時(shí)反饋與架構(gòu)約束糾正 Agent 行為——learn-harness-engineering Project 04 增量索引調(diào)試指南Harness 實(shí)戰(zhàn)用運(yùn)行時(shí)反饋與架構(gòu)約束糾正 Agent 行為——learn harness engineering Project 04 增量索引調(diào)試指南創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考