LLM 技術的快速發展為電商領域的自動化行銷和產品開發提供了新的可能性。本文將以 Shopify 外掛推廣為例,詳細介紹如何利用 LLM 工作流程構建一個自動化的外掛開發和推廣系統。此係統能夠分析店鋪資訊、生成外掛構想,並自動撰寫和傳送行銷郵件,大幅提升開發效率和行銷成效。
在實際開發過程中,我們需要將複雜的任務拆解成多個可管理的子任務,例如:取得熱門 Shopify 店鋪清單、分析店鋪詳情、生成外掛構想、撰寫行銷郵件以及傳送郵件。每個子任務都需要明確的輸入和輸出定義,以便於 LLM 的理解和處理。例如,在生成行銷郵件的任務中,輸入應包含外掛構想和店鋪資訊,而輸出則為郵件內容。
為了提高 LLM 任務的效率和準確性,我們可以採用範本提示的方法。透過設計一個包含變數的提示範本,可以根據不同的店鋪和外掛資訊生成客製化的行銷郵件。這種方法可以有效地引導 LLM 生成符合預期結果的內容。此外,Python 程式碼範例也提供了實際操作的參考,方便開發者快速上手。
實作對話代理的深度解析
對話流程控制與上下文理解
在前面的章節中,我們已經看到如何使用大語言模型(LLM)來建立一個基本的對話代理。Table 8-2 中的 run_conversation 函式展示瞭如何包裝 process_messages 函式(見 Example 8-1),從而建立一個簡單但完整的對話代理。整個程式碼是通用的,你可以透過修改系統訊息和工具輕鬆建立所需的行為。
程式碼解析
def run_conversation(messages, model="gpt-4"):
# 省略實作細節
pass
def process_messages(messages, tools):
# 省略實作細節
pass
內容解密:
這段程式碼定義了兩個關鍵函式:run_conversation 和 process_messages。run_conversation 負責執行對話流程,而 process_messages 則處理訊息並呼叫適當的工具。這種設計使得對話代理具有很高的靈活性,可以輕鬆擴充套件和修改。
對話代理的上下文理解能力
對話代理最關鍵的新行為是在最後一次互動中表現出來的,當它正確地將溫度還原到起始點 64ºF。這一步之所以能夠實作,是因為我們現在正確地跟蹤了不僅是當前的互動,還有之前的對話內容。這使得代理能夠參照對話開始時的溫度值。
為什麼上下文理解很重要?
- 連貫性:對話代理能夠記住之前的對話內容,從而在後續的互動中保持連貫性。
- 使用者經驗:使用者不需要重複之前的對話內容,代理能夠根據上下文提供更準確的回應。
- 智慧化:透過上下文理解,對話代理表現出更高的智慧化水平,能夠處理更複雜的對話場景。
使用者經驗設計
在實際應用中,使用者通常會透過更豐富的視覺介面與對話代理互動。Figure 8-3 展示了一個典型的聊天介面,其中包括了一些基本的使用者經驗設計元素。
圖表說明
此圖示展示了一個典型的聊天介面,包括:
- 處理指示器:當代理正在處理使用者請求時,顯示一個轉圈的指示器(標記為 1)。
- 工具使用指示:在代理訊息中顯示一個按鈕(標記為 2),指示代理正在使用工具。
- 工具呼叫詳情:使用者可以點選“Tool calls”按鈕(標記為 3)檢視工具呼叫的詳細資訊。
- 使用者干預:使用者可以修改工具引數(標記為 4)並重新提交請求。
- 重新生成對話:根據使用者修改後的請求,重新生成後續的對話內容(標記為 5)。
隨著對話代理變得越來越複雜,你可能需要花時間思考如何處理本章討論的其他問題,例如:
- 為代理提供適當的工具來處理請求。
- 檢索之前的對話內容。
- 以工件的形式整合資訊。
此外,你可能還需要將代理佈署在 API 後面,處理錯誤,並新增日誌記錄功能。但總的來說,可能性是無限的。你會首先創造什麼?
立即實踐
為了更好地理解本章的內容,請嘗試以下練習:
- 將 Example 8-1 和 Table 8-2 中的程式碼複製到 Jupyter Notebook 中。
- 將溫控工具替換為你自己選擇的領域中的工具。
- 觀察對話助手在不同情況下的反應。
- 調整函式定義,觀察模型準確性的變化。
- 測試當工具出現錯誤時的情況。
提示
編寫函式定義可能是一項繁瑣的工作。你可以將幾個示例複製貼上到 ChatGPT 中,然後向這個對話助手請求新的工具想法和相應的函式定義。透過一點努力,你甚至可以讓 ChatGPT 為你編寫連線真實 API 的函式。
LLM 工作流程:提升任務完成的強度與專注度
在前一章中,我們探討了對話代理(Conversational Agent)的設計與實作,特別是如何利用工具呼叫(Tool Calls)來增強其功能。然而,當我們引入可能修改現實世界資產的工具呼叫時,也引入了新的風險。因此,使用者授權機制變得至關重要,以確保系統的安全性與可靠性。本章將進一步探討如何利用大語言模型(LLM)工作流程來完成更複雜的任務。
為何需要 LLM 工作流程?
傳統的機器學習模型通常只擅長於特定領域的單一技能,例如推文的情感分析、信用卡交易的欺詐檢測、或英法文字翻譯等。然而,隨著 GPT 模型的出現,單一模型現在可以執行多種多樣的任務,跨越不同的領域。儘管模型品質有了顯著提升,但我們仍然遠未達到創造人工通用智慧(AGI)的階段。AGI 是一種能夠達到或超越人類認知水平的 AI,能夠同化知識、進行推理、解決新穎且複雜的問題,甚至產生新的知識。
目前的 LLM 在推理和問題解決方面存在明顯的缺陷,特別是在數學方面,這是科學發現的關鍵組成部分。它們生成的文字展示了對現有知識的廣泛理解,但很少引入新的內容。在訓練之外,這些模型無法學習新資訊。未來的 AGI 將具備強大的能力和通用性,能夠解決複雜問題並適用於任何領域。然而,在當前的 LLM 中,這兩方面的智慧似乎存在著權衡。
LLM 工作流程的優勢
在光譜的一端是對話代理,如前一章介紹的那樣。在極端情況下,像 ChatGPT 這樣的純聊天應用非常通用——它可以與你討論任何你想談的話題。然而,它無法為你解決複雜的任務。如果我們為特定的領域設計代理的系統訊息,並為該領域配備一套工具,那麼該代理在該狹隘領域內完成任務的能力將會增強。儘管如此,對話代理仍然最適合涉及一次一兩個步驟的任務,並且需要使用者的協助。
本章將進一步沿著這個光譜前進,以換取完成更複雜任務的能力。我們將介紹 LLM 工作流程,透過聚焦領域和構建更嚴格的結構來引導 LLM 的決策,從而提高其強度。利用 LLM 工作流程,您可以將大型任務分解為小型、明確定義的任務,這些任務可以高保真地執行。一個監督程式(可能使用或不使用 LLM)協調這些任務,分配工作,收集結果,並按照設計的流程推進,以實作預期的結果。工作流程不會處理任意的使用者請求,而是針對特定任務進行設計,因此比對話代理更能夠完成該任務。
技術實作與挑戰
在實作 LLM 工作流程時,我們需要考慮以下幾個關鍵因素:
- 任務分解:將複雜任務分解為小型、可管理的子任務。
- 任務協調:使用監督程式來協調子任務的執行。
- 結果收集與處理:收集子任務的結果,並根據需要進行處理。
- 流程控制:根據預定義的流程推進任務的執行。
程式碼範例:簡單的工作流程管理
from typing import List, Dict
def execute_task(task: Dict) -> str:
# 執行特定任務
task_type = task['type']
if task_type == 'text_generation':
# 呼叫 LLM 生成文字
return generate_text(task['input'])
elif task_type == 'data_processing':
# 處理資料
return process_data(task['input'])
else:
return "Unknown task type"
def generate_text(input_data: str) -> str:
# 簡單示例:呼叫 LLM 生成文字
# 在實際應用中,這裡會呼叫 LLM 的 API
return f"Generated text based on: {input_data}"
def process_data(input_data: str) -> str:
# 簡單示例:處理資料
return f"Processed data: {input_data}"
def manage_workflow(tasks: List[Dict]) -> List[str]:
results = []
for task in tasks:
result = execute_task(task)
results.append(result)
return results
# 定義工作流程中的任務
tasks = [
{'type': 'text_generation', 'input': 'Hello, world!'},
{'type': 'data_processing', 'input': 'Some data to process'}
]
# 執行工作流程
workflow_results = manage_workflow(tasks)
for result in workflow_results:
print(result)
內容解密:
execute_task函式:根據任務型別執行不同的操作,例如呼叫 LLM 生成文字或處理資料。generate_text和process_data函式:這兩個函式模擬了實際應用中可能需要的操作,例如呼叫 LLM 的 API 或進行資料處理。manage_workflow函式:負責管理工作流程中的任務順序和執行,收集每個任務的結果。- 工作流程定義:透過定義一個包含多個任務的列表來描述工作流程,每個任務指定了其型別和輸入資料。
對話式代理(Conversational Agent)是否足夠?
在探討工作流程代理(workflow agency)之前,讓我們先考慮如果嘗試使用對話式代理來完成越來越複雜的任務會發生什麼。本文將介紹一個例子,一旦我們展示了這種方法的侷限性,我們將在本章的其餘部分繼續討論這個例子。
假設你在一個專門開發Shopify商店前端外掛的小型軟體開發公司工作。業務發展緩慢,因此你產生了一個大膽的想法:構建一個LLM應用程式,用於生成外掛想法並將其推廣給商店前端所有者。以下是實作這一目標的步驟:
- 生成一個流行的Shopify商店前端列表,並檢索其網站的HTML。
- 對於每個商店前端,提取詳細資訊——產品供應、品牌、風格、價值觀等。
- 評估每個商店前端,並提出一個對其業務有益的外掛。
- 生成行銷電子郵件,向每個商店前端所有者宣傳外掛概念。
- 傳送電子郵件。
這聽起來像是一個相當瘋狂的想法,對吧?你基本上是在為尚不存在的軟體產品群發電子郵件!LLM應用程式真的能完成這樣的工作嗎?它是否足夠好,以至於人們可能會回覆你的電子郵件?
答案是肯定的。2023年初,當整個世界開始探索LLM應用程式的新能力和可能性時,一位創業開發者就做了這樣的事情(見圖9-2)。這個線索繼續揭示了一些令人印象深刻的趣聞——成千上萬的行銷電子郵件一鍵傳送,一些非常有創意的產品想法,以及一些來自真正網站所有者的熱情回應。最好的GPT-4生成的想法是為一家襪子商店建立的。它是一個名為Sock-cess Stories的網頁(見圖9-3)。你不得不承認,這是一個很好的銷售推銷。
對話式代理的侷限性
但是,你能用對話式代理實作這一點嗎?讓我們從最簡單的可能性開始:一個沒有工具的對話式代理,以及以下開放式系統訊息:“你是一個有用的助手。你可以做任何事情——你只需要相信。”在介紹中概述的通用性與強度譜上,這個代理是完全通用的,但非常弱。
要啟動Shopify任務,你可以簡單地將指令列表作為使用者訊息傳遞——類別似於“抓取一堆積Shopify商店前端,為每個商店想出新的外掛,然後向每個商店前端傳送關於該想法的促銷電子郵件。”結果,不會太有用。最終,助手會告訴你,它無法搜尋網路、瀏覽特定網站或傳送電子郵件。相反,它會生成一個假設性的計劃,說明你應該怎麼做,這無非是對你原來指令的詳細闡述。
顯然,這種方法根本行不通,但是你可以給你的代理一些工具來幫助它獲得更好的結果。也就是說,給它所需的工具:search_web、browse_site和send_email。這稍微降低了通用性,因為你已經將領域從“任何事情”縮小到“與網路相關的事情”,但它更強大了,因為代理現在可以接觸到真實世界。
如果你用這個更好的對話式代理執行相同的請求,你仍然會感到失望。收集候選商店前端的方法很幼稚——它將提交一個簡單的網路搜尋“最佳Shopify商店前端2024”,生成幾個簡短描述的外掛,並生成一封無非是格式信函的電子郵件,其中包含[your_name]——除非你真的很幸運,否則send_email所做的只是向潛在客戶傳送非常糟糕的行銷郵件。
加強對話式代理
讓我們不要就此放棄;讓我們進一步推動對話式代理,使其更強大,同時降低其通用性。與其要求代理為你完成這項工作,不如將指令移到系統訊息中——從而使這成為一個非常狹隘定義的代理。確保在系統訊息中提供非常具體的細節,涵蓋剛剛提到的所有問題方面。你也可以選擇為代理提供更多有用的工具,根據這項具體工作量身定製,每個工具都有自己的描述和細節。但是,當你這樣做時,你正在進行權衡。
系統訊息和工具的組合將使基本提示變得更大、更複雜,這可能會讓代理感到迷惑和混亂,因為其任務變得越來越長。事實上,情況甚至更糟糕。對話式代理無法提供一種簡單的方法來處理工作單元。一次性將它們全部塞進去將是一場災難,而一次做一個則需要你設定一個佇列——所以你已經知道你將不得不構建比對話式代理更複雜的東西。而且,由於代理在完成工作時有一定的自由度,那麼當某些事情失敗時,你該如何修復它?系統訊息基本上只是一個強烈的建議,而不是更多。
這些負面結果表明需要更多的結構。對話式代理不適合如此複雜的工作流程。相反,這個代理過程中的每一步都應該被隔離並定義為自己的專門任務,並且應該將整個任務集組裝成一個工作流程。在本章的其餘部分,我們將看到工作流程如何更好地滿足我們的需要。
基本LLM工作流程
在本章的後半部分,我們將討論一種工作流程,其中任務的驅動者是LLM。在本文中,我們將討論更常見的LLM工作流程模式,其中每個任務都可能使用LLM,但總體工作流程只是一個傳統的、簡單的工作流程,透過將工作專案從每個任務傳遞到其連線的下游任務來驅動。
如圖9-4所示,構建基本工作流程所需的步驟如下:
定義目標。確定工作流程的目的。工作流程將實作什麼樣的輸出或變化?
指定任務。將工作流程分解為一組任務,當按正確順序執行時,將實作你的目標。對於根據LLM的任務,請考慮每個任務所需的工具。同時確定每個任務的輸入和輸出。
實施任務。按照規格構建任務。確保輸入和輸出被清楚地定義。確保每個任務在隔離狀態下正確工作。
內容解密:
定義目標:這是規劃工作流程的第一步,需要明確工作流程要達成的目標或預期結果。例如,在Shopify外掛生成的例子中,目標可能是自動生成外掛想法並向相關商店前端所有者傳送行銷電子郵件。
指定任務:這一步涉及將整體目標分解為多個具體、可執行的任務。在Shopify外掛生成的例子中,任務可能包括檢索Shopify商店前端HTML、分析內容以提出外掛想法、生成行銷電子郵件以及傳送這些電子郵件。每個任務都需要明確定義其輸入(如所需資料)和輸出(如生成的外掛想法或電子郵件內容)。
實施任務:在這一步中,需要根據前一步指定的任務需求來構建或實作每個任務。這包括選擇合適的工具或技術(如LLM、網頁抓取工具、電子郵件客戶端API),編寫必要的程式碼,並確保每個任務都能正確地獨立執行。例如,使用LLM生成外掛想法的任務需要設計合適的提示詞和解析輸出,而傳送電子郵件的任務可能需要整合電子郵件服務API。
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title LLM工作流程實作Shopify外掛推廣
package "Python 應用架構" {
package "應用層" {
component [主程式] as main
component [模組/套件] as modules
component [設定檔] as config
}
package "框架層" {
component [Web 框架] as web
component [ORM] as orm
component [非同步處理] as async
}
package "資料層" {
database [資料庫] as db
component [快取] as cache
component [檔案系統] as fs
}
}
main --> modules : 匯入模組
main --> config : 載入設定
modules --> web : HTTP 處理
web --> orm : 資料操作
orm --> db : 持久化
web --> cache : 快取查詢
web --> async : 背景任務
async --> fs : 檔案處理
note right of web
Flask / FastAPI / Django
end note
@enduml
此圖示呈現了建立基本LLM工作流程的主要步驟,從定義目標開始,到執行整個工作流程結束。每一步都是構建可靠且有效的工作流程所不可或缺的。
LLM 工作流程的建置與最佳化
在前面的章節中,我們已經討論瞭如何定義目標和拆解複雜任務。在本文中,我們將探討如何將這些任務串連成一個完整的工作流程,並對其進行最佳化,以提升品質、效能和成本效益。
工作流程的建置步驟
- 定義目標:明確工作流程的目標和預期成果。
- 拆解任務:將複雜的問題拆解成多個可管理的子任務。
- 實作任務:根據任務需求,選擇合適的方法(傳統軟體或LLM)來實作每個任務。
- 串連任務:將任務按照邏輯順序串連起來,確保輸出與輸入的匹配。
- 最佳化工作流程:對工作流程進行最佳化,以提升整體效能和成本效益。
以Shopify外掛程式推廣為例
讓我們以Shopify外掛程式推廣為例,來演示如何建置一個成功的工作流程。我們的目標是建立一個LLM應用程式,能夠產生外掛程式想法並向店主推廣。
任務拆解
- 生成熱門Shopify店鋪清單:擷取熱門Shopify店鋪的網站HTML。
- 分析店鋪詳情:從每個店鋪的網站中提取產品、品牌、風格、價值觀等資訊。
- 提出外掛程式想法:根據店鋪分析結果,提出能夠為店鋪帶來價值的外掛程式概念。
- 生成行銷郵件:根據外掛程式概念和店鋪資訊,生成針對店主的行銷郵件。
- 傳送郵件:將生成的行銷郵件傳送給店主。
任務實作
在實作這些任務時,我們需要考慮輸入和輸出的定義。例如,在生成行銷郵件的任務中,輸入應該包括外掛程式概念和店鋪資訊,而輸出則是行銷郵件的內容。
表9-1:用於電子郵件生成的Shopify外掛程式欄位定義
| 欄位名稱 | 資料型別 | 內容說明 | 範例 |
|---|---|---|---|
| name | 文字 | 外掛程式名稱 | Sock-cess Stories |
| concept | 文字 | 基本概念 | 一面牆的故事和與商店商品的自拍 |
| rationale | 文字 | 良好的理由 | 提高參與度和推廣溫暖的品牌形象 |
| store_id | UUID | 用於檢索商店詳情 | 550e8400-e29b-41d4-a716-446655440000 |
表9-2:用於電子郵件輸出的欄位定義
| 欄位名稱 | 資料型別 | 內容說明 | 範例 |
|---|---|---|---|
| subject_line | 文字 | 電子郵件主題 | 為您的店鋪介紹Sock-cess Stories |
| body | 文字 | 電子郵件內文 | 您的襪子商店很棒;我們可以一起讓它更好 |
LLM任務實作方法
在實作根據LLM的任務時,我們可以採用範本提示(Templated Prompt)的方法。這種方法涉及建立一個自定義的提示範本,以滿足特定任務的需求。
表9-3:完成模型的提示範本
# 研究與提案檔案
JivePlug-ins建立令人愉快且盈利的Shopify外掛程式。
本檔案呈現了關於{storefront.name}的研究、我們的
外掛程式概念"{plugin.name}",以及傳送給店主{storefront.owner_name}的電子郵件。