標籤: LangChain

  • 用 HeyZoku 指揮程式碼 Agent 的最簡上手法

    用 HeyZoku 指揮程式碼 Agent 的最簡上手法

    📌 本文重點

    • HeyZoku 以語音協調多個程式碼 Agent
    • 讓 AI 自動分工處理修 bug、重構、測試與文件
    • 適合個人開發者與團隊做多 Agent 開發實驗
    • 從連接 Git repo 與設定 Agent 即可開用

    用一句話說清楚:HeyZoku 是讓你用語音指令協調多個程式碼代理(coding agents),一起幫你完成修 bug、重構、寫測試、產生文件的工作台。

    相比用鍵盤一個一個丟指令給 ChatGPT、Cursor、LangChain,HeyZoku 主打的是「我只負責說清楚要做什麼,具體執行交給一群 AI 程式碼 Agent 分工」。

    官網/Product Hunt:https://www.producthunt.com/products/heyzoku


    核心功能:把你的語音變成多 Agent 的「作業清單」

    1. 語音介面:說話就能派工,而不是打字寫 Prompt

    HeyZoku 的核心是語音介面:你開口說,系統負責轉成結構化指令,再分派給不同程式碼 Agent。

    可以先從這幾種語音指令開始練習:

    • 任務型指令
    • 「幫我檢查這個 PR 的潛在 bug,重點看錯誤處理。」
    • 「把 user-service.ts 裡的重複邏輯抽成共用函式。」
    • 範圍型指令
    • 「只看 backend 資料夾,不要動 frontend。」
    • 限制型指令
    • 「改動控制在 50 行以內,先給我 diff 再套用。」

    💡 關鍵: 透過語音明確描述任務與限制,HeyZoku 能自動轉成結構化多 Agent 作業清單,大幅減少手動寫 Prompt 的負擔。

    可以馬上做的事

    1. 列一份自己常對 AI 說的開發請求,把它改寫成一句話就能說清楚的格式。
    2. 盡量包含:目標檔案/行為(修 bug、重構、寫測試…)/限制條件(行數、不要動哪裡)。

    2. 多個程式碼 Agent 協作:讓 AI 自動分工而不是一個模型包山包海

    HeyZoku 的設計是「一個工作台 + 多個角色分明的 coding agents」。典型設定會長這樣:

    • 分析 Agent:負責理解需求、拆解成具體子任務。
    • 實作 Agent:在程式碼庫裡進行實際修改、新增檔案。
    • 測試 Agent:補齊或更新單元測試、行為測試。
    • 文件 Agent:根據變更更新 README、API 文件、註解。

    當你下達語音指令時,HeyZoku 的工作台會:

    1. 把語音轉成文字並抽取「任務」、涉及檔案、限制。
    2. 交給分析 Agent 拆解成多個可執行的步驟。
    3. 由不同 Agent 順序執行,並把進度回報到同一個介面。

    可以馬上做的事

    先替自己腦中「理想的 AI 開發小組」命名 3 個角色:

    • Agent A:只負責拆需求和寫 TODO。
    • Agent B:只負責動程式碼和開 PR。
    • Agent C:只負責寫測試和文件。

    到 HeyZoku 裡對應設定,避免「一個 Agent 什麼都做」導致上下文混亂。


    3. 支援的典型開發任務與環境整合

    HeyZoku 主打的是重複、結構明確的開發工作

    • 修 bug:根據 log / issue / PR diff,幫你定位問題並產生修補程式碼。
    • 重構:整理長函式、去除重複邏輯、抽共用模組。
    • 寫測試:補齊缺失的單元測試、行為測試(例如 Gherkin 格式)。
    • 產生文件:同步更新 README、API docs、註解,避免程式碼改了文件沒跟上。

    典型整合環境包含:

    • Git repo(GitHub / GitLab 等,實際支援要以 HeyZoku 最新說明為準)。
    • 主流語言專案:JavaScript/TypeScript、Python 等常見 web/backend 專案結構。
    • 可能串接現有 Issue tracker 或 CI,把測試結果回報到同一工作台。

    可以馬上做的事

    1. 選一個已存在的 Git 專案,而不是從零開始(AI agent 在既有結構裡表現更好)。
    2. 清點這個專案里最耗時的重複工作(例如每次改 API 都要改 3 個地方),列成 HeyZoku 要接手的任務清單。

    適合誰用:三種典型場景

    1. 個人開發者:把「重複體力活」外包給 AI 小組

    如果你是一人公司或自由接案者,通常會遇到:

    • 改一個小需求,要自己寫程式、寫測試、寫文件。
    • 常常在不同 repo、不同專案間切換。

    HeyZoku 的用法是:你用語音定義「什麼算完成」,讓多個 Agent 幫你跑完全部流程。

    例子:

    「新增一個 POST /users/{id}/deactivate API,要求:
    – 有基本驗證錯誤處理
    – 有單元測試覆蓋成功和失敗情境
    – 更新 API 文件與 README 的使用範例」

    可以馬上做的事

    • 選出一個你最不想自己動手寫、但規則很清楚的小功能,交給 HeyZoku 測試整個「需求到測試與文件」的流程。

    2. 團隊:試驗「AI Pair Programming 小組」

    在團隊裡,HeyZoku 更適合作為實驗用工作台

    • 一名人類開發者 + 一組 AI Agent 當「虛擬 Pair」,幫忙拆需求、做初版 commit。
    • Team lead 定義測試、品質規則,像 Uncle Bob 提到的那樣用約束而不是肉眼審每一行 AI code。

    可以借鏡這則 Hacker News 提到的思路:

    「我不再閱讀 agents 寫的程式碼,而是用單元測試、gherkin 測試、品質指標、變異測試等手段,確保它們產出的程式碼有足夠信心。」
    原文:https://news.ycombinator.com/item?id=49074693

    對 HeyZoku 來說,就是:

    • 團隊只審查測試與約束是否夠嚴
    • AI Agent 在這些約束下自動跑修 bug、重構、文件更新。

    可以馬上做的事

    1. 選一個「技術債清理」類的支線專案,讓 HeyZoku 的 Agent 專門負責重構與測試補齊。
    2. 團隊只在 PR 層面把關:測試是否完備、CI 是否全綠。

    3. 行動情境:走動中、會議中也能操作 AI 開發

    HeyZoku 的語音介面特別適合這幾種情境:

    • 走路通勤時:想到一個改動,就直接用手機說明任務。
    • 會議中:討論到某個需求,當場用語音下指令,讓 Agent 回頭補程式碼與測試草稿。

    例子:需求討論到一半,你說:

    「為現在的訂單系統新增一個『預約取消』功能,先給我:
    – 用例清單
    – 影響到的服務清單
    – 這一版不改 DB 結構,只改 service 層。」

    分析 Agent 會先幫你產出拆解與影響範圍,等你回到桌前再決定要不要進一步讓實作 Agent 開始寫程式。

    可以馬上做的事

    • 想像自己在走路或開會時,最希望 AI 幫忙做的「前期準備」是什麼(用例整理、影響分析、TODO 列表),先在 HeyZoku 裡讓分析 Agent專門負責這一塊。

    怎麼開始:從註冊到第一次語音下指令

    Step 0:準備好要讓 Agent 動手的環境

    在開啟 HeyZoku 前,先準備:

    • 至少一個 Git repo(本機或雲端皆可,但要能被 HeyZoku 讀取)。
    • 清楚的專案結構(src/, tests/, docs/ 等最好有基本規範)。
    • 一份簡短專案說明(README 或架構圖),讓分析 Agent 有上下文可用。

    可以馬上做的事

    • 為你的主力專案補一份「給 AI 看的 README」,寫清楚:主要模組、測試位置、常見指令(啟動、測試、lint)。

    Step 1:註冊並登入 HeyZoku

    1. 前往 Product Hunt 頁面:https://www.producthunt.com/products/heyzoku,找到官方連結進入 HeyZoku。
    2. 使用 GitHub 或 Email 進行註冊(實際支援方式以當前版本為準)。
    3. 登入後,尋找「Workspace」或「Project」入口,建立第一個工作區。

    可以馬上做的事

    • 為第一個 Workspace 命名成你常用的專案名,例如 backend-orders-service,方便之後語音指令直接說專案名。

    Step 2:連接你的程式碼庫與設定 Agent 分工

    1. 在 HeyZoku 介面中,連接你的 Git repo(授權讀寫必要權限)。
    2. 建立 3–4 個核心 Agent:
    3. PlannerAgent:拆需求、寫 TODO。
    4. CoderAgent:寫實作程式碼。
    5. TestAgent:補測試、追求覆蓋率。
    6. DocAgent:更新文件與註解。
    7. 對每個 Agent 提供對應的說明與範圍(例如 TestAgent 只能動 tests/ 資料夾)。

    可以馬上做的事

    • 在每個 Agent 的說明中寫明「不該動的區域」,例如:DocAgent 不得修改 production config

    Step 3:設計適合語音的指令格式

    語音指令的關鍵在於結構清楚,建議用固定模板:

    「在【專案/資料夾】裡,對【檔案/功能】,做【動作類型】,限制是【條件】。」

    幾個範例:

    • 「在 backend-orders-service 裡,針對 OrderController,重構取消訂單的邏輯,限制是不要改資料庫 schema。」
    • 「在 user-service 專案,對 auth 模組新增登入失敗重試次數的設定,限制是要有對應單元測試與 README 更新。」

    可以馬上做的事

    • 把這個模板貼在自己螢幕前,實際對著麥克風練習 3 種不同任務的語音說法,觀察 HeyZoku 的理解情況。

    Step 4:示範一個「小型自動化開發流水線」的 playbook

    我們來示範一條簡單流水線:

    角色配置

    • Agent 1(需求拆解):PlannerAgent
    • Agent 2(寫程式):CoderAgent
    • Agent 3(測試與文件):TestDocAgent(合併角色)

    語音指令

    「在 backend-orders-service 專案,新增『延遲出貨』功能:
    – PlannerAgent:先拆成具體子任務與影響模組列表
    – CoderAgent:實作出貨延遲的核心邏輯與 API
    – TestDocAgent:補上對應的單元測試與 README 使用範例
    限制是:不改既有資料庫表,只在 service 層實作。」

    預期流程

    1. PlannerAgent 產出:子任務列表 + 影響範圍(哪些 service / controller / config)。
    2. 你確認列表沒有遺漏,再允許 CoderAgent 開始 commit。
    3. TestDocAgent 根據 diff 補測試與文件。
    4. HeyZoku 工作台顯示整個流水線的狀態,最後產出一個 PR 或變更集供你審查。

    可以馬上做的事

    • 找一個「現有功能的小改版」來跑這條流水線,例如:新增一種訂單狀態、調整折扣計算方式,用來驗證 HeyZoku 是否能完整跑完分析→實作→測試→文件的鏈。

    跟其他多 Agent 工具的差異

    如果你已經聽過 LangChain、Composer 等多 Agent 工具,可以用下表快速對比定位:

    名稱 核心功能 免費方案 適合誰
    HeyZoku 語音指令協調多個程式碼 Agent 依官方方案,偏雲端服務 想用說話操作 AI 的開發者
    LangChain Python/JS 中組合 LLM + Tool + Agent 開源框架,免費使用 要自行搭建 Agent 系統的工程師
    Composer v3 多模型、多元件工作流程編排 社群工具,視專案而定 研究者與實驗多模型整合的人

    💡 關鍵: 若你不想寫多 Agent 框架程式碼,HeyZoku 提供即開即用的語音工作台,是從「想試試多 Agent 能做什麼」到「再用 LangChain/Composer 客製」之間的理想起點。

    可以馬上做的事

    • 如果你不想自己寫 Agent 框架程式碼,只想快點看「多 Agent 實際能幫我做什麼」,先從 HeyZoku 開始;之後再視需要用 LangChain 或 Composer 做客製化延伸。

    🚀 你現在可以做的事

    • 前往 HeyZoku Product Hunt 頁面,註冊並建立第一個 backend-orders-service 工作區
    • 選一個既有 Git 專案,連接 Repo 並設定 PlannerAgentCoderAgentTestAgentDocAgent 的職責與禁止修改區域
    • 實際用語音下達一個「小改版需求」,跑完分析→實作→測試→文件的完整流水線,觀察多 Agent 協作效果
  • 用狀態機把 13GB 小模型變成工程實習生

    用狀態機把 13GB 小模型變成工程實習生

    📌 本文重點

    • 小模型別當全能 Agent,要當被流程管控的小工
    • 用顯式狀態機拆任務,大幅提升穩定性與可回滾性
    • 每步輸出 JSON + schema 驗證,讓小模型也能穩定改碼

    只靠 prompt 堆疊,13GB 本地模型在中大型改碼任務幾乎必翻車:上下文飄掉、一次回錯一堆檔、改到一半忘記需求。把模型包進顯式狀態機,把「一次大任務」拆成可恢復的子任務,可以在不改模型的前提下,大幅提升穩定性、可觀測性與可測試性——正是那篇 13.8GB 模型從 2/10 變成 10/10 的核心做法。

    💡 關鍵: 只改調用方式與流程設計,就能把同一顆 13.8GB 小模型的表現從 2/10 拉到 10/10。


    重點說明

    1. 小模型為什麼在長對話裡特別容易翻車?

    從工程視角,有三個根本原因:

    1. token 預算太小 + 資訊密度太高
      13GB 級(多是 7B〜13B 參數)在 4k–16k context 內要同時塞:需求、專案結構、幾個檔案內容、測試結果、對話歷史,關鍵訊息會被截斷或壓縮到模型抓不到

    2. 上下文漂移(context drift)
      多輪長對話時,你不可能每次都重貼完整需求與檔案。模型只能靠「語意回憶」之前說過什麼,多輪後任務邊界就開始模糊:忘記原本的 constraint、改到不該動的檔案、把舊 bug 當新需求。

    3. 一次性決策成本過高
      傳統「一條大 prompt + chain-of-thought」會在單輪裡要求:理解需求 → 找檔 → 設計改動 → 寫碼 → 自我檢查。這在 token 限制與小模型推理能力下,極易在中間任一步 hallucinate,之後又沒有明確的 rollback 機制。

    關鍵結論: 小模型不適合當「一次性全能 Agent」,更適合當「被嚴格流程控制的小工」,讓狀態機負責 long-term 記憶與決策邊界。

    💡 關鍵: 把 long-term 記憶與流程決策交給狀態機,小模型只做局部推理,能顯著降低翻車率。


    2. 用顯式狀態機拆解大任務:核心設計

    把「改造一個中小型專案」拆成明確的 State + Transition

    常見狀態設計可以是:

    1. DISCOVER_PROJECT:掃描 repo、建立檔案索引
    2. PLAN_CHANGE:根據需求與索引產生修改計畫(檔案清單、步驟)
    3. EDIT_FILE:逐檔案修改(step-by-step)
    4. RUN_TESTS:執行測試、收集結果
    5. ROLLBACK_OR_FIX:測試失敗→嘗試修復或回滾
    6. DONE / FAILED:終止狀態

    每個狀態都只給模型 極簡上下文 + 明確輸入/輸出 schema,例如在 EDIT_FILE

    • 輸入:
    • 需求摘要(短)
    • 該檔案目前內容(或片段)
    • 計畫中對此檔案的變更描述
    • 輸出:
    • 結構化 JSON:{"status": "ok|skip|abort", "patch": "...diff..."}

    轉移條件示例:

    • DISCOVER_PROJECTPLAN_CHANGE:索引成功建立
    • PLAN_CHANGEEDIT_FILE:生成的計畫通過 schema 檢查
    • EDIT_FILERUN_TESTS:所有目標檔案處理完
    • RUN_TESTS
    • 全綠 → DONE
    • 有失敗 + 可定位 → EDIT_FILE (targeted fix)
    • 多次失敗 → ROLLBACK_OR_FIX

    失敗重試策略與超時機制

    • 每個狀態設定 max_retries,例如 2–3 次,超過則標記為 FAILED 或轉 ROLLBACK_OR_FIX
    • 每次 LLM 回應必經:
    • JSON schema 驗證
    • domain guard(例如禁止刪除大量無關 code)
    • 超時機制
    • 單次呼叫 timeout(例如 60s),保障工作流不被卡死
    • 整個工作流 wall-clock timeout(例如 30 分鐘),方便在 CI 或自動化工具中運行

    💡 關鍵: 把重試、超時、回滾寫死在狀態機邏輯裡,比指望 prompt 提醒模型「要小心」可靠太多。


    3. 實作範例:13GB 本地模型改造專案(Python)

    以下是精簡版 pseudo-code,示範如何把本地模型包在狀態機裡,跑 step-by-step 編碼、測試與回滾。假設:

    • 使用 vLLM / llama.cpp server 暴露出 OpenAI-compatible API
    • GPU:3060 12GB,模型用 Q4 / Q5 量化
    import enum
    import json
    import subprocess
    from dataclasses import dataclass
    from typing import Dict, Any, List
    import requests
    
    OPENAI_BASE = "http://localhost:8000/v1"
    MODEL_NAME = "local-13b-q4"
    
    class State(enum.Enum):
        DISCOVER_PROJECT = "DISCOVER_PROJECT"
        PLAN_CHANGE = "PLAN_CHANGE"
        EDIT_FILE = "EDIT_FILE"
        RUN_TESTS = "RUN_TESTS"
        ROLLBACK_OR_FIX = "ROLLBACK_OR_FIX"
        DONE = "DONE"
        FAILED = "FAILED"
    
    @dataclass
    class Context:
        repo_path: str
        requirement: str
        file_index: Dict[str, Any] = None
        plan: List[Dict[str, Any]] = None
        current_file_idx: int = 0
        test_result: str = ""
    
    
    def call_llm(system_prompt: str, user_prompt: str, max_tokens: int = 1024) -> str:
        resp = requests.post(
            f"{OPENAI_BASE}/chat/completions",
            json={
                "model": MODEL_NAME,
                "messages": [
                    {"role": "system", "content": system_prompt},
                    {"role": "user", "content": user_prompt},
                ],
                "temperature": 0.2,
                "max_tokens": max_tokens,
            },
            timeout=60,
        )
        resp.raise_for_status()
        return resp.json()["choices"][0]["message"]["content"]
    
    
    def discover_project(ctx: Context) -> Context:
        # 這裡可以用 ripgrep / fd 產生檔案清單,略
        ctx.file_index = {"files": ["src/a.py", "src/b.py"], "tests": ["tests/test_a.py"]}
        return ctx
    
    
    def plan_change(ctx: Context) -> Context:
        system = """你是資深工程師,輸出 JSON,字段: steps: [{file, description}]。"""
        user = f"需求: {ctx.requirement}\n可修改檔案: {ctx.file_index['files']}\n請產生最多 10 個步驟。"
        raw = call_llm(system, user)
        try:
            plan = json.loads(raw)
        except Exception:
            raise ValueError("PLAN_CHANGE: model output not JSON")
        ctx.plan = plan["steps"]
        ctx.current_file_idx = 0
        return ctx
    
    
    def apply_patch(repo_path: str, file: str, patch: str):
        # 建議用 unified diff + `patch` 指令,這裡簡化處理
        with open(f"{repo_path}/{file}", "w", encoding="utf-8") as f:
            f.write(patch)
    
    
    def edit_file(ctx: Context) -> Context:
        step = ctx.plan[ctx.current_file_idx]
        file_path = step["file"]
        with open(f"{ctx.repo_path}/{file_path}", encoding="utf-8") as f:
            content = f.read()
    
        system = """你只負責修改單一檔案。輸出 JSON: {status, patch}。
        - status: ok | skip | abort
        - patch: 完整檔案內容,不要解釋文字。"""
    
        user = f"需求: {ctx.requirement}\n此步驟: {step['description']}\n原始內容:\n{content[:4000]}"
        raw = call_llm(system, user, max_tokens=2048)
        try:
            out = json.loads(raw)
        except Exception:
            raise ValueError("EDIT_FILE: invalid JSON")
    
        if out["status"] == "ok":
            apply_patch(ctx.repo_path, file_path, out["patch"])
        elif out["status"] == "abort":
            raise RuntimeError("Model aborted edit")
    
        ctx.current_file_idx += 1
        return ctx
    
    
    def run_tests(ctx: Context) -> Context:
        proc = subprocess.run(["pytest"], cwd=ctx.repo_path, capture_output=True, text=True)
        ctx.test_result = proc.stdout + "\n" + proc.stderr
        return ctx
    
    
    def rollback_or_fix(ctx: Context) -> Context:
        # 真實情況應該搭配 git: reset --hard HEAD~1 或建立 branch
        # 這裡示意:交給模型看測試輸出,決定要修哪個檔案
        system = "請從測試輸出中找出最可能需要修改的單一檔案,輸出 JSON: {file, reason}"
        user = ctx.test_result[:4000]
        raw = call_llm(system, user)
        try:
            out = json.loads(raw)
        except Exception:
            raise ValueError("ROLLBACK_OR_FIX: invalid JSON")
    
        # 根據 out['file'] 重新插入 plan
        ctx.plan.insert(ctx.current_file_idx, {"file": out["file"], "description": out["reason"]})
        return ctx
    
    
    def run_state_machine(ctx: Context):
        state = State.DISCOVER_PROJECT
        retries: Dict[State, int] = {s: 0 for s in State}
        MAX_RETRIES = 2
    
        while True:
            try:
                if state == State.DISCOVER_PROJECT:
                    ctx = discover_project(ctx)
                    state = State.PLAN_CHANGE
    
                elif state == State.PLAN_CHANGE:
                    ctx = plan_change(ctx)
                    state = State.EDIT_FILE
    
                elif state == State.EDIT_FILE:
                    if ctx.current_file_idx >= len(ctx.plan):
                        state = State.RUN_TESTS
                    else:
                        ctx = edit_file(ctx)
    
                elif state == State.RUN_TESTS:
                    ctx = run_tests(ctx)
                    if "failed" in ctx.test_result:
                        state = State.ROLLBACK_OR_FIX
                    else:
                        state = State.DONE
    
                elif state == State.ROLLBACK_OR_FIX:
                    ctx = rollback_or_fix(ctx)
                    state = State.EDIT_FILE
    
                elif state in (State.DONE, State.FAILED):
                    return state, ctx
    
            except Exception as e:
                print(f"State {state} error: {e}")
                retries[state] += 1
                if retries[state] > MAX_RETRIES:
                    return State.FAILED, ctx
    
    
    if __name__ == "__main__":
        ctx = Context(repo_path="/path/to/repo", requirement="把 API v1 換成 v2 並修正測試")
        final_state, final_ctx = run_state_machine(ctx)
        print("Final state:", final_state)
    

    重點:

    • 模型只做 局部、可回滾的決策(例如一次只改一檔)。
    • 工作流邏輯(狀態、重試、回滾)都在 可測試的 Python 函式 中,而不是藏在 prompt 裡。

    若用 TypeScript + LangGraph / 自行寫狀態機,模式相同:每個 Node 是一個狀態,Edge 由測試結果與 JSON 輸出決定。


    4. 與「prompt + chain-of-thought」相比的實際好處

    1. 穩定性
    2. CoT 依賴模型「自己監督自己」,小模型的推理錯誤會被往後 propagate,沒有硬性 checkpoint。
    3. 狀態機把流程切成多個 可檢查的邏輯節點,每步都能強制過 schema、判斷失敗與回滾。

    4. 成本與資源

    5. 單輪 prompt 巨大 → token 費用高,且在本地 GPU 上速度慢。
    6. 狀態機讓每輪上下文更短、更聚焦,在 3060 12GB + Q4 模型上可以穩定跑 多輪短對話,總延遲往往比一輪巨 prompt 更好控制。

    7. 觀測性(logging / trace)

    8. 把每個狀態轉移、LLM input/output、git diff 全記錄(例如存到 SQLite / OpenTelemetry trace),可以:

      • 後覽失敗案例
      • 做離線分析:哪個狀態最常出錯?哪種需求最難?
    9. 可測試性

    10. 傳統做法難以單元測試 Agent:prompt 無法 deterministic。
    11. 狀態機可以用 fake LLM 或 replay 真實輸出,對每個 state handler 寫 unit test,例如:當測試結果是某種錯誤訊息時,ROLLBACK_OR_FIX 應插入哪個 plan。

    建議與注意事項

    1. 避免狀態爆炸

    • 限制狀態數量在 5–10 個,複雜度放在狀態內部的子函式,而不是新增一堆細碎狀態。
    • 優先建立 通用狀態模板PLAN / EXECUTE / VERIFY / RECOVER 四類,大部分工程任務都能套這個骨架。

    2. 處理 hallucination 與非法狀態

    • 所有 LLM 輸出一律要求 JSON + schema 驗證,非法就走重試邏輯。
    • EDIT_FILE 等關鍵步驟設計 domain guard
    • 檢查 patch 是否刪除超過 X% 行數;
    • 檢查是否涉及黑名單檔案(例如 config、CI YAML)。

    3. 設計「保守模式」避免改壞檔案

    建議預設開啟:

    1. 所有改動先走分支 / 工作目錄拷貝
    2. 狀態機只在 temp branch/dir 上動手,最後才由人類 review + merge。

    3. 只允許白名單檔案被修改

    4. PLAN_CHANGE 事先產出可修改清單,EDIT_FILE 收到不在清單內的檔案時直接拒絕。

    5. 必備 diff 檢查

    6. 每次改檔後,log 一份 git diff。
    7. 可以加一個 HUMAN_APPROVAL 狀態,在 CI 或 IDE 裡讓人按「Approve」才繼續。

    4. 3060 12GB 本地 GPU 的實務建議

    • 模型:選 Q4_K_M / Q5 量化的 7B–13B 開源模型(如 Llama 系家族、Qwen 等),在 Agentic coding 任務上實測延遲可接受。
    • 推理引擎:
    • llama.cpp / ollama:部署簡單,適合單機開發。
    • vLLM:若你需要高併發與更細緻的 batching,可考慮,但對記憶體稍敏感。
    • 參數建議:
    • max_tokens 控制在 512–2048,依狀態不同調整。
    • temperature 低於 0.3,減少 hallucination。
    • 避免在單輪塞完整檔案,改成 片段 + 明確上下文(例如「你只看這個 function」)。

    5. 映射到現有 Agent framework 的模式

    這套思路可以直接映射到:

    • LangChain / LangGraph
    • 每個狀態 = 一個 Node(通常是 Tool + LLM)。
    • 轉移條件透過 conditional edges 判斷 JSON output 中的 status / next_state
    • 用 LangGraph 的 checkpointingContext 存到外部 store,可做恢復與可視化。

    • LangMCP(可檢視狀態的 Agent framework)

    • Context 中的 file_index / plan / test_result 全部納入 inspectable state
    • 除錯時可以直接在 UI 裡看到「Agent 在哪一步做錯決策」,而不是只看 tokens trace。

    • Claude Code / goal-workflow 類工具

    • 把這裡的狀態機當作後端 orchestrator,前端 IDE 只負責:設定 goal → 顯示 plan → 顯示每步 diff / 測試 → 提供人類 approve。

    總結工程模式:

    LLM 做局部推理 + 生成,狀態機做長期決策 + 記憶 + 恢復。
    把「智慧」從模型本體,搬到你可控、可測、可觀測的工作流程式碼中,13GB 小模型也能在工程任務裡穩定交付 10/10 的結果。


    🚀 你現在可以做的事

    • 在本地架一個 llama.cppvLLM 的 OpenAI-compatible 服務,載入一顆 7B–13B Q4/Q5 模型試跑上文的狀態機範例
    • 把你現有的「一條大 prompt 改碼流程」改寫成 5–10 個明確狀態,並為每步定義 JSON schema 與 max_retries
    • 在 CI 或開發機中為這套狀態機加上 logging / trace(例如 SQLite 或 OpenTelemetry),實際分析哪個 state 最常出錯
  • Hippo 記憶:讓本機 AI Agent 真正記住你

    📌 本文重點

    • Hippo 讓 AI Agent 具備結構化長期記憶
    • 不只用向量搜索,而是多維度記憶召回
    • 可直接接入 LangChain / LangGraph 現有架構

    如果你受夠了每次開新對話 AI 就失憶,Hippo 是一個專門幫 AI Agent 建長期記憶結構 的開源工具,讓模型可以跨對話記住你、記住專案、記住世界觀。

    專案連結:https://github.com/kitfunso/hippo-memory


    核心功能:它跟「塞進向量資料庫」有什麼不一樣?

    1. 生物啟發的記憶結構:不是只靠 embedding 搜索

    一般「加記憶」做法:

    • 把所有對話 / 文件轉成向量,丟進向量資料庫
    • 查詢時用 embedding 相似度召回

    這樣會遇到:

    • 記憶越多越慢
    • 容易抓到語意相似但情境不對的內容
    • 很難做「時間感」與「重要程度」的區分

    Hippo 的做法更像大腦海馬迴:

    • 把記憶拆成多種型態(事件、事實、偏好、任務等)
    • 每種記憶有自己的欄位:時間戳、重要性、來源、關聯 id
    • 召回時不只看相似度,還會考慮:
    • 時間距離(最近 / 很久以前但被多次提及)
    • 重要性(例如「明天要開會」權重更高)
    • 記憶種類(對話中問的是偏好,就優先找偏好類)

    💡 關鍵: Hippo 透過「記憶類型 + 時間 + 重要性」多維度過濾與排序,比單靠 embedding 更接近人類大腦的記憶方式。

    你可以採取的行動

    • 在設計 Agent 時,把「要記住什麼」先分類(例:使用者設定、長期專案狀態、一次性任務)
    • 對應到 Hippo 的不同記憶類型,而不是全部塞進單一向量庫

    2. 高效寫入 / 召回:不是每一句話都存

    Hippo 會讓 LLM 幫忙「過濾」哪些內容要進長期記憶:

    • 每輪對話結束時,呼叫一次 LLM:
    • 請它輸出:要存什麼?是什麼類型?重要性幾分?
    • 只有被標註為「值得記住」的內容才寫入記憶庫

    召回時則是:

    • 先根據 當前任務類型 過濾可疑記憶(例如問「專案」時,優先專案類)
    • 再用 embedding + 時間 + 重要性加權排序

    效果:

    • 記憶庫不會無限膨脹
    • 查詢時間穩定,對話變長也不會暴漲

    💡 關鍵: 透過 LLM 篩選與加權排序,Hippo 在長期對話下仍能維持穩定的查詢速度與記憶品質。

    你可以採取的行動

    • 在對話 loop 中加入一個 summarize_and_store_memory() 步驟
    • 規劃一份提示詞,教 LLM:什麼東西需要記住(例如使用者偏好、長期任務)

    3. 可以直接當「記憶模組」接到 LangChain / LangGraph

    Hippo 把核心封裝成一個獨立記憶層:

    • 暴露簡單的 API:add_memory(), retrieve_memories(), summarize_dialogue()
    • 你可以把它包成一個自訂的 LangChain Memory 類或 LangGraph node

    這代表你不必改整個 Agent 架構,只要:

    • 把原本「向量記憶」的那一層換成 Hippo
    • Prompt 裡多餵一段:{relevant_memories}

    你可以採取的行動

    • 先用 Hippo 做一個獨立小腳本,確定記憶寫入 / 召回正常
    • 再把它接進現有的 LangChain / LangGraph 專案

    適合誰用?三種具體場景

    1. 客服 / 助理型 Agent:跨對話記住使用者

    問題:

    • 今天跟你聊過喜好,明天又得重講一次

    用 Hippo 可以:

    • 把「使用者個人偏好」「公司規則」「歷史問題」分成不同記憶類型
    • 在每次新對話開始前,先用使用者 id 去 retrieve_memories()

    具體做法:

    • 每個 user 綁一個 user_memory_store
    • 首輪對話後,寫入:
    • 常用產品 / 方案
    • 語氣偏好(喜歡簡短回答、或喜歡詳細教學)
    • 下次對話開頭,在系統 prompt 裡加:
    • 你已知這個使用者的偏好:...

    2. 工具型 Agent:追蹤專案長期狀態

    像是:

    • 本機程式碼助手
    • 專案管理 / 自動化腳本編排 Agent

    用 Hippo 可以把:

    • 已完成的任務
    • 未完成的 TODO
    • 決策理由(為什麼選 A 而不是 B)

    長期存起來,讓 Agent 未來做決策時可以「回頭想」,而不是只看當前 prompt。

    具體做法:

    • 每次工具成功執行後,寫入:操作內容、輸入、輸出、錯誤紀錄
    • 下次 Agent 在決定要不要呼叫同個工具時,先查過去的失敗 / 成功案例

    💡 關鍵: 對工具型 Agent 來說,持續累積「決策與結果」記憶,可以大幅降低重複犯錯與無效操作。

    3. 遊戲 / 模擬:角色人格與世界觀持久化

    如果你在做:

    • 文字冒險遊戲中的 NPC
    • 模擬城市 / 社會裡的多 Agent 系統

    Hippo 可以:

    • 把 NPC 的「人生事件」「人際關係」「信念」拆成不同記憶
    • 讓同一個角色在不同局遊戲中保有成長、偏好

    具體做法:

    • 每次玩家與 NPC 互動後,將關鍵事件寫入該 NPC 的記憶庫
    • 下次載入遊戲時,先載入角色記憶,再生成回應

    怎麼開始:本機跑一個有長期記憶的 Agent

    下面示範:在本機用一個輕量開源 LLM + Hippo 跑出一個最小可用的長期記憶 Agent。

    1. 安裝依賴(Python)

    假設你有 Python 3.10+,先開一個虛擬環境:

    python -m venv venv
    source venv/bin/activate  # Windows 用 venv\Scripts\activate
    
    pip install hippo-memory
    pip install transformers accelerate sentence-transformers
    

    如果你想用 Ollama / 本機模型,也可以只要 HTTP API,把 llm_call() 改成呼叫本地端服務即可。

    2. 建一個最小記憶介面

    概念流程:

    1. 使用者說話
    2. Agent 回應(用 LLM)
    3. 用 LLM 檢查這輪對話有沒有值得記住的東西
    4. 需要記住的就丟給 Hippo
    5. 下一輪對話前,從 Hippo 取出相關記憶加進 prompt

    簡化版範例(偽代碼結構):

    from hippo_memory import HippoMemory
    
    memory = HippoMemory()
    
    def llm_call(prompt: str) -> str:
        # TODO: 換成你實際使用的本機 LLM(Ollama / vLLM / transformers)
        ...
    
    
    def summarize_for_memory(dialogue: str) -> list[dict]:
        """讓 LLM 決定要存哪些記憶,回傳 list[{"type":..., "content":..., "importance":...}]"""
        prompt = f"""
    你是記憶管理員。以下是剛剛的一段對話:
    {dialogue}
    
    請列出值得長期記住的事情(使用者偏好、長期目標、重要事件)。
    用 JSON 陣列輸出,每個元素包含 type, content, importance(1-5)。
    如果沒有,回傳 []。
    """
        import json
        res = llm_call(prompt)
        return json.loads(res)
    
    
    def add_dialogue_to_memory(history: list[tuple[str, str]]):
        # history = [(user_msg, assistant_msg), ...]
        text = "\n".join([f"User: {u}\nAssistant: {a}" for u, a in history[-3:]])
        items = summarize_for_memory(text)
        for item in items:
            memory.add_memory(
                mem_type=item["type"],
                content=item["content"],
                importance=item.get("importance", 3),
            )
    
    
    def chat_loop():
        history = []
        while True:
            user = input("你:")
            if user.strip().lower() in {"exit", "quit"}:
                break
    
            # 1) 先查記憶
            relevant = memory.retrieve_memories(query=user, top_k=5)
            memory_text = "\n".join([f"- {m.content}" for m in relevant])
    
            # 2) 組 prompt
            prompt = f"""你是一個會記住使用者的助理。
    以下是你對這位使用者的已知記憶:
    {memory_text or '(目前沒有特別記憶)'}
    
    現在的對話:
    使用者:{user}
    請根據記憶與對話回應。
    """
            assistant = llm_call(prompt)
            print("Agent:", assistant)
    
            history.append((user, assistant))
            add_dialogue_to_memory(history)
    
    
    if __name__ == "__main__":
        chat_loop()
    

    你可以採取的行動

    • 把上面程式框架複製到自己的專案
    • llm_call() 替換成你現用的 LLM(如 Ollama 的 /api/chat
    • 用幾輪「自我介紹 → 問之前說過什麼」來測試記憶效果

    3. 接到 LangChain / LangGraph 的 memory 模組

    如果你已經在用這些框架,可以這樣思考:

    • LangChain:
    • 寫一個 HippoMemoryWrapper,實作 load_memory_variables + save_context
    • 內部直接呼叫 HippoMemory.add_memory() / retrieve_memories()
    • LangGraph:
    • 把 Hippo 抽成一個 node:「更新記憶」與「擷取記憶」
    • 在主對話 graph 中,讓每輪都經過這兩個 node

    這樣你不用推翻原有設計,只是把記憶 backend 換成更聰明的 Hippo。


    小結:什麼時候值得上 Hippo?

    你可以用一個簡單判斷:

    • 只做「單次任務、一次對話就結束」的 Agent → 一般向量資料庫就夠
    • 需要「跨天、跨專案、角色長期成長」的 Agent → 值得導入 Hippo 記憶

    先從一個很小的場景開始:例如讓你的本機助理 記住你的個人偏好。當你發現它真的記得你說過的事,再把同樣的記憶結構,複製到客服、專案管理或遊戲 NPC 上。

    專案原始碼與設計細節: https://github.com/kitfunso/hippo-memory

    🚀 你現在可以做的事

    • 打開專案頁面,閱讀 Hippo 的 README 與範例程式碼:https://github.com/kitfunso/hippo-memory
    • 在本機建立一個小腳本,實作文中 llm_call() 並跑起示範的記憶型 Agent
    • 將 Hippo 接入你現有的 LangChain / LangGraph 專案,先讓一個特定 user 或 NPC 擁有長期記憶