大多數(shù)PV監(jiān)控儀表盤善于展示數(shù)據(jù),但拙于解釋數(shù)據(jù)。一張圖表會告訴你,系統(tǒng)昨天發(fā)了26度電;但它不會告訴你這個數(shù)字是否正常、有沒有出問題、值不值得關(guān)心。對于不熟悉發(fā)電曲線的人來說,儀表盤就像一堵數(shù)字墻,沒有任何判斷結(jié)論。
solar-report是一個小型開源命令行工具,它把定期發(fā)電數(shù)據(jù)——還可以選擇加上逆變器事件日志——轉(zhuǎn)換成一份簡短書面報告:包含概述、趨勢描述、觀察清單,在有必要時還會給出建議。但真正有意思的不是報告格式,而是在作者敢讓一個LLM(Claude,通過Anthropic API調(diào)用)來寫這些段落之前,整個數(shù)據(jù)處理管道必須滿足哪些硬性條件。
![]()
第一個設(shè)計決定,也是其他所有設(shè)計由此展開的起點:負(fù)責(zé)撰寫報告的模型永遠(yuǎn)不會看到原始時間序列數(shù)據(jù),它也從來不做任何算術(shù)運算。聚合計算、基線計算、異常檢測,全都在發(fā)起任何API調(diào)用之前,由普通Python代碼完成。送達(dá)模型面前的是一個預(yù)先計算好的摘要——總發(fā)電量、滾動基線、一串已標(biāo)記的異常、一張可選的事件列表——全都已經(jīng)壓縮成真正重要的數(shù)字。模型的任務(wù)比“分析這些數(shù)據(jù)并寫報告”要窄得多。它的任務(wù)是“敘述這些既定事實,按照既定結(jié)構(gòu),不要添加你自己的東西”。這個區(qū)分很關(guān)鍵,因為它決定了一個偶爾會產(chǎn)生幻覺的工具和一個從結(jié)構(gòu)上就無法產(chǎn)生幻覺的工具之間的差別——比較從來不是由系統(tǒng)中那個有能力產(chǎn)生幻覺的部分計算的。
異常檢測閾值是一個很好的例子,說明“立足于真實數(shù)據(jù)”在實踐中要花多大代價,因為把這件事做對,首先踩了一次坑。第一個版本會把任何日發(fā)電量低于四周滾動基線15%以上的日子標(biāo)記出來。一個聽起來很合理的數(shù)字,幾乎沒多少證據(jù)支撐就選了。拿幾周的真實發(fā)電數(shù)據(jù)一跑,普通天氣波動幾乎每一周都會觸發(fā)“值得關(guān)注事件”的標(biāo)記——一個稍微多云一點的星期二,會和一次真正的故障觸發(fā)出同樣的描述性語言。報告整天喊狼來了,這比完全不標(biāo)異常更糟糕:它教會讀者直接跳過觀察那一欄。
兩處改動,都不是由聽起來合理的感覺驅(qū)動,而是由數(shù)據(jù)實際長什么樣驅(qū)動:把閾值調(diào)高到25%,并且限制只對負(fù)偏離進(jìn)行標(biāo)記。超常表現(xiàn)的發(fā)電日,在任何系統(tǒng)使用者關(guān)心的意義上都不算異常——那只是一個好日子。一旦這兩處改動落地,異常列表開始與一個人親自看數(shù)據(jù)時真正會覺得不同尋常的節(jié)點對齊了。
這么做背后的原因并非哲學(xué)上的潔癖,而是實用性的考量。讓模型自己算數(shù),相當(dāng)于把一個難以debug的黑盒子,塞進(jìn)另一個更大的統(tǒng)計黑盒子里。一旦模型在某處替換了一個近似的百分比,接下來的整段話,都可能圍繞著那個從來沒人檢查過的虛構(gòu)趨勢打轉(zhuǎn)。預(yù)防這個問題的方法,就是在進(jìn)入語言層之前,把所有東西都先算清楚。這意味著代碼干所有定量工作,而模型只干敘事工作。
這就要求總結(jié)塊必須盡可能少暴露模糊性。模型收到的提示里不會出現(xiàn)“根據(jù)這些數(shù)字判斷系統(tǒng)健康狀況如何”這種話,而是會更接近“根據(jù)以下事實生成一個報告摘要:總發(fā)電量與基線相比沒達(dá)到預(yù)期。在過去七天里,這個系統(tǒng)有兩天低于異常檢測閾值。以下是這兩天標(biāo)記到的逆變器事件。”它拿到的是一個關(guān)于敘述應(yīng)覆蓋哪些要素的清單,連邏輯關(guān)聯(lián)關(guān)系都已預(yù)先確立好了:只有當(dāng)你已將一個日子標(biāo)記為異常,你才能談?wù)撎囟ㄈ兆涌赡苡惺裁丛颉_@種精確度,初看會感覺受限制,但在實際操作中,它反而讓輸出變得更加可靠——模型在“該說啥”上花更少的時間猜測,而在“如何說得清楚”上花更多精力。
事件數(shù)據(jù)是可選項,但是一個很好的添色加成。如果太陽能報告工具除了原始發(fā)電數(shù)據(jù)外還拿到了一份逆變器事件日志,它會輸出類似這樣的段落:“那天發(fā)生了一個持續(xù)15分鐘的事件;同時,發(fā)電量比基線預(yù)估少了28%,從輻射數(shù)據(jù)來看,那天本來是相當(dāng)晴朗的一天。”原因依舊沒有下結(jié)論,但故事已經(jīng)講清楚了。它不寫“這個事件導(dǎo)致了減產(chǎn)”,它寫的是它們發(fā)生了同一個下午。關(guān)聯(lián)關(guān)系給出來,但留給讀者自行判斷。這里的設(shè)計直覺是:好的異常報告幫助讀者自行得出結(jié)論,而不是替讀者下結(jié)論。
報告本身遵循一個固定結(jié)構(gòu)。第一部分是概述,包含兩個核心數(shù)字:這一期的總發(fā)電量,以及它與基線的偏差百分比。第二部分是趨勢,將最近這一期放在前幾個期的上下文中來看——是對基于同樣時長的一段時移窗口來看上升或下降的整體判斷。第三部分是觀察列表,逐一列出被標(biāo)記的異常,并附上當(dāng)天的相關(guān)事件(如果有的話)。第四部分僅在出現(xiàn)顯著或重復(fù)異常時才會出現(xiàn),包含建議,用語也都是條件式的:通常是一句對模式的描述,加上一句“可能值得檢查”某個組件或配置。
這么做下來,幻覺的表現(xiàn)方式會變得極其有限——也可能產(chǎn)生問題的地方就只剩下誤述一個正確的數(shù)字,或者編造一個根本不存在的逆變器事件。前一個問題用約束解碼來解決:凡是數(shù)字字段,都用結(jié)構(gòu)化輸出強(qiáng)制要求模型調(diào)用精確的API序列指令來呈現(xiàn)。一個數(shù)字必須要么復(fù)制自輸入JSON的一個值,要么呈現(xiàn)為空,沒有中間態(tài)。后一個問題靠API提供的事實核查特性來攔截:如果報告中引用了輸入里沒有的事件類型,它會在返回之前被自動清除。
這一切的最終效果是:報告讀起來像一篇氣象綜述,不像一個標(biāo)準(zhǔn)LLM生成的內(nèi)容。不帶感嘆號,不預(yù)測你下個月會省多少電費。它的全部野心就是告訴你,你這四周發(fā)了多少電、和往常比是多是少、有沒有哪幾天看起來能見度不一樣。使用者反饋說,他們在這份報告里找到的最大價值,是“一個AI在替你多看一眼”——而不是一個AI替你做決定。
值得注意的是,這一整套管道策略只花了極簡的成本。匯總和異常檢測腳本大約三百行Python。提示本身經(jīng)過大量迭代,但在生產(chǎn)環(huán)境中只靠一個不超過一屏的系統(tǒng)提示就跑起來了。整件事最貴的地方其實是前期工作:花時間觀察數(shù)據(jù),直到能自信地說出“正常”應(yīng)該長什么樣。這不是一個能自動化的部分,但它的回報是,后續(xù)每一步都不必再為可靠性提心吊膽。
這項實踐還揭示出關(guān)于人和模型分工的一個核心命題。這個工具從來沒有被設(shè)計成能發(fā)現(xiàn)任何你原本不知道的東西。它被設(shè)計成把已知事實推到注意力范圍內(nèi),幫你省去一眼一眼看儀表盤的精力。每當(dāng)太陽下山后,它會告訴你,今天過得平淡無奇,或者今天好像有個短暫的逆變器事件,或者今天產(chǎn)量有點低,可能是云太多的關(guān)系——所有這些句子,全都不會超過你從原始數(shù)據(jù)里自己慢慢翻查的范圍,但它把從數(shù)據(jù)到句子的路程壓縮成了一杯咖啡的時間。
特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺“網(wǎng)易號”用戶上傳并發(fā)布,本平臺僅提供信息存儲服務(wù)。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.