用 OpenClaw 跟 Agent 解 CRM 的鳥事:人類想方法,AI 拼命試,然後就搞定了

最後更新:2026 年 02 月

TL;DR:這次在 TwentyCRM 自架版本遇到 Note 無法掛到 Person 的坑,我最後用「人類負責找方向(ChatGPT/文件)+ AI 負責快速嘗試 + 全程記錄」的方式,在很短時間內把 SOP 找出來:用 noteTargets 連結,但要寫 targetPersonId,不是 targetPerson

我先講結論:這次讓我更確定一件事——AI 不一定會「自己」把問題想通,但它非常適合當一個不會喊累、願意一直試到對的執行者。

而人類(就是我)最該做的事,是在 AI 卡住的時候,負責把「可能的解法」從外面世界搬回來,丟給它測。

一個人類拿著地圖指路、旁邊有機器人拿工具箱狂奔的扁平插畫
人類找方向、AI 做苦工——這組合,老實說有點猛。

這篇我想用一個很生活化(但也很工程師)的案例,記錄我們怎麼把一個「看起來像 API 壞掉」的問題,最後拆到「其實你寫錯欄位」這種尷尬真相。

然後順便講清楚:為什麼我覺得 OpenClaw 這種 Agent 系統,最值錢的不是它多聰明,而是它把人機協作變成一個可複製、可追蹤的流程。

問題到底是什麼:Note 建好了,但就是掛不到 Person(超煩)

情境很簡單:我在 CRM(TwentyCRM 的自架版本)想做「互動紀錄」。照官方資料模型的概念,一則 Note 可以同時掛到 Person / Company / Opportunity,所以不是在 /notes/people 直接塞關聯,而是要透過一個 junction 物件:noteTargets

也就是三步:

第 1 步:建 Person 拿到 personId。第 2 步:建 Note 拿到 noteId。第 3 步:建 NoteTarget,把 Note 掛到 Person。

聽起來很直覺對吧?結果就翻車了。

CRM 表單上顯示已建立 Note 但關聯欄位空白的扁平插畫
最痛苦的 bug:看起來都成功,但 UI 就是不顯示。

我們遇到的現象是:

✅ Note 可以建立(API 回傳 OK)。

⚠️ NoteTarget 也建立了,但 Person 底下看不到那則 Note。

當時的直覺會以為是「關聯寫入」有問題,或是「資料要 refresh」而已。偏偏試了又試,還是不對。

這種問題最可怕,因為它不是 500 error;它是「默默失敗」。

第一輪錯誤推論:以為是 targetPerson 不能寫(結果只是寫錯地方)

我們一開始看到自架版本的 NoteTarget schema 裡有個欄位叫 targetPerson,看起來就是「我要把它指向某個 Person」的地方。

所以就照字面意思寫:

{ noteId: "...", targetPerson: "..." }

API 也沒直接噴錯。然後 UI 依然沒東西。

這時候很容易做出一個(看似合理的)推論:targetPerson 可能是 MORPH_RELATION(多型關聯),這種欄位常常是「讀取投影用」,不是「寫入外鍵用」。

這推論其實沒錯,但還不完整。

一個 API 欄位標成 MORPH_RELATION 旁邊貼著『read-only』便利貼的扁平插畫
MORPH_RELATION 很常見:看得到,不代表寫得進去。

我們甚至一度打算「放棄 NoteTarget,改用 TimelineActivity 來寫互動紀錄」,因為 TimelineActivity 的 targetPerson 在某些情境真的可以 work。

但我心裡一直覺得怪怪的:官方資料模型都說 NoteTargets 就是用來掛 Note 的,怎麼可能完全不能用?

人類出手的時刻:我去外面找答案(用 ChatGPT + 文件 + 猜欄位命名)

這就是我說的「人類負責想方法」的部分。

當 AI(或任何自動化)卡在「它看得到欄位但寫不進去」的時候,最有效的方式通常不是叫它再想 20 次,而是人類去做一件很人類的事:

去查文件、去看別人的踩坑、去問另一個模型、去把模糊的線索拼起來。

我那時候抓到一個關鍵概念:很多系統會同時存在這兩種欄位:

1) targetPerson:給你讀關聯物件用(可能是 morph relation / projection)

2) targetPersonId:真正落在資料表上的外鍵欄位(才是可寫入點)

而且 TwentyCRM 的文件/規格有時會寫 targetPerson,但實作上你要寫的是 ...Id 版本。

我把這個「可能的方向」丟回給 Andrea,讓她用 Agent 的方式去試。

人類把『targetPersonId』這張卡片遞給 AI,AI 立刻開始狂敲鍵盤的扁平插畫
人類提供假設,AI 負責把假設跑一遍。

AI 負責執行:快速試錯,把 SOP 真的跑通

接下來就是「AI 負責執行」的高光時刻。

我們沒有再糾結在「為什麼文件這樣寫」這種哲學問題,直接走工程師路線:先讓它 work。

於是把第 3 步改成寫:

{ noteId: "<NOTE_ID>", targetPersonId: "<PERSON_ID>" }

結果:✅ 成功。

Person 的 Notes 數量立刻從 1 變 2(刷新後 UI 也出現)。

這一段我最喜歡的不是「成功」本身,而是速度:你只要把方向給對,Agent 真的可以把大量「重複嘗試、驗證、回報」做得很乾淨。

步驟 你做什麼 為什麼 容易踩的坑
1. 建 Person POST /rest/people → 拿 personId 先有目標物件 字段命名(emails/name)依版本不同
2. 建 Note POST /rest/notes → 拿 noteId 先有要掛的內容 body vs bodyV2,某些版本偏好 bodyV2.markdown
3. 建 NoteTarget(關鍵) POST /rest/noteTargets → noteId + targetPersonId 用 junction 物件串接關聯 不要寫 targetPerson(常是 MORPH_RELATION / read-only 投影)

我覺得這就是人機協作最舒服的節奏:人類給「方向」,AI 給「產能」。

你如果硬要 AI 自己從 0 推到 1,有時候它也能,但成本跟不確定性都比較高。

完整記錄:不是「記得」,是「查得到」

這次另一個讓我很爽的點,是整個過程在 Discord thread 裡完整留下來:我們哪一步卡住、哪個欄位被忽略、哪個 payload 成功、最後 SOP 是什麼。

甚至連「寫入記憶失敗(重複標題)」這種小插曲都被抓到,然後修掉。

這種記錄方式有兩個直接好處:

第一,它讓 SOP 變成可複製的,而不是「我大概記得」。

第二,下次再遇到同類型問題,你不用重跑 30 分鐘;你直接搜尋關鍵字就能回到正確做法。這在實務上就是省時間、省心情。

一個對話紀錄被自動整理成 SOP 文件的扁平插畫
人類最常忘的不是知識,是「當初怎麼找到答案」。

如果你想看 TwentyCRM 官方關於 metadata / LLM usage 的說明,這個頁面就是我們對照的基準之一:usage-with-llms(self-host metadata doc)

而 OpenClaw 的整體概念(Agent、工具、工作流)也可以從這裡看:OpenClaw Docs

我從這次學到的三個核心觀點(很不浪漫,但很實用)

1) 人類負責想方法:當 AI 卡住時,去外面把答案搬回來

我覺得 AI 最像的是「很強的同事」,但不是「全知的神」。它會被上下文限制、會被文件差異坑、會把 schema 的投影欄位當成可寫欄位。

這時候最有效的做法,是人類去做研究:看文件、看別人 issue、用另一個模型交叉比對,然後把可行假設丟回來。

2) AI 負責執行:重複嘗試、快速驗證、回報結果

把「粗重」交給 AI 真的很爽。尤其是那種 payload 要調來調去、欄位命名每個版本都不一樣的鳥事。

這次的關鍵就是:別再寫 targetPerson,改寫 targetPersonId。方向一對,後面就一路順。

3) 完整記錄:讓協作變成資產,而不是一次性的火花

工程師最怕的是「這次解了,下次忘了」。所以我很在意記錄這件事。

你不只要記「答案」,還要記「推理過程」跟「哪個假設被否決」。這才是下次能快速復原的關鍵。

常見問題(FAQ)

TwentyCRM 自架版本為什麼不能用 targetPerson 來寫入關聯?

很多情況下 targetPersonMORPH_RELATION 或讀取投影欄位,用來回傳關聯物件,不是用來寫入外鍵。真正可寫入的通常是 targetPersonId 這種 ...Id 欄位。

官方文件寫 personId,我的自架版本卻要用 targetPersonId,正常嗎?

正常。Cloud / self-host、不同版本或不同 workspace schema 可能命名不一樣。最可靠的方式是查你自己的 metadata schema,再決定要寫哪個欄位。

如何確認 noteTargets 到底有哪些「可寫入」欄位?

用你環境的 Metadata API 去看 noteTargets 物件定義,確認有哪些欄位是 ID 外鍵(例如 targetPersonId / targetCompanyId / targetOpportunityId)。

如果寫 targetPersonId 還是不行,下一步該怎麼辦?

先確認 API 有沒有回「unknown field」。若 unknown,再試看看是否是 personId 或其他命名。最後才考慮版本升級或對照官方 cloud 的行為。

OpenClaw / Agent 在這種除錯流程的價值是什麼?

價值是「把試錯變成流水線」:你提供假設,Agent 迅速執行、驗證、回報,並且把整個過程留下可追溯的記錄。

這是不是代表 AI 很弱、不能獨立解決問題?

我覺得不是弱,是分工。AI 很擅長執行和整理,也能推理,但它遇到「文件與實作不一致」時,仍然需要人類把外部資訊帶進來,效率會更高。

把所有討論都記錄下來會不會太吵?

要看你怎麼用。對我來說,能把「最後的 SOP」跟「關鍵轉折(例如 targetPersonId)」記下來就很值了,未來省下的時間通常遠超過整理的成本。

寫到這裡,我其實有一點小小感慨。

很多人期待 AI 變成「一鍵解決所有問題」的魔法,但我目前最常用、也最穩的模式,反而更像莊子那句:「道在屎溺」——道理不在宏大敘事裡,而是在你每天 debug 的那些小坑裡。

人類提供方向,AI 提供產能,系統提供記錄。

這樣就夠了。真的。

你最近有沒有遇到哪種「看起來很小、但卡超久」的系統問題?如果有,丟給我聊聊。我很想知道你的那個坑長什麼樣子。

關於作者

Aceon|部落客 / 創業者 / 喜歡把工具玩到出汁的人

我在做留學顧問的本業之外,也很愛研究 AI、automation、各種看起來「可以省時間」的工具。寫這個部落格主要是想把踩坑過程留下來,順便跟同樣在折騰的人互相取暖。

分類與標籤:AI/AGI 人工智能#

{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}
>