工程實作 34 min read

LINE 串 Claude Code 怎麼接得上話?每則訊息先讓 Claude 判讀,再用 --resume 接回同一個 session

line-talk 把家裡桌機的 Claude Code 接上 LINE:每則訊息開一個新的 claude -p 程序,帶 --resume 接回同一個 session,服務只在 state.json 記下該接哪個 id。訊息進來先交給 Claude(Sonnet)判讀——排任務、聊天還是問進度,新開還是接哪張舊卡,屬於哪個分類——分類存進任務卡,「上次那個」才找得回來;判讀沒回來才退回網址規則與 Haiku。

LINE 串 Claude Code 怎麼接得上話?每則訊息先讓 Claude 判讀,再用 --resume 接回同一個 session
本文目錄 · 13
懶人包
  • 每則 LINE 訊息都會開一個新的 claude -p 程序,但帶 --resume <session id>,所以接的是同一段對話。對話內容存在 Claude Code 自己的 session 檔,服務只記一個 id。
  • 服務的狀態只有一個 state.json:chatSessionId(常駐聊天 session)加上 threads(LINE 訊息 id → session、資料夾、任務卡)。上線兩天,常駐 session 一個檔案就接了 11 則聊天、跨 12 小時。
  • 同時問好幾件事時,chat-lanes.ts 用 Promise 鏈分線:同一條線依序 resume 同一個 session,不同的線並行;常駐 session 正在忙就用 --fork-session 分出一段。
  • 每則訊息先交給 Claude(Sonnet)判讀,一次決定四件事:要排任務、聊天還是問進度;屬於哪個分類;新開還是接續哪張舊任務;要做哪幾種任務。判讀結果直接回給我看,不靠關鍵字規則。
  • 分類存進任務卡,下次判讀時舊任務連分類一起列給 Claude,同網址的標 ★ 排最前面,所以「上次那個」會接回同一張卡、同一個 session。判讀沒回來才退回網址規則或 Haiku 分流。
  • 長按「回覆」跳過判讀,用被引用訊息的 id 直接查出 session。
  • 背景任務一件一張 Markdown 卡片,可以同時跑好幾件。session id 開工前先寫進卡片,服務重啟後用 --resume 接著做。

line-talk 是我自己用的 LINE 官方帳號:手機傳訊息,家裡桌機上的 Claude Code 處理完再推回 LINE。這篇照一則訊息實際走過的程式碼,說明它怎麼讓對話接得上。

LINE → Cloudflare Tunnel → Bun 服務(127.0.0.1:8766,server.ts)→ claude -p --resume <id>

程式是 TypeScript,跑在 Bun 上,主要檔案:

檔案行數做什麼
server.ts632收 webhook、分派訊息、聊天流程
intake.ts161收訊判讀的 prompt、解析與回覆文字
claude.ts79組 claude -p 參數、開程序
chat-lanes.ts49聊天分線
triage.ts42判讀失敗時的 Haiku 分流
jobs.ts219背景任務佇列、任務卡、重啟接續
store.ts179state.json、任務卡讀寫
line.ts213LINE API:reply、push、記訊息 id

📌 目錄

  1. 每則訊息都是新程序,為什麼還接得上?
  2. 一則訊息從進來到回覆走過哪些程式?
  3. 聊天分線怎麼實作?
  4. 每則訊息怎麼先讓 Claude 判讀?
  5. 長按「回覆」怎麼找回原本的 session?
  6. 背景任務怎麼排、怎麼接續?
  7. 「之前那個」是怎麼找到的?
  8. 平常怎麼用:圖文選單
  9. 上線兩天的數字
  10. 限制
  11. 常見問題

🧠 每則訊息都是新程序,為什麼還接得上?

服務裡沒有常駐的 Claude 程序。每則訊息進來,claude.ts 用 Bun.spawn 開一個 claude -p,回答完程序就結束:

// claude.ts
const args = [CLAUDE_BIN, '-p', '--output-format', 'json', '--settings', SETTINGS];
if (opt.systemPrompt) args.push('--append-system-prompt', opt.systemPrompt);
if (opt.sessionId) args.push('--resume', opt.sessionId);
if (opt.sessionId && opt.fork) args.push('--fork-session');
if (opt.newSessionId) args.push('--session-id', opt.newSessionId);
if (opt.quick) args.push('--model', opt.model ?? 'haiku', '--strict-mcp-config', '--tools', '', '--no-session-persistence');

接得上是因為 --resume <session id>。Claude Code 把每段對話存成 ~/.claude/projects/<資料夾>/<session id>.jsonl,--resume 會讀回整段對話再接下去。服務本身只要記住「下一句該 resume 哪個 id」。

記憶分三個地方:

東西放哪誰寫
對話內容~/.claude/projects/<資料夾>/<session id>.jsonlClaude Code
下一句接哪個 session~/.local/share/line-talk/state.jsonline-talk
做過的任務、收過的訊息Obsidian vault 的 line-talk/items/*.md、log.jsonlline-talk
state.json 的長相(id 已遮):
{
  "chatSessionId": "<uuid>",
  "threads": {
    "<LINE 訊息 id>": {
      "sessionId": "<uuid>",
      "cwd": "~/workspace/line-lab/20261023-114229",
      "title": "台北狂騎 WO13:破風、後追、隨機起跑格已上線",
      "item": "20261023-114229"
    }
  }
}
  • chatSessionId:常駐聊天 session。一般聊天都 resume 它;每次聊完把回傳的 session_id 寫回來,順便記輪數和最後一問一答(server.ts:184-187)。
  • 常駐 session 接滿 40 輪或超過 24 小時就換新的,最後一問一答帶進新 session 的第一句,話題不會斷。兩個門檻是 CHAT_SESSION_MAX_TURNS、CHAT_SESSION_MAX_AGE_HOURS。
  • 聊天出錯(不是逾時),而且出錯的就是常駐 session 時清成 null(server.ts:188),下一句會開乾淨的 session。
  • 傳 /new 也是清成 null(server.ts:309)。
  • threads:bot 送出的每則 LINE 訊息 id 都對到一個 session,長按回覆時用(後面講)。最多留 3000 筆。
實際紀錄:常駐 session 現在的 jsonl 檔有 11 則我的訊息,第一則在台灣時間 10/23 01:31、最後一則 13:44,中間每一則都是不同的 claude -p 程序。state.json 有 24 筆 thread,對到 12 個不同的 session,其中 11 筆是常駐 session。

--settings '{"disableAllHooks":true}' 是因為我桌機的 hooks 是給終端機用的,例如結束前擋一下要我檢查任務清單。LINE 那頭沒人能回應,所以全部關掉。

🔀 一則訊息從進來到回覆走過哪些程式?

以一則普通文字訊息為例:

  1. 收 webhook(server.ts 的 Bun.serve):驗 x-line-signature 的 HMAC-SHA256,不對回 401;對了先回 ok 給 LINE,事件丟給 handle() 背景處理。
  2. 只理一個人(handle()):e.source.userId 不是設定的 owner 就記 log 丟掉。文字訊息寫一行到 log.jsonl,交給 onText()。
  3. 分派(onText()),照順序判斷:
- / 開頭的指令(/new、/jobs、/research…)→ 直接處理。 - 有 quotedMessageId(長按回覆)→ 查 threads,找到就帶著那個 thread 進聊天。 - 其他全部交給 judge(),由 Claude 判讀(下一節之後詳講),再依判讀結果走:排任務、回進度、接回舊任務的 session 聊,或進一般聊天。 - 判讀沒回來:有網址、圖片或選單模式就照網址規則排任務;其他進聊天,改用 Haiku 分流。
  1. 先回一句(routeChat()):叫出 LINE 的「輸入中」動畫,用判讀給的線和 ack,以 replyToken 立刻回。
  2. 正式回答(chat()):runClaude(text, { cwd, sessionId, fork, systemPrompt: persona.md }),最長 4 小時,每 15 分鐘 push 一則「⏳ 還在做,已 N 分鐘」。
  3. 送出並記住(line.ts 的 send()):push 回答,第一則訊息帶原訊息的 quoteToken,LINE 會顯示成「引用了你那則訊息」。LINE 回傳的每個訊息 id 都用 rememberThread() 寫進 threads。

是,查得到 thread
不經判讀

否

job

status

chat,接續舊任務

chat,某條忙碌中的線

chat,new

LINE 文字訊息

長按回覆?

resume
那則訊息
或那張卡的
session

Claude 收訊判讀

回判讀內容
排背景任務

回進度

排在那條線後面

開新線
resume 常駐 session
它在忙就 fork

replyToken 先回一句

claude -p 跑完
push 回答並引用原訊息

訊息 id 寫進 threads

send() 先用 replyToken,失敗或過期就改 push:

// line.ts
if (replyToken) {
  const r = await post('/v2/bot/message/reply', { replyToken, messages });
  if (r.ok) ids = await sentIds(r);
}
if (ids === null) {
  const p = await post('/v2/bot/message/push', { to: OWNER, messages });
  if (p.ok) ids = await sentIds(p);
}
if (thread && ids) for (const id of ids) await rememberThread(id, thread);

🧵 聊天分線怎麼實作?

一件事還在跑時,下一則訊息不用等它。chat-lanes.ts 用一個 Map 存所有正在跑的線,每條線是一條 Promise 鏈:

// chat-lanes.ts
lane.pending += 1;
lane.chain = lane.chain.then(async () => {
  try {
    const id = await task(lane.session);
    if (id) {
      lane.session = { id, fork: false };
      if (!lane.sessionIds.includes(id)) lane.sessionIds.push(id);
    }
  } finally {
    lane.pending -= 1;
    if (lane.pending === 0) lanes.delete(laneId);
  }
});
  • 同一條線依序跑:新訊息接在 chain 後面,前一則做完才輪到它。
  • 接同一個 session:每則做完把回傳的 session id 存回 lane.session,下一則就 resume 它。
  • 不同線並行:每條線各自一條鏈,互不等待。
  • 做完就刪:pending 歸零就從 Map 拿掉,所以 Map 裡永遠只有正在忙的線。
  • 線的 id:一般聊天是 chat:<時間戳>,長按回覆是 thread:<session id>。
新開的線從哪個 session 起頭,在 server.ts:143-151:
const chatId = (await chatThread())?.sessionId;
const limits = { maxTurns: CHAT_SESSION_MAX_TURNS, maxAgeHours: CHAT_SESSION_MAX_AGE_HOURS };
const rotate = shouldRotate(!!chatId, await chatMeta(), limits);
// 常駐聊天 session 正被別條線使用時,分出一段新對話:保留聊天脈絡,兩邊不互相覆蓋
const fork = !rotate && !!chatId && lanes.findBySession(chatId) !== null;
const model = CHAT_SIMPLE_MODEL && tri.simple ? CHAT_SIMPLE_MODEL : undefined;
const session = { id: rotate ? undefined : chatId, fork };
  • 常駐 session 閒著 → 直接 --resume 它。
  • 常駐 session 正在別條線上跑 → --resume <id> --fork-session:新的一段看得到之前的對話,但寫進另一個新 session,兩個程序不會同時寫同一個檔。
  • 輪數或時間到了 → 不帶 id 開新 session,第一句前面附上上一輪的問答。
  • 判讀說這句很簡單(打招呼、道謝)而且有設 CHAT_SIMPLE_MODEL → 用小模型回。

⚡ 每則訊息怎麼先讓 Claude 判讀?

一則 LINE 訊息進來,要先回答三個問題才能動手:這是新的事還是延續某件舊事、要做什麼、跟以前哪些東西有關。這三件事都靠語意,「上次那個再深入一點」「這篇寫成 blog 就好」用關鍵字規則判不準,所以交給 Claude 判讀,judge() 在 server.ts:212-231:

claude -p --model sonnet --strict-mcp-config --tools '' --no-session-persistence

不載 MCP、不給工具、不留 session,逾時 45 秒。模型由 INTAKE_MODEL 設定,預設 Sonnet。

prompt 給 Claude 看什麼(intake.ts:60-95)

  • 我的訊息文字、網址、圖片張數;剛點過選單的話,加上選單選的類型。
  • 正在進行的聊天線(標題與已跑幾分鐘)。
  • 最多 40 張舊任務卡,同網址的排最前面並標 ★,其餘取最近的。每張一行:
- <任務 id>|<mm/dd>|<類型>|<狀態>|分類:<分類>|<標題>|<網址>|★同網址

要它判斷的四件事

1. kind:job=要排背景任務;status=在問進度、催;chat=其他。
2. topic:這則屬於哪一類,2–8 字的主題。舊任務有接近的分類就沿用同一個字,方便之後歸在一起。
3. resume:同網址、或明顯在延續那件事(「上次那個」「接著做」「再深入」)才接續,填舊任務 id。只是主題相近不算接續,放 related。
4. types:訊息明講要什麼就照講的;沒明講用預設整條鏈。接續舊任務時,已做過的種類不重做。

kind 是 chat 時另外回 lane(同一件事填正在進行的線編號,否則 new)與 simple(打招呼、道謝這類能用小模型回的)。回傳一行 JSON:

欄位用途
kindjob 排任務、status 回進度、chat 進聊天
topic分類,寫進任務卡 frontmatter,卡片描述顯示成 [分類]
resume要接續的舊任務 id;有值就從那張卡的 session 接著做
types依序要做的任務,例如 research → blog
related相關但不接續的舊任務,報告路徑附進新任務的需求
reason一句話理由,原樣回給我看
ack30 字內的即時回應
判讀結果直接回給我

排任務時,LINE 上收到的是判讀本身,不是一句「收到」。intakeText() 組成的格式:

收到,我的判讀:
・分類:<topic>
・Session:接續 <mm/dd> <類型>「<舊任務標題>」(新開時寫「新開」)
・要做:<類型> → <類型>
・相關舊事:<最多 3 張>
・理由:<reason>

判錯了一眼就看得出來,可以馬上更正。

解析守門(parseIntake(),intake.ts:99-130)

  • 抓第一段 {…} 再 JSON.parse,壞掉回 null。
  • resume、related 只收清單裡真的有的任務 id;types 只收已啟用的類型並去重。
  • 點過選單時,選單的類型強制排第一個。
  • kind 是 job 卻沒有任何類型、kind 不認得、ack 空白 → 整個當判讀失敗。
  • topic 沒給就填「未分類」。
判讀之後走哪裡
判讀結果做什麼
job,新開enqueue() 依 types 排任務,分類寫進卡片
job,接續舊卡derive() 從舊卡開新任務,帶著舊卡的報告路徑;舊卡還在排隊或在跑就不重排
status回 ack 加上目前的任務清單
chat,接續舊卡且卡上有 session進那張卡的 session 聊,cwd 切回它的工作資料夾
chat,其他routeChat(),用判讀給的 lane、simple、ack
判讀沒回來時

逾時或解析失敗不會讓訊息卡住:有網址、圖片或選單模式就照網址規則排任務,回「收到。Claude 判讀這次沒回來,先照規則排」;其他訊息進聊天,改用 triage.ts 的 Haiku 分流(逾時 30 秒)決定進哪條線。

每次判讀在 server.log 寫一行 intake kind=… topic=… resume=… types=…,在 vault 的 log.jsonl 寫一筆 kind:"intake",token 用量記成「聊天(收訊判讀)」,後台看得到這一層花多少。

↩️ 長按「回覆」怎麼找回原本的 session?

這條路不經過判讀,是最準的接話方式。

  1. bot 每次送訊息,LINE API 回傳 sentMessages[].id。send() 把每個 id 對到當時的 thread 寫進 state.json。
  2. 我在 LINE 長按某則 bot 訊息、選「回覆」,webhook 的 message 會帶 quotedMessageId。
  3. onText() 用 findThread(quotedMessageId) 查出 {sessionId, cwd, title, item}。
  4. routeChat() 把它推進 thread:<sessionId> 這條線,resume 那個 session,cwd 也切回當時的資料夾:
// server.ts:123-129
if (req.thread) {
  const running = lanes.findBySession(req.thread.sessionId);
  const t = lanes.push(running?.id ?? `thread:${req.thread.sessionId}`, { label: req.label, session: { id: req.thread.sessionId, fork: false } }, run);
  const ack = typeof judged === 'string' ? `${judged}(接回「${oneLine(req.thread.title, 24)}」那段)` : `收到,${OWNER_NAME},接著這段處理。`;
  await send(replyToken, t.joined ? `收到,${OWNER_NAME}。「${t.lane.label}」那件還在做,做完接著處理這則。` : ack);
  return t.done;
}
  • 引用的是背景任務的完成訊息時,cwd 是那件任務的工作資料夾。追問「README 第三段」時,它是在那個 repo 裡讀。
  • 那個 session 還在某條線上跑,就排在它後面,回「那件還在做,做完接著處理這則」。
  • 判讀說要接續的舊卡上有 session 時,也走這段程式:judged 是判讀給的 ack,後面補上接回哪一段。
  • 引用任務訊息、內容剛好是「寫 blog」「寫成 blog」「寫文章」或「做 shorts」「做成 shorts」時,不進聊天,直接用那件任務開一件新的 blog/Shorts 任務(derive(),下一節)。

🗂️ 背景任務怎麼排、怎麼接續?

研究一個 repo、改一個網站動輒半小時,放在聊天線會一直報進度。這類事走 jobs.ts 的佇列,同時跑幾件由 JOB_CONCURRENCY 決定(預設 1,我的電腦設 4)。

進佇列的入口

  • 判讀為 job 的訊息:startJudgedJob() 依判讀的 types 與 resume 呼叫 enqueue() 或 derive()。
  • 判讀沒回來、但有網址、圖片或選單模式:照網址規則 enqueue()。
  • 改程式模式下的訊息:startJob() 直接排 build 任務。
  • /research <內容> 這類指令。
  • 聊天中交代的事:persona.md 寫明「估計超過 5 分鐘的事一律排背景」,Claude 在 enqueue.jsonl 追加一行,ticker.ts 每 30 秒讀一次、清空、逐行 enqueue():
{"type": "research", "request": "研究這個 repo 的架構", "urls": ["https://github.com/..."]}

每件任務一張卡

enqueue() 產生台灣時間的 id(20261023-134134,同一秒重複就加 -2),建工作資料夾,寫一張 items/<id>.md。frontmatter 每個值都存成 JSON,讀回時逐行 JSON.parse:

---
id: "20261023-134134"
type: "blog"
status: "done"
title: "Graphify 有裝,但只裝了一半:CLI 全域、Claude Code 整合只在暫存複本"
workDir: "~/workspace/line-lab/20261023-134134"
reportPath: "~/workspace/line-lab/20261023-134134/REPORT.md"
sessionId: "<uuid>"
durationMin: 4
summary: "有裝,但只裝了一半。…"
---

內文放原始需求、LINE 摘要、完整報告,以及一行桌機接手指令:

cd "<工作資料夾>" && claude --resume <sessionId>

session id 先寫進卡片,再開工(startFresh()):

// jobs.ts
const sessionId = crypto.randomUUID();
const startedItem: Item = { ...item, status: 'running', sessionId };
await saveItem(startedItem);
// …組 prompt…
return { item: startedItem, res: await runClaude(prompt, { cwd, newSessionId: sessionId, timeoutMs: JOB_TIMEOUT_MS }) };
  • 用 --session-id <自己產的 uuid> 開 session,所以程序還沒結束,卡片上就已經有 id。
  • 服務啟動時 resumeQueue() 掃所有卡片:queued 和 running 都重新排隊。
  • 輪到 running 的那張,runJob() 用 --resume <卡片上的 id> 接著做,prompt 是 job-resume.md:先看工作目錄和 REPORT.md 做到哪,接著做完,不要從頭重來。
  • Claude 回 No conversation found(session 還沒寫入就斷了)就用同一份需求重開。
  • 開機自動啟動:服務註冊成 Windows 工作排程,觸發條件是開機(延遲 30 秒)與登入,登入類型 S4U,不用登入也會跑。
做完推什麼(runJob() 結尾):
  • 讀 REPORT.md 的 ## LINE 摘要 段落推到 LINE;有 ## 等尊上決定 段落就附在後面。沒有摘要段落就算失敗。
  • 結尾固定一句「長按這則訊息「回覆」,可以接著跟我聊這個題目。」這則的訊息 id 會記成 thread,item 欄位是任務 id,cwd 是工作資料夾。
  • 快速回覆按鈕:👍 👎、寫成 Blog、做 Shorts、看進度。「寫成 Blog」送出 postback act=derive&type=blog&item=<id>。
  • derive() 開一件新任務,需求是原需求加一句「延續任務 <id>,那次的研究報告在 <路徑>,先讀它」。

🔎 「之前那個」是怎麼找到的?

session 只負責「接著剛才那段聊」。我問「上週研究的那個 AI 影片工具」時,常駐 session 可能早就換過了,靠的是另外兩層。

第一層是收訊判讀:

  • 每張任務卡有判讀時給的分類(topic),判讀 prompt 要求沿用既有的分類字,同一題材的任務會歸在同一個字下。
  • 判讀時舊任務連分類一起列給 Claude,同網址的標 ★ 排最前面。明顯在延續的填 resume,從那張卡的 session 接著做;只是主題相近的填 related。
  • related 的報告路徑會附在新任務需求的最後,寫成「相關的舊任務,有需要就讀」,新任務開工時就知道以前做過什麼。
第二層是檔案:
  • 每則進出的 LINE 訊息寫一行到 vault 的 log.jsonl(store.ts 的 logMessage())。
  • 每件任務一張 items/*.md,frontmatter 有 status、title、topic、links,內文有摘要與完整報告。
  • persona.md(每次聊天都用 --append-system-prompt 帶上)列出這兩個路徑,並寫明被問「之前那個」時先讀檔再回答。
所以就算是全新的 session,Claude 也會先 grep 卡片找到那件任務,必要時再照卡片上的 sessionId 和 workDir 接著做。Obsidian vault 怎麼讓 Claude Code 讀寫,我在個人知識庫怎麼讓 AI 真的用上寫過另一條路。

📱 平常怎麼用:圖文選單

line-talk 的 LINE 圖文選單,六格分別是研究連結、寫 Blog、做 Shorts、錄音記事提醒、進度找舊東西、使用回顧
選單postback服務做什麼
🔍 研究連結act=menu&k=research回用法提示,記 10 分鐘的研究模式
✍️ 寫 Blogact=menu&k=blog同上,下一則訊息直接開 blog 任務
🎬 做 Shortsact=menu&k=shorts同上,開 Shorts 任務
🎙️ 錄音・記事・提醒act=menu&k=note回用法提示;語音用 faster-whisper 在本機轉文字再進聊天
📋 進度・找舊東西act=jobs列進行中、排隊、最近 6 件完成的任務
📊 使用回顧act=review近 30 天各功能次數、失敗數、👍👎 比例
選單送的是 postback,不是文字,所以不會進聊天紀錄,也不會觸發 Claude。

📊 上線兩天的數字

從 2026-10-22 上線到寫這篇,log.jsonl、state.json 與事件紀錄:

項目數量
LINE 訊息69 則(我傳 20、它回 49)
長按引用回覆2 則
背景任務卡片11 張
state.json 的 thread24 筆,對到 12 個 session
常駐 session 接的聊天11 則,跨 12 小時
單件任務耗時2–88 分鐘
88 分鐘那件是「台北狂騎」網站改版,從 LINE 交代,做完已上線。兩則長按回覆,一則是接著那件任務叫它 commit 並調大 timeout,一則是更正它對需求的理解。

⚠️ 限制

  • 只服務一個人:handle() 只收一個 userId,state.json 只有一個 chatSessionId。要給多人用,兩者都得按使用者拆開。
  • 電腦要開著:關機期間 LINE 的 webhook 打不到,那段時間的訊息不會補處理。
  • 背景任務同時跑的件數有上限:超過 JOB_CONCURRENCY 的任務會排隊,88 分鐘的任務會占住一格。聊天分線不受影響。
  • 判讀會判錯:Claude 只看得到訊息文字、網址和舊任務的標題與分類,看不到網址內容。把延續判成新開時,會開一張新卡。判讀內容會回給我看,判錯就更正;要確定接到哪件事就用長按回覆。
  • 每則訊息多一次模型呼叫:判讀用 Sonnet,最長 45 秒,token 用量在後台的「收訊判讀」一欄。
  • fork 之後常駐 session 只留一份:兩條線做完都會把自己的 session id 寫回 chatSessionId,後完成的那條成為下一句的起點。
  • LINE 不渲染 Markdown:persona.md 規定回覆不用表格、標題、粗體、程式碼框,條列用「・」。

❓ 常見問題

每則 LINE 訊息都開新的 session 嗎?

每則都開新的 claude -p 程序,但 session 不是新的:程序帶 --resume <chatSessionId>,讀回同一段對話再接下去。只有傳 /new、常駐 session 出錯、接滿 40 輪或超過 24 小時,或常駐 session 正在忙要 fork 時,才會換成新的 session。判讀說要接續某張舊任務時,則是 resume 那張卡上的 session。

LINE 官方帳號串 Claude Code 要用 API key 嗎?

line-talk 呼叫本機的 claude CLI,用的是 Claude Code 登入的帳號,服務沒有另外設 Anthropic API key。LINE 這邊需要 Messaging API 的 channel secret 和 access token,放在 .env,不進版控。

長按回覆和直接打字差在哪?

直接打字先經過 Claude 判讀,由它決定新開或接續哪張舊任務;長按回覆用被引用訊息的 id 查 state.json,直接 resume 那則訊息背後的 session,連工作資料夾都切回去,不經過判讀。

背景任務做到一半,可以從電腦接手嗎?

可以。任務卡片裡有 cd "<工作資料夾>" && claude --resume <sessionId>,在終端機貼上就是同一個 session。

收訊判讀多久回應?判讀失敗會怎樣?

逾時上限 45 秒,這是程式設定值,不是實測平均。逾時或格式不對時,有網址、圖片就照網址規則排任務,其他訊息改用 Haiku 分流(逾時 30 秒)決定進哪條聊天線。

🔗 延伸資源

author
陳
陳彥彤

AI 工程師 · AI 顧問。Java 後端 8 年、AI 工程師 2 年。AI 內訓 · AI 導入顧問 · 前後端與雲端培訓。

support

覺得文章有用可以到 GitHub 給個 star,或是透過信箱聊聊 AI 內訓、AI 導入顧問或前後端 / 雲端培訓。

related

相關文章

[AI 教學] · 13min
awesome-agentic-ai-zh 實測:8.4k 星中文 AI Agent 學習地圖,50 支範例跑過 49 支
awesome-agentic-ai-zh 是 Lehigh 博士研究生 Wenyu Chiou 在 2026-05 開的 MIT 授權 repo,用繁中、英文、簡中三語把 AI Agent 從零排到上線,分「用 CLI Agent 做事」和「自己寫 Agent」兩條路,每題附 mock 測試。半年 8.4k 星,我不帶 API key 跑完 50 支測試 49 支通過——當自學或開課骨架可以直接用,只是 Stage 4 框架要一題一個環境裝。
[AI 工具] · 21min
Harness² 是什麼?Google 開源讓 AI agent 不換模型自己改 harness,我用 claude -p 實測 18 次
Harness² 是 Google Research 在 2026-10-09 發表的 Apache-2.0 框架,模型權重不動,讓另一個 LLM 比對執行軌跡後改寫 agent 的 prompt、script、skill,並把附證據的經驗存進 library。我用 claude -p 做了迷你版跑 3 題 18 次全對——分數沒有進步空間,變的是做法被固化成 script,值得搬它的 prompt 設計,不建議直接用官方 repo。
[工作流] · 10min
8 支 Claude Code 旗艦 skill:從開案到發文一條龍
我把每天反覆在做的工作流寫成 8 支 Claude Code 旗艦 skill:開案的 /wez-cms-scaffold、/springboot-init,開發的 /spec-flow、/plan、/review-and-clean,驗收部署的 /screenshot-review、/jenkins-docker,還有發文的 /blog-create。共通點是完成要從輸出端驗、沒驗過就標沒驗過——想要可以寫信跟我拿。