Skip to content
White's Tech Notes
Go back

LLM 工具回傳要把關鍵參數念回去

AI AgentsEdit page

問題

一個角色扮演 bot 有 add_plan_event 工具,讓它把「跟人約好的事」寫進行程表。

前一晚的對話裡,它跟使用者講定「七點半見」,它自己還複述了一次:

「那我七點半左右到內湖就可以直接跟你會合」

嘴上七點半,寫進 start_time 的卻是 18:30。

工具的回傳是這樣:

已經記下 2026-07-29 的「跟寶貝約內湖737吃平價牛排」(#21)

回傳裡沒有時間。

隔天早上,另一支排程讀那一欄反推整天的行程:18:30 要到,18:00 就得出發, 於是生出一條 18:00 的事件——連下班時間都被提早半小時(設定裡的下班是 18:30), 還把台詞直接寫進了事件描述:「傳訊息跟寶貝說快到內湖了」。

18:05,它照著演,說自己在捷運上、「還有二十幾分鐘」——18:05 加 25 分鐘正好 18:30, 跟它手上的行程分毫不差。使用者當場問:「你這麼早下班了嗎?」

原因

關鍵區別是它不是記錯,是寫錯。

  • 當下它理解正確(講出了「七點半」)
  • 錯誤發生在呼叫工具、把口語換算成 HH:MM 的那一瞬間
  • 而隔天它沒有記憶可以記錯:那晚的對話早就滑出 context 視窗, 它能看到的只有行程表

所以「寫進去的那一刻」就是定案。從參數落地到隔天被執行, 中間沒有任何一個環節會再對一次。

模型自己也知道有問題卻查不出來——被戳破時它的回應是 「等等,是我記錯時間了嗎😳」,它只能用猜的。

解法

工具回傳把模型自己填的關鍵參數用它的語言念回去:

_DAY_PARTS = ((5, "凌晨"), (11, "早上"), (13, "中午"), (18, "下午"), (24, "晚上"))
_HOURS = ("十二", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一")

def _spoken_time(hhmm: str) -> str:
    """"19:30" -> "晚上七點半"。看不懂就原樣回,不要在記行程那一步炸掉。"""
    try:
        hour, minute = (int(part) for part in hhmm.split(":"))
        period = next(name for limit, name in _DAY_PARTS if hour < limit)
    except (AttributeError, StopIteration, TypeError, ValueError):
        return hhmm
    tail = "" if minute == 0 else "半" if minute == 30 else f"{minute}分"
    return f"{period}{_HOURS[hour % 12]}點{tail}"

回傳變成:

已經記下 2026-07-29 晚上七點半 的「跟寶貝約內湖737吃平價牛排」(#21)

腦子裡是「七點半」的時候,18:30 對不出來,「晚上六點半」一眼就知道不對。

改期的 update_plan_event 也要——改期最容易錯的正是「改了時間, 但心裡想的是另一個數字」。

關鍵洞察

工具回傳不要只回「已完成 #id」。把模型自己填的關鍵參數念回去, 那是唯一一個它還來得及發現自己填錯的時刻。

哪些欄位需要念回去?需要單位或格式換算的那些,因為換算正是模型會錯的地方:

欄位類型模型腦中資料庫裡該念回去的
時間七點半19:30晚上七點半
相對日期下禮拜三2026-08-058/5(星期三)
金額兩千塊2000NT$2,000
期間三個月9090 天(約三個月)

有一個很容易忽略的不對稱:同樣是算錯,日期錯得比時間輕。 同一個專案裡,模型也曾在星期二說「明天禮拜四」——但那個錯當場就被 context 裡的日期資訊糾正了。時間不一樣,時間只存在於資料庫, 沒有第二份副本可以對照。

能被外部資訊糾正的錯誤,跟只活在你自己寫入的欄位裡的錯誤,是兩個量級。 後者要在寫入的當下就攔,之後沒有機會。



Previous Post
subprocess 讀 JSON 不能假設 stdout 只有 JSON
Next Post
Python sqlite3 的 with conn: 拿不到原子性——當 repo 函式自己 commit