@jc20231028/local-code-agent
v0.1.20
Published
A local coding CLI that uses Ollama or LM Studio models to inspect and modify project files.
Maintainers
Readme
local-code-agent
local-code-agent 是一個本地端 npm CLI,功能方向接近 Claude Code,但模型來源改成你自己電腦上的:
OllamaLM Studio
它會在啟動時先做偵測:
- 讓使用者選擇
Ollama或LM Studio - 使用上下鍵與 Enter 在終端內選擇
- 檢查電腦上是否有安裝該軟體
- 檢查本地 API 是否已啟動
- 檢查是否已有可用的本地模型
- 將使用者選過的
provider/model自動寫回.local-code.json
如果缺少任何一項,CLI 會直接提示使用者先安裝或先下載模型。
目前支援的能力
- 列出檔案
- 讀取檔案
- 讀取專案以外的檔案:在
chat模式用/attach <路徑>附加電腦上任何位置的檔案(跟 Claude Code 一樣,會把解析出來的絕對路徑印在終端機上讓你確認讀到的是哪個檔案),下一則訊息送出時會一併帶給模型分析;模型也可以直接呼叫read_external_file工具讀取你在對話中提到的絕對路徑(唯讀、單檔上限 2MB,見下方「讀取專案以外的檔案」) - 搜尋文字
- 建立資料夾
- 寫入或覆蓋檔案
- 追加內容到既有檔案(
append_file),不用重新輸出整份既有內容 - 進行局部字串替換
- 寫入
.py/.js/.mjs後自動做語法檢查,結果會回饋給模型自我修正 - 執行本地命令(
dotnet build、npm test、python xxx.py等)來編譯/測試/執行程式碼——預設每次執行前會在終端機跳出來問你要不要允許,--allow-commands則整個 session 都自動允許不再詢問 - 上網查資料:
web_search(DuckDuckGo 搜尋,回傳標題/連結/摘要)、web_fetch(抓單一網頁並轉成純文字給模型讀)——讓模型能回答訓練資料截止日之後的新資訊。預設每次連網前也會在終端機問你要不要允許,--allow-network則整個 session 都自動允許不再詢問 - 用
/名稱打關鍵字叫出自訂 Skill(見下方「Skill 系統」) - 任務進度 Checkpoint:存目標/待辦事項,並自動附上最近對話內容,跨 session 恢復(見下方「任務進度 Checkpoint」)
- 背景子任務(
spawn_agent/check_agent/list_agents):模型遇到「多個彼此獨立」的子任務時,可以把其中一個丟到背景執行,自己繼續做別的事,之後再回來取結果(見下方「背景子任務」) - 每一步顯示推理時間與 token 消耗:每次模型回覆後自動印出耗時與 prompt / 生成 token 數,方便即時掌握模型速度與 context 使用量
安裝(推薦,跟 Claude Code 一樣)
從 npm 全域安裝,裝完就能在任何資料夾直接打 local-code,不用額外初始化。以下指令在 Windows(PowerShell / cmd)、macOS、Linux 都通用:
npm install -g @jc20231028/local-code-agent裝完之後,切到任何專案資料夾都可以直接執行:
cd /path/to/your-project # Windows 上對應 cd C:\path\to\your-project
local-code chat注意:一定要加 -g。 如果只下 npm install @jc20231028/local-code-agent(沒有 -g),
npm 只會把執行檔裝進當下專案的 node_modules/.bin,不會加進系統 PATH,
直接打 local-code 會抓不到指令。這種情況下要嘛加 -g 重裝,要嘛用 npx local-code chat 執行。
如果你已經用沒加 -g 的方式裝過,先移除本地安裝再改用全域安裝:
npm uninstall @jc20231028/local-code-agent
npm install -g @jc20231028/local-code-agentWindows 上如果
npm指令解析有問題(例如某些 shell 找不到npm),可以改用npm.cmd代替npm。macOS / Linux 一律用npm即可,不需要(也沒有)npm.cmd。
provider / model 留空時,local-code chat 第一次啟動就會直接跳出互動選單讓你選(見下方「初始化設定」),
不需要先手動跑 local-code init——init 只是用來印出設定檔範例,不是必要步驟。
workspace 預設就是執行當下的 process.cwd(),所以不同專案資料夾會各自使用自己的 .local-code.json / .local-code-state.json(沒有的話 CLI 會在互動模式下詢問並建立)。
本地開發(clone 這個 repo 時使用)
npm install直接執行:
node ./bin/local-code.js help想在其他專案資料夾測試本地修改,可以用 npm link 掛成全域命令:
npm link(Windows 上若 npm 解析有問題可改用 npm.cmd,macOS / Linux 不需要這個副檔名。)
專案結構
bin/local-code.js CLI 進入點,直接呼叫 src/cli.js 的 main()
src/cli.js 指令路由(run/chat/models/init/skills/checkpoint/help),只做組裝
src/cli/
args.js 解析 argv -> {command, prompt, options}
attachments.js /attach 用到的路徑清理與附加內容組裝
progress.js 終端機進度輸出(每步耗時、token 數、工具呼叫摘要)
providerWizard.js 啟動時 provider/model 偵測與互動選單
checkpoints.js checkpoint save/list/show/complete(CLI 版與 chat 內 /checkpoint 版共用)
chat.js 互動式 chat REPL(/provider /model /status /repair /reset /attach ...)
startup.js 啟動時載入「上次任務摘要/最近修改檔案」等提示資訊
help.js help/init 的說明文字
src/agent.js agent 對話迴圈(呼叫 provider -> 解析回覆 -> 執行工具 -> 回填結果)
src/toolCallParser.js 從模型回覆解析 <tool_call> 區塊,含多層 JSON 修復(獨立於 agent 迴圈,方便單獨測試)
src/tools.js 工具(read_file/write_file/run_command/...)定義與核准流程
src/workspace.js 實際檔案系統/程序操作,工具背後的實作
src/providers/ Ollama / LM Studio 的 API 封裝
src/runtime.js provider 偵測、診斷、修復建議
src/checkpoint.js checkpoint 資料結構與存讀
src/config.js .local-code.json / .local-code-state.json 讀寫
src/skills.js Skill 檔案載入與比對
src/ui.js 終端機選單、spinner、輸出格式src/cli.js 原本是單一 1000+ 行的檔案,混雜了參數解析、chat REPL、checkpoint 指令、provider 選擇精靈;已拆成上面 src/cli/ 底下的獨立模組,每個檔案只負責一件事,方便個別測試與修改。src/agent.js 裡原本內嵌的 <tool_call> JSON 容錯解析邏輯(約 260 行)也拆到 src/toolCallParser.js,agent 迴圈本身現在只處理對話流程。
初始化設定(選用)
node ./bin/local-code.js init建立 .local-code.json:
{
"provider": "",
"model": "",
"workspace": ".",
"ollamaBaseUrl": "http://127.0.0.1:11434",
"lmStudioBaseUrl": "http://127.0.0.1:1234",
"ollamaNumCtx": 32768,
"requestTimeoutMs": 180000,
"maxSteps": 12,
"allowCommands": false,
"allowWrites": false,
"allowNetwork": false,
"temperature": 0.2
}ollamaNumCtx(選填):Ollama 的 context window 大小,單位 token。預設值為 32768(工具已自動設定,無需手動調整)。像 web_fetch 抓回來的整頁內容、或多輪對話疊加的工具結果,很容易超過舊版預設的 8192,導致模型回覆被截斷(回覆內容被長度限制截斷)。若你的 GPU 記憶體有限需要縮小,或想換更大值以支援更長對話,可在此欄位覆蓋,也可用環境變數 LOCAL_CODE_OLLAMA_NUM_CTX 設定。
requestTimeoutMs(選填):等待 Ollama/LM Studio 回覆單次請求的逾時毫秒數。預設值為 180000(3 分鐘)。實測發現部分情況下 Ollama 的背景 runner 會卡死、完全沒有 CPU 活動也不會回傳任何回應或錯誤——沒有這個逾時的話,整個 CLI 會永遠卡住沒有任何提示。超時後會拋出清楚的「request timed out」錯誤(而不是無限等待),並照一般的 provider 錯誤處理流程重試/回報。可用 --request-timeout-ms 或環境變數 LOCAL_CODE_REQUEST_TIMEOUT_MS 覆蓋;本地跑很大的模型、生成明顯偏慢時可以調大。
provider 或 model 留空時,程式會在啟動時互動式詢問使用者。
如果目前終端不是互動模式,程式會輸出完整的 provider 診斷摘要。
首次選完後,CLI 會把結果寫回 .local-code.json,下次直接沿用。
用法
列出可用模型:
node ./bin/local-code.js models
node ./bin/local-code.js models --provider ollama
node ./bin/local-code.js models --provider lmstudio單次執行:
node ./bin/local-code.js run "閱讀目前專案,建立一個簡單的 express API"互動模式:
node ./bin/local-code.js chat執行本機命令(編譯、測試、跑程式):
node ./bin/local-code.js run "編譯並執行這個 C# 專案"預設不用加任何參數——模型呼叫 run_command(例如 dotnet build、npm test)時,會直接在終端機印出指令內容並問你 Allow this command? [y/N]:,按 y 才會真的執行。如果不是在真人操作的終端機裡執行(例如透過管道/腳本),沒有 TTY 可以問就會直接安全拒絕。
如果你完全信任這個專案、不想每次都被問,可以整個 session 跳過詢問:
node ./bin/local-code.js run "執行測試並修正失敗案例" --allow-commands同樣地,模型呼叫 write_file、append_file、replace_in_file、make_directory、delete_file、move_file 這些會建立/覆寫/修改/刪除檔案或資料夾的工具時,預設也會先印出要變更的路徑(和內容預覽)並問 Allow this change? [y/N]:,按 y 才會真的寫入;沒有 TTY 時一樣直接安全拒絕。想跳過詢問可以加 --allow-writes:
node ./bin/local-code.js run "幫我建立這個功能的檔案" --allow-writes模型呼叫 web_search(查 DuckDuckGo)或 web_fetch(抓網頁內容)時,一樣預設會先問 Allow this network request? [y/N]:,按 y 才會真的發出連線;沒有 TTY 時直接安全拒絕。這讓模型能查到訓練資料截止日之後的新資訊(例如新版本號、近期新聞),不用只靠舊的訓練知識回答。想跳過詢問可以加 --allow-network:
node ./bin/local-code.js run "幫我查一下最新的 Node.js LTS 版本" --allow-networkrun_command/run_command_background 之外的其他工具(list_files、glob_files、read_file、search_text、todo_write、todo_read、read_background_output、list_background_commands)只是讀取或記錄進度,不會跳出詢問;stop_background_command 則沿用 run_command 的指令核准規則。每一步驟模型在做什麼、呼叫了哪個工具、帶了什麼參數,都會即時印在終端機(stderr),不會等到最後才一次顯示結果。
工具清單新增/強化的部分:
glob_files:用檔名 pattern(**/*.ts、src/**/*.test.js)找檔案,取代自己讀list_files再手動篩選。search_text:從單純的子字串比對,升級成類似grep的搜尋——可加regex:true用正規表示式、ignoreCase不分大小寫、contextLines顯示前後文、glob限定副檔名/路徑。read_file:新增offset/limit,讀大檔案時可以只抓一段,回傳內容會自動加上行號(方便之後用replace_in_file精準定位)。delete_file/move_file:刪除、搬移/重新命名工作區內的檔案,同樣走使用者核准流程。todo_write/todo_read:讓模型維護一份多步驟任務的待辦清單(pending/in_progress/completed),方便你即時看到進度,而不是等到最後一次性報告。run_command_background/read_background_output/stop_background_command/list_background_commands:run_command本身是同步阻塞的,不適合拿來跑 dev server 之類長駐程序;這組工具可以在背景啟動、之後輪詢輸出、要停的時候再停掉(Windows 上會連同它產生的子行程一起清乾淨,不會留下孤兒行程)。
模型知道「現在」是什麼時候: 每一則使用者訊息送給模型前,CLI 都會自動加上一行 <current_datetime>2026-08-18 (Tuesday) 14:35 local time (UTC+08:00)</current_datetime>(每次對話都重新產生,不是對話開始時固定不變,跨日的長 chat session 也不會用到過期日期)。這是為了讓模型能正確解讀「今天」「明天」「這星期」之類的相對日期,也能拿來比對 web_fetch 抓回來的網頁上寫的發布/更新時間是否真的是最新的,而不是憑空猜測或直接當成訓練資料截止日。這行只加在送給模型的內容裡,/checkpoint 自動擷取的「最近輸入」不會顯示這個標籤。
web_fetch 可以讀取用 JavaScript 動態載入內容的網站(render:true): web_fetch 預設是單純的 HTTP GET 再把 HTML 標籤剝掉,不會執行 JavaScript。像中央氣象署這類「畫面內容要靠前端 JS 抓 API 才會出現」的網站,預設抓回來的只會是導覽列、選單這些結構性文字,沒有實際的天氣數字——模型通常會誠實地說明抓不到內容,而不是編造答案,這部分行為是對的,但問題沒有真正解決。
web_fetch 現在多一個選填參數 render:true:改用公開的 Jina AI Reader(https://r.jina.ai/)在伺服器端把該網頁的 JavaScript 完整執行、渲染後再回傳乾淨的 Markdown 內容,能讀到純 HTTP GET 讀不到的動態內容。System prompt 已經教模型:先試預設的純抓取,如果回來的內容明顯只有導覽選單、沒有真正資料,就對同一個網址再呼叫一次 web_fetch 並加上 render:true。因為導覽選單類的連結列表常常會把真正的內容擠到很後面,render:true 模式也會自動過濾掉「整行都只是一個連結」的導覽列樣式行、並把預設 maxChars 從 8000 提高到 20000,實測(中央氣象署台北縣市預報頁)驗證過完整 7 天預報、紫外線指數等資料都能在這個範圍內讀到。這個 render 請求會比一般抓取慢(最多等 45 秒),所以只當作 fallback,不是預設行為。請注意 render:true 會把該網址送到 Jina AI 這個第三方公開服務做渲染,跟一般 web_fetch/web_search 一樣需要先通過 Allow this network request? 詢問(或 --allow-network)才會發送;如果該網址包含敏感資訊,不建議使用 render:true。
針對天氣查詢,也可以像上面範例一樣改抓 AccuWeather 等本身就把預報資料直接渲染進 HTML 的網站,或用 https://wttr.in/<城市>?format=j1(含未來幾天預報的 JSON)、?format=4(單行摘要)這個純文字氣象服務,兩者都不需要 render:true 就能讀到。
小模型仍可能整個不呼叫工具: 上面這個時間標籤解決的是「模型呼叫了 web_search/web_fetch 之後,該怎麼判斷抓到的內容是不是最新的」;但實測發現部分本地模型(觀察到 gemma、qwen2.5-coder 等幾顆模型都會偶爾如此)在被問到天氣這類問題時,會直接回答「我沒有即時資訊」而完全不嘗試呼叫工具,即使 system prompt 已經明確要求「這類問題一定要先試著呼叫 web_search,不能直接用這句話當最終答案」也一樣,而且同一顆模型不同次也不一定會重現。這是模型本身指令遵循能力/取樣隨機性的限制,不是本工具的網路/工具設定問題;遇到這種情況可以換一顆模型、或同一顆模型重問一次再試。
列出目前可用的 Skill:
local-code skills用關鍵字叫出 Skill(run 跟 chat 都支援,一開頭打 /名稱):
local-code run "/reviewer 看一下 src/agent.js 有沒有明顯 bug"local-code chat
> /skills
> /reviewer 看一下 src/agent.js 有沒有明顯 bug推理進度與 Token 消耗
每次模型回覆後,CLI 會在終端機自動顯示該步驟的耗時與 token 使用量:
step 1: waiting for model...
step 1: 2.3s · prompt 2,450 tok · gen 312 tok
step 1 result: called tool "list_files" -> .
step 2: waiting for model...
step 2: 4.1s · prompt 2,680 tok · gen 847 tok
step 2 result: called tool "write_file" -> scraper.py (1234 chars)欄位說明:
- 耗時:整個 API 來回的實際等待時間(
< 1s顯示毫秒、≥ 1s顯示秒) prompt X tok:這一步送給模型的 prompt token 數(系統提示詞 + 完整對話歷史 + 工具結果,會隨步驟累積增加)gen X tok:模型這一步生成的 token 數
透過這些數字你可以:
- 知道每一步模型在「思考」多久,哪個工具呼叫最耗時
- 觀察 prompt token 是否接近模型的 context 上限(若快超過,考慮
/reset清歷史或用較大的ollamaNumCtx) - 比較不同模型的生成速度
Ollama 的 token 數由 API 直接回傳(
prompt_eval_count/eval_count);LM Studio 使用 OpenAI 格式的usage欄位。若 API 沒有回傳 token 資料,只會顯示耗時。
Skill 系統
Skill 是一份 Markdown 檔,開頭有簡單的 frontmatter,用來把「特定任務的額外指示」跟「這次任務可以用哪些工具」包成一個可重複使用、可分享的單位,類似 Claude Code 的 Skill / Slash command。
放置位置(同名時,專案層級蓋掉使用者層級):
- 專案層級:
<workspace>/.local-code/skills/*.md— 可以連同專案一起 commit,團隊共用 - 使用者層級:
~/.local-code/skills/*.md— 個人跨專案共用
檔案格式,例如 .local-code/skills/reviewer.md:
---
name: reviewer
description: Review code changes for bugs, risky edge cases, and style issues.
keywords: rv, code-review
tools: read_file, search_text, list_files
---
You are in "reviewer" mode for this task. Only look for bugs, risky edge
cases, and style issues. Do not modify files unless explicitly asked.欄位說明:
name:必填,唯一識別,也是預設觸發用的/名稱description:必填,local-code skills列表會顯示keywords:選填,逗號分隔的別名,一樣可以用/別名觸發tools:選填,逗號分隔的工具白名單;省略代表這次任務可以用全部工具。模型呼叫白名單以外的工具時,會收到明確的錯誤訊息(不會讓整個 CLI 崩潰),可以在剩餘步數內自行改用允許的工具
觸發方式是明確的 /名稱 前綴(不是讓模型自己語意判斷要不要用),對本地小型模型來說最穩定、可預期:
local-code run "/reviewer 檢查 src/agent.js"reviewer 開頭的指示會被組進送給模型的內容,格式類似:
[Skill: reviewer]
<skill 內文>
Task: 檢查 src/agent.js保留字(不能拿來當 Skill 名稱或別名,會被忽略並印出警告):exit、provider、model、status、skills、reset、repair、doctor。
chat 模式內也可以用 /skills 列出可用 Skill,或直接打 /名稱 ... 觸發。
Chat 指令與記憶重置
chat 對話記錄會存在 .local-code-state.json,下次在同一個資料夾用同樣的 provider/model 開 chat 時會自動還原(restored saved chat history (N turn(s)))。
Chat 內建指令:
/provider切換 provider,同時清空記憶重新開始/model切換 model,同時清空記憶重新開始/status顯示目前 provider、model、workspace、記憶狀態/repair(或/doctor)診斷目前這個 provider:有沒有安裝、本機 API 有沒有連線、有沒有模型、(Ollama)偵測到的版本號,並印出對應的中文修復步驟/reset只清空對話記憶,provider/model/workspace 都不變/attach <路徑>讀取電腦上任何位置的檔案(不限於目前 workspace),下一則你送出的訊息會自動附上這份內容一起給模型(見下方「讀取專案以外的檔案」)/skills列出可用 Skill/exit離開
什麼時候要用 /reset: 對話記憶會把過去的 <tool_result>(包含失敗訊息)一起還原給模型。如果你升級了 local-code(例如修了某個工具的 bug)、或改了 --allow-commands 之類的設定,但這個資料夾的 chat 記憶裡還留著「舊版工具失敗」的紀錄,模型會傾向照著自己之前講過的話回答,即使新版工具其實已經能做到了,也可能還是說「我做不到」。這時候打 /reset 清掉舊記憶重新開始,模型才會重新嘗試。
Provider 連線壞掉時怎麼辦: 如果聊天時連續 3 次收到「provider/model request failed」(例如剛更新完 Ollama 之後常見的 500 Internal Server Error 或 fetch failed),CLI 會自動跑一次診斷,並在最終訊息附上具體修復建議(例如「完全結束 Ollama 再重開」「執行 ollama serve 看有沒有錯誤」「執行 ollama -v 確認版本,必要時到官網重新下載安裝覆蓋」),不用等到失敗也可以隨時手動打 /repair 檢查。這個檢查只會讀取狀態、印出建議,不會自動幫你重啟服務或重新安裝。
實際除錯時發現兩種常見的具體情況,CLI 現在都能分辨出來:
- 請求整個卡住、完全沒回應:Ollama 的背景 runner 有時會卡死,
ollama行程 CPU 使用率是 0% 卻永遠不回覆也不報錯。這種情況現在會在requestTimeoutMs(預設 3 分鐘)後主動逾時並印出「request timed out ... this usually means the ollama process is stuck」,而不是讓整個 CLI 卡住不動。 - 錯誤訊息包含
EOF:代表 Ollama 內部跑模型的 runner 子行程在處理請求途中當掉,通常是顯示卡/系統記憶體不足、模型檔案損毀,或 GPU 驅動更新後不相容。/repair現在會針對這個訊息給出對應的建議(換小一點的模型測試、ollama pull重新下載、檢查記憶體用量、查看server.log),而不是只給通用的「重開 Ollama」建議。
任務進度 Checkpoint
跟 chat 記憶(對話逐字稿)分開,另外提供一套「任務進度」的存檔機制:記錄目標、目前狀態、已完成/待完成的步驟、背景決策、卡關點、關鍵檔案,存在同一個 .local-code-state.json 的 checkpoints欄位裡,跨資料夾重開 chat 或重啟電腦都還在。
存檔時會自動從當下的對話紀錄擷取最近幾則你打過的原始 prompt(會過濾掉 <tool_result> 之類的工具回傳內容,只留你自己輸入的部分),附加進 checkpoint 裡,不用自己手動回想輸入一次。
在 chat 內使用:
/checkpoint # 互動式存檔(依序詢問目標/狀態/已完成/待辦/背景/卡關點/關鍵檔案)
/checkpoint list # 列出所有 checkpoint
/checkpoint show [id] # 顯示指定或目前進行中的 checkpoint 完整內容
/checkpoint complete [id] # 標記完成不進 chat,直接用 CLI 也可以:
node ./bin/local-code.js checkpoint save
node ./bin/local-code.js checkpoint list
node ./bin/local-code.js checkpoint show
node ./bin/local-code.js checkpoint complete只要該資料夾還有「進行中」(未標記完成)的 checkpoint,下次執行 local-code chat 時會自動在最上方顯示,提醒你從待辦步驟繼續,不用自己去找。
讀取專案以外的檔案
預設情況下,list_files/glob_files/read_file/search_text 都只能看到目前 workspace 根目錄底下的檔案(跟 Claude Code 一樣,會擋掉 ../ 這種跳出 workspace 的路徑)。如果想讓模型分析電腦上其他地方的檔案,有兩種方式:
/attach <路徑>(只在chat模式):像 Claude Code 拖檔案進來一樣,輸入絕對路徑(或相對於啟動local-code那個資料夾的相對路徑),例如:> /attach C:\Users\me\Desktop\error-log.txt attached: C:\Users\me\Desktop\error-log.txt (1234 chars) - will be sent with your next message > 幫我看這份 log 裡有什麼問題終端機會印出解析後的絕對路徑,讓你確認實際讀到的是哪個檔案;內容會在你送出下一則訊息時一併附上給模型,附加一次後就清空,不會重複夾帶。
模型主動呼叫
read_external_file:如果你在對話中直接提到一個專案外的絕對路徑,模型也可以自己呼叫這個工具讀取,不需要你先手動/attach。
兩種方式都是唯讀,不能寫入 workspace 以外的地方,單一檔案上限 2MB,且都會回傳(或印出)解析後的絕對路徑,方便確認讀到的是哪一份檔案。
背景子任務
模型可以呼叫 spawn_agent 把一個跟目前任務彼此獨立的子任務丟到背景執行(沿用同一個 workspace 與權限設定),呼叫會立刻回傳 {id, status:"running"},不會卡住主流程。之後模型可以:
check_agent:帶id查詢該子任務目前是running/done/failed,以及完成後的結果list_agents:列出這次 session 內所有背景子任務(最新的在前面)
這是給模型自己在推理過程中決定要不要用的工具,不是給使用者手動下的指令;例如「同時檢查兩個沒有關聯的檔案」這種可以平行處理的任務,模型可能會用 spawn_agent 分派其中一半,自己繼續做另一半,最後再用 check_agent 收結果。
併發上限: 同時間最多只能有 maxConcurrentAgents(預設 3)個背景子任務處於 running 狀態,超過就直接讓 spawn_agent 回傳錯誤(不是排隊等待),提示模型先用 check_agent 收一些結果再繼續開新的。這是因為每個並行的對話請求都會在本地模型伺服器(Ollama/LM Studio)裡各自佔用一份 context/KV-cache,一次開太多平行請求容易把本地伺服器的記憶體/顯存吃爆,讓整個環境變慢甚至掛掉。可以用 .local-code.json 的 maxConcurrentAgents、--max-concurrent-agents 參數或看你要的方式調整這個上限。
限制(目前是最小版本):
- 任務清單只存在記憶體裡,CLI 結束就會消失,不像 chat 記憶或 checkpoint 會落地存檔(清單本身也不會自動清除已完成的舊紀錄,長時間跑的 session 裡會持續累積)
- 子任務如果也需要寫檔/跑指令/連網的核准,一樣會跳出終端機
[y/N]詢問,跟主任務的詢問可能交錯出現,是同一個共用的終端輸入 - 超過併發上限時是直接報錯而不是排隊,模型需要自己用
check_agent等一個任務做完再重試
偵測邏輯
Ollama
- 先檢查
ollama指令或常見安裝路徑 - 再檢查
http://127.0.0.1:11434/api/tags - 如果沒有模型,會提示像
ollama pull qwen2.5-coder:7b
LM Studio
- 先檢查
LM Studio常見安裝路徑或lms指令 - 再檢查
http://127.0.0.1:1234/v1/models - 如果沒有模型,會提示先在 LM Studio 下載並啟用 local server
限制
- 目前仍是 MVP,不是完整複刻 Claude Code
- 工具呼叫仍採 prompt 協議,不是原生 function calling,本地小型模型偶爾會把大段程式碼包進 JSON 時跳脫字元出錯或被輸出長度截斷;CLI 會依序嘗試三種自動修復策略(控制字元修復 → 未跳脫引號提取 → 模型重試),多次失敗才會放棄並清楚回報,但無法保證每次都成功。遇到連續失敗時,建議把任務拆小(例如先用
write_file寫骨架、再用append_file分段補內容)或換用較大的模型-replace_in_file仍是字串替換,不是 AST 或 diff patch - 語法檢查目前只支援
.py(需要系統裝有python/python3/py)與.js/.mjs(用 Node 內建--check),其他副檔名不會檢查 - Skill 觸發只支援明確的
/名稱前綴,沒有 Claude Code 那種依描述語意自動判斷要不要用某個 Skill 的能力 - 模型偶爾會在自然語言回答裡「宣稱」做了某件事但實際沒有呼叫工具(幻覺);system prompt 已要求模型有實際工具結果才能宣稱成功、被問到檔案在哪要先查證,但無法 100% 杜絕,遇到可疑的回答可以直接請它用
list_files/read_file再次確認 - 較弱的本地模型有時只會回一句「讓我看看/我將確認一下」之類的意圖描述、卻沒有在同一則回覆裡附上
<tool_call>;CLI 會偵測這種「只講意圖沒動作」的回覆並自動要求模型補發真正的<tool_call>,連續三次仍是如此才會放棄並清楚回報(而不是把那句話當成任務已完成的最終答案) - 部分具備「思考」模式的模型(例如 GLM 系列)透過 Ollama 呼叫時,預設會把整段推理塞進獨立的
thinking欄位、content留空,導致原本該有的回覆消失;CLI 呼叫 Ollama 時已固定帶上think: false來避免這個情況,對不支援思考模式的模型是無害的 - 少數模型(觀察到 GLM 系列)的 Ollama 對話模板內建原生 tool-calling 解析器,可能誤判本工具自訂的
<tool_call>{"tool":...}</tool_call>純文字協議、回傳 HTTP 500 錯誤;CLI 會把這類 provider 端錯誤當成可重試的失敗處理,連續三次才會停止並清楚回報,不會讓整個run/chat直接崩潰;停止時會順便跑一次 provider 診斷(見上方「Provider 連線壞掉時怎麼辦」),把「服務沒開/沒裝/剛更新完不穩」跟「這個模型本身跟工具協議不相容」區分開來
Workspace 掃描的容錯處理
啟動時(例如顯示「最近修改的檔案」)會遞迴掃描 workspace 目錄。掃描邏輯會:
- 略過讀取失敗(權限不足、壞掉的 symlink 等)的檔案或資料夾,不會讓整個 CLI 崩潰
- 最多掃描 5000 個項目,避免在超大型目錄(例如整個使用者家目錄)下卡住
如果直接在很大的資料夾(如使用者家目錄)下執行,建議還是切到實際的專案子資料夾再用 local-code,掃描範圍較小、啟動也更快。
