在與大模型語言(LLMs)互動時,如何精確地傳達我們的需求是成功的關鍵。提示工程不僅是一門科學,更是一門藝術。經過多年與各種語言模型的互動經驗,我發現提示的設計對於獲得預期結果有著決定性的影響。

程式碼分隔符的重要性

在技術環境中,清晰地標記程式碼區塊是非常重要的。讓我們看一個簡單的例子:

def my_print(text):
    return print(text)

這段程式碼看似簡單,但它展示了一個重要概念:函式封裝。這裡我們定義了一個名為my_print的函式,它接受一個文字引數,然後透過內建的print函式輸出。雖然這個例子很基本,但它說明瞭在提示工程中如何明確地標記程式碼區段,讓模型能夠清楚識別什麼是指令,什麼是程式碼。

在實際應用中,我常使用三個反引號(```)作為分隔符,這已成為標準做法。這種分隔方式不僅提高了可讀性,更能確保模型正確理解和處理程式碼區塊。

實際應用案例:與GPT模型互動

當需要生成特定功能的程式碼時,清晰的提示設計至關重要。以下是一個完整的互動範例:

query = "generate a Python function to calculate the nth Fibonacci number"

response = openai.ChatCompletion.create(
    model="gpt-3.5-turbo",  
    messages=[
        {"role": "system", "content": system_message},
        {"role": "user", "content": query},
    ]
)

print(response['choices'][0]['message']['content'])

這段程式碼展示瞭如何使用OpenAI API傳送請求。我們建立了一個查詢,要求模型生成計算斐波那契數列的Python函式。注意這裡的結構:

  1. 定義查詢內容
  2. 使用openai.ChatCompletion.create()方法傳送請求
  3. 指定使用的模型(這裡是gpt-3.5-turbo)
  4. 設定訊息格式,包含系統訊息和使用者查詢
  5. 最後提取並列印回應內容

這種結構化的請求方式確保了模型能夠理解我們的意圖,並以預期的格式回應。

提示工程的基礎與進階技巧

在開發AI應用時,無論專案型別如何,一些基本原則都能提升模型的表現。接下來我將分享一些進階技巧,這些方法能顯著改善模型的推理過程和輸出品質。

少樣本學習:以例子引導模型

少樣本學習(Few-shot Learning)是一種強大的技術,可以在不進行微調的情況下定製模型行為。Brown等人的研究證明,GPT-3在少樣本設定下能在多種自然語言處理任務中取得優異表現。

實際應用:產品標語生成

假設我們需要為一款名為"Elevation Embrace"的攀巖鞋生成標語。我們可以使用少樣本學習,提供一些類別似風格的例子:

system_message = """
You are an AI marketing assistant. You help users to create taglines for new product names.
Given a product name, produce a tagline similar to the following examples:
Peak Pursuit - Conquer Heights with Comfort
Summit Steps - Your Partner for Every Ascent
Crag Conquerors - Step Up, Stand Tall

Product name:
"""

product_name = 'Elevation Embrace'

response = openai.ChatCompletion.create(
    model="gpt-3.5-turbo",
    messages=[
        {"role": "system", "content": system_message},
        {"role": "user", "content": product_name},
    ]
)

print(response['choices'][0]['message']['content'])

這段程式碼展示了少樣本學習的實際應用。我們建立了一個系統提示,其中:

  1. 明確定義了AI助手的角色(行銷助理)
  2. 提供了三個產品標語的具體例子,展示了我們期望的風格和格式
  3. 設定了一個明確的輸入格式(產品名稱)

當我們輸入新產品"Elevation Embrace"時,模型會根據提供的例子生成相似風格的標語。這種方法無需詳細解釋要求,只需透過例子展示期望的輸出格式,模型就能理解並模仿這種模式。

輸出結果為:Tagline idea: Embrace the Heights with Confidence.

可以看到,模型成功地保持了我們提供的標語的風格、長度和寫作慣例。這種方法在需要模型遵循特定範本或風格時非常有效。

情感分析的少樣本應用

少樣本學習在專業領域任務中同樣有效。以情感分析為例,我們可以提供一些帶標籤的文字作為參考:

system_message = """
You are a binary classifier for sentiment analysis.
Given a text, based on its sentiment, you classify it into one of two categories: positive or negative.
You can use the following texts as examples:
Text: "I love this product! It's fantastic and works perfectly." Positive
Text: "I'm really disappointed with the quality of the food." Negative
Text: "This is the best day of my life!" Positive
Text: "I can't stand the noise in this restaurant." Negative
ONLY return the sentiment as output (without punctuation).
Text:
"""

這個提示設計了一個二元情感分類別器。關鍵元素包括:

  1. 明確的任務定義(情感分析分類別器)
  2. 分類別類別的清晰說明(positive或negative)
  3. 每個類別的兩個標註例子
  4. 明確的輸出格式要求(僅回傳情感標籤,不帶標點)

這種方式相當於為模型提供了一個小型的訓練集,但不同於微調,我們沒有更新模型引數。

使用IMDb電影評論資料集進行測試:

import numpy as np
import pandas as pd

df = pd.read_csv('movie.csv', encoding='utf-8')
df['label'] = df['label'].replace({0: 'Negative', 1: 'Positive'})

# 隨機抽取10條評論進行測試
df = df.sample(n=10, random_state=42)

def process_text(text):
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[
            {"role": "system", "content": system_message},
            {"role": "user", "content": text},
        ]
    )
    return response['choices'][0]['message']['content']

df['predicted'] = df['text'].apply(process_text)
print(df)

這段程式碼展示瞭如何應用我們的少樣本情感分析器到實際資料上:

  1. 首先讀取IMDb電影評論資料集,並將標籤從0/1轉換為Negative/Positive
  2. 隨機抽取10條評論作為測試樣本
  3. 定義處理函式,將每條評論傳送給模型進行分類別
  4. 使用pandas的apply方法處理所有評論,並將結果儲存在新列中
  5. 最後列印結果,比較真實標籤與預測結果

測試結果顯示,即使只提供了四個例子,模型也能正確分類別所有評論。這充分展示了少樣本學習的強大潛力,在許多情況下,它可以達到與微調相當的效果,但實施成本更低。

思維鏈提示技術

思維鏈(Chain of Thought, CoT)是Wei等人在研究中提出的一種技術,它能激發大模型語言的複雜推理能力。這種方法鼓勵模型透過中間推理步驟解釋其思考過程,避免過快給出可能錯誤的回應。

解決一元一次方程的思維鏈

以解決一元一次方程為例,我們可以引導模型遵循特定的推理步驟:

system_message = """
To solve a generic first-degree equation, follow these steps:

1. **Identify the Equation:** Start by identifying the equation you want to solve. It should be in the form of "ax + b = c," where 'a' is the coefficient of the variable, 'x' is the variable, 'b' is a constant, and 'c' is another constant.

2. **Isolate the Variable:** Your goal is to isolate the variable 'x' on one side of the equation. To do this, perform the following steps:
   a. **Add or Subtract Constants:** Add or subtract 'b' from both sides of the equation to move all constants to the right-hand side.
"""

這個提示開始建立解決一元一次方程的思維鏈框架。它引導模型按照結構化的步驟思考:

  1. 首先識別方程的形式(ax + b = c)
  2. 然後開始隔離變數的過程:
    • 透過加減操作將常數項移到方程一側

雖然這只是思維鏈的開始部分,但它已經展示了這種技術的核心思想:將複雜問題分解為一系列邏輯步驟,引導模型進行有條理的推理。完整的思維鏈還會包括移項、係數處理和最終求解等步驟。

思維鏈技術的優勢在於它能夠:

  • 提高模型處理複雜問題的能力
  • 減少推理過程中的錯誤
  • 使模型的思考過程更透明,便於理解和驗證結果

在開發需要複雜推理的應用時,思維鏈提示是一個非常有效的技術。透過明確的步驟引導,即使是標準模型也能處理複雜的邏輯和數學問題。

提示工程的實踐經驗

在實際應用中,我發現提示工程是一個需要不斷實驗和最佳化的過程。以下是一些我在實踐中總結的經驗:

  1. 提示的精確性比長度更重要:一個簡短但精確的提示通常比冗長但模糊的提示效果更好。

  2. 系統性測試不同提示變體:小的措辭變化可能產生顯著不同的結果,系統性測試各種提示變體有助於找到最佳方案。

  3. 結合多種技術:在複雜應用中,結合少樣本學習和思維鏈等多種技術往往能獲得最佳結果。

  4. 考慮模型特性:不同模型對提示的敏感度不同,為特定模型最佳化提示可以顯著提升效能。

  5. 迭代改進:提示工程是一個迭代過程,根據模型回應不斷調整和最佳化提示。

透過精心設計的提示,我們能夠充分發揮大模型語言的潛力,為各種應用場景提供有效的解決方案。

提示工程的未來發展

隨著語言模型技術的快速發展,提示工程也在不斷演進。我認為未來幾年將出現更多結構化的提示框架和工具,幫助開發者更高效地與模型互動。同時,模型對提示的理解能力也將不斷提升,可能降低對精確提示的依賴性。

然而,無論技術如何發展,理解如何有效地與這些強大的AI模型溝通的核心原則仍將保持重要性。掌握提示工程的藝術與科學,將使開發者能夠更好地駕馭這些技術,創造出更人工智慧、更有用的應用。

提示工程不僅是一項技術技能,更是一種思維方式——它要求我們清晰地表達需求,理解模型的能力和侷限,並創造性地解決問題。隨著我們繼續探索這一領域,將會發現更多提升模型效能的方法,推動AI應用的邊界不斷擴充套件。

ReAct技術:結合推理與行動的語言模型新正規化

在人工智慧領域中,語言模型的推理能力一直是研究的重點。隨著大模型語言(LLM)的發展,我們看到了CoT(Chain-of-Thought)等技術的興起,而ReAct技術則是這一領域的重要突破。在這篇文章中,我將探討ReAct技術的原理、實作方式以及實際應用案例。

線性方程解題:推理過程的基礎

在介紹ReAct之前,讓我們先來看看語言模型如何透過步驟化推理解決數學問題。以下是一個線性方程解題的例子:

equation = "3x + 5 = 11"

response = openai.ChatCompletion.create(
    model="gpt-3.5-turbo",  # engine = "deployment_name"
    messages=[
        {"role": "system", "content": system_message},
        {"role": "user", "content": equation},
    ]
)

print(response['choices'][0]['message']['content'])

這段程式碼展示瞭如何使用OpenAI的ChatCompletion介面來解決一個線性方程。我們提供了方程"3x + 5 = 11"作為輸入,並透過API呼叫取得解題過程。這裡的system_message(雖然沒有顯示)應該包含了指導模型如何解題的提示。這是一個典型的API呼叫模式,使用了role-based的訊息格式,這是ChatGPT介面的標準格式。

當執行這段程式碼時,模型會回傳詳細的解題步驟:

  1. 識別方程:方程是 3x + 5 = 11
  2. 隔離變數:
    • 從兩邊減去5:3x + 5 - 5 = 11 - 5,簡化得 3x = 6
    • 兩邊除以3:3x/3 = 6/3,簡化得 x = 2
  3. 簡化:已經簡化完成
  4. 求解x:x = 2
  5. 驗證解:將x = 2代入原方程,3(2) + 5 = 11,得到6 + 5 = 11,驗證成功
  6. 表達解:方程 3x + 5 = 11 的解是 x = 2
  7. 考慮特殊情況:因為系數3不為零,沒有特殊情況需要考慮

這種逐步推理的方法稱為Chain of Thought(思維鏈),它允許模型"慢慢思考"以解決複雜問題。在處理需要多步驟推理的任務時,這種方法特別有效。

ReAct:思考與行動的協同正規化

ReAct的核心概念

ReAct(Reason and Act)技術由Yao等人在論文《ReAct: Synergizing Reasoning and Acting in Language Models》中提出。這是一個將推理和行動相結合的通用正規化,相比於僅生成推理步驟的CoT,ReAct能夠:

  1. 生成推理跟蹤(Reasoning Traces)
  2. 執行行動(Actions)
  3. 接收外部觀察(Observations)
  4. 根據這些訊息動態調整行動計劃

ReAct與CoT的主要區別在於,ReAct不僅能生成中間推理步驟,還能執行行動並接收外部訊息,形成"思考-行動-觀察"的閉環。這使語言模型能夠與外部工具(如網路搜尋)互動,取得最新訊息並根據此調整推理過程。

實作ReAct:LangChain與外部工具整合

以下是一個使用LangChain實作ReAct技術的例子,這個例子展示瞭如何讓語言模型取得最新的奧運會訊息:

import os
from dotenv import load_dotenv
from langchain import SerpAPIWrapper
from langchain.agents import AgentType, initialize_agent
from langchain.chat_models import ChatOpenAI
from langchain.tools import BaseTool, StructuredTool, Tool, tool
from langchain.schema import HumanMessage

model = ChatOpenAI(
    model_name='gpt-35-turbo'
)

load_dotenv()
key = os.environ["SERPAPI_API_KEY"]
search = SerpAPIWrapper()
tools = [
    Tool.from_function(
        func=search.run,
        name="Search",
        description="useful for when you need to answer questions about current events"
    )
]

agent_executor = initialize_agent(
    tools, 
    model, 
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, 
    verbose=True
)

這段程式碼構建了一個根據LangChain的人工智慧代理,能夠使用ReAct方法解決問題。關鍵元件包括:

  1. ChatOpenAI模型:使用gpt-35-turbo作為基礎語言模型
  2. SerpAPIWrapper:包裝了SerpAPI,允許代理進行網路搜尋
  3. Tool.from_function:將搜尋功能包裝為代理可用的工具
  4. initialize_agent:使用ZERO_SHOT_REACT_DESCRIPTION代理型別,這是一個預建的遵循ReAct方法的代理

這個設定允許語言模型透過網路搜尋工具取得最新訊息,實作與外部世界的互動。verbose=True引數讓我們能看到代理的中間思考過程。

ReAct提示範本解析

當我們檢查agent_executor的提示範本時,可以看到ReAct方法的核心結構:

Answer the following questions as best you can. You have access to the following tools:
Search: useful for when you need to answer questions about current events

Use the following format:
Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [Search]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question
Begin!
Question: {input}
Thought:{agent_scratchpad}

這個提示範本定義了代理如何使用ReAct方法解決問題的格式:

  1. 首先列出了代理可用的工具(這裡是Search工具)
  2. 然後詳細說明瞭代理應該遵循的格式:
    • Question:原始問題
    • Thought:代理的思考過程
    • Action:要採取的行動(這裡是Search)
    • Action Input:提供給行動的輸入
    • Observation:行動的結果
    • 這個思考-行動-觀察迴圈可以重複多次
    • 最後,代理提供最終答案

這個結構化的格式強制代理遵循ReAct方法論,使其能夠在思考和行動之間切換,根據新取得的訊息調整策略。

ReAct實戰:解答2024巴黎奧運攀巖選手問題

以下是使用ReAct代理回答關於2024巴黎奧運會的問題的實際例子:

agent_executor('who are going to be the italian male athletes for climbing at the Paris 2024 Olympics?')

執行這個查詢時,我們可以看到代理的完整思考-行動-觀察迴圈:

  1. 思考:我應該搜尋關於2024巴黎奧運會義大利男子攀巖運動員的最新訊息

  2. 行動:Search

  3. 行動輸入:“Italian male athletes climbing Paris 2024 Olympics”

  4. 觀察:一些攀巖運動員已確保參加2024巴黎奧運會,其中義大利的Matteo Zurloni和印尼的Desak Made Rita Kusuma Dewi不僅獲得了奧運資格,還在各自類別中獲得了世界冠軍

  5. 思考:我需要最佳化搜尋以找到更完整的義大利男子攀巖運動員名單

  6. 行動:Search

  7. 行動輸入:“List of Italian male climbers Paris 2024 Olympics”

  8. 觀察:義大利派出了五名男子體操運動員…(訊息不完整)

  9. 思考:這些訊息似乎不太可靠,我應該嘗試聯絡義大利攀巖聯合會取得更多訊息

  10. 行動:Search

  11. 行動輸入:“contact information for Italian climbing federation”

  12. 觀察:IFSC總公司:Corso Vinzaglio 12 10121, Torino, ITALY…

  13. 思考:我可以聯絡義大利攀巖聯合會詢問參加2024巴黎奧運會的男運動員名單

  14. 嘗試無效行動:Contact(不是有效工具)

  15. 思考:我將進一步最佳化搜尋以檢視是否有關於義大利男子攀巖運動員的最新訊息

  16. 行動:Search

  17. 行動輸入:“Latest updates on Italian male climbers for Paris 2024 Olympics”

  18. 觀察:Aleksandra Miroslaw和Bassa Mawem已獲得明年巴黎2024奧運會的參賽資格…

這個例子生動展示了ReAct方法的工作原理:代理不斷思考、執行動、接收觀察結果,然後根據這些訊息調整下一步行動。當一個行動路徑不成功時(如嘗試聯絡義大利攀巖聯合會),代理會嘗試其他方法。

ReAct技術的優勢與應用場景

ReAct相比純推理方法的優勢

從上面的例子可以看出,ReAct技術相比純推理方法(如CoT)有以下明顯優勢:

  1. 訊息取得能力:能夠取得外部最新訊息,不受預訓練資料時間限制
  2. 自我糾錯:當一個行動路徑不成功時,可以嘗試其他方法
  3. 動態適應:能夠根據新取得的訊息調整推理過程
  4. 工具使用:能夠利用外部工具擴充套件自身能力邊界

這些優勢使ReAct特別適合需要最新訊息或外部工具支援的任務。

ReAct適用的場景

ReAct技術特別適合以下應用場景:

  1. 訊息檢索任務:需要從網路或資料函式庫取得最新訊息的任務
  2. 多步驟推理:需要多個思考-行動迴圈才能解決的複雜問題
  3. 工具輔助任務:需要使用計算器、翻譯器等外部工具的任務
  4. 互動式問答:需要根據使用者反饋動態調整回答的對話系統
  5. 研究輔助:協助研究人員進行文獻綜述和資料收集

在這些場景中,純推理方法往往因為訊息受限或無法使用外部工具而表現不佳。

ReAct與其他推理技術的比較

推理技術核心特點優勢侷限性
Chain of Thought (CoT)生成中間推理步驟提高複雜推理能力無法取得外部訊息
ReAct結合推理和行動能夠使用外部工具和取得最新訊息需要更複雜的提示設計和工具整合
Tree of Thoughts構建思考樹狀結構可以探索多個推理路徑計算開銷大,實作複雜
Self-Consistency生成多個推理路徑並取多數結果提高準確性需要多次推理,效率較低

ReAct相比其他技術的最大優勢在於能夠與外部世界互動,取得最新訊息並使用專用工具,這使它在處理開放性問題時特別有效。

實作自己的ReAct系統:關鍵步驟與最佳實踐

如果你想實作自己的ReAct系統,以下是一些關鍵步驟和最佳實踐:

設計合適的提示範本

ReAct系統的效果很大程度上取決於提示範本的設計。一個好的ReAct提示範本應該:

  1. 明確定義可用工具及其功能
  2. 清晰規定思考-行動-觀察的格式
  3. 鼓勵代理在每個步驟詳細說明推理過程
  4. 設定合適的停止條件

工具選擇與整合

選擇合適的

大模型語言應用開發實戰:從 LangChain 開始

在現代 AI 開發領域,大模型語言(LLM)已成為構建人工智慧應用的核心技術。本文將介紹如何透過 LangChain 架構將 LLM 整合到實際應用中,提供清晰的技術與實作方向。

大模型語言應用的新時代

大模型語言為軟體開發創造了全新正規化,開啟了一系列以自然對話為基礎的應用型別。這些模型不僅使用者與系統之間的溝通變得更加流暢,還以其獨特的推理能力增強了現有的應用,如聊天機器人和推薦系統。

對企業而言,開發 LLM 驅動的應用已成為保持市場競爭力的關鍵因素。這促使新的程式函式庫和框架如雨後春筍般出現,其中包括 Semantic Kernel、Haystack、LlamaIndex 和 LangChain 等,它們都旨在簡化 LLM 與應用程式的整合過程。

LangChain:LLM 應用開發的根本

LangChain 作為 AI 應用的協調平台,在過去一年經歷了巨大的變革。2024 年 1 月,LangChain 發布了首個穩定版本,引入了全新的套件和程式函式庫組織方式,主要由以下部分組成:

  1. 核心骨架 - 儲存所有抽象和執行時邏輯
  2. 第三方整合層 - 提供各種元件和整合功能
  3. 預構建架構 - 包含可直接使用的架構和範本
  4. 服務層 - 允許將鏈條作為 API 消費
  5. 監控層 - 在開發、測試和生產階段監控應用

LangChain 主要套件

開始使用 LangChain 時,你可以安裝以下三個核心套件:

  • langchain-core:包含整個 LangChain 生態系統的基本抽象和執行時
  • langchain-experimental:包含實驗性的 LangChain 程式碼,主要用於研究和實驗
  • langchain-community:包含所有第三方整合

此外,還有三個額外的套件可用於監控和維護 LangChain 應用:

  • langserve:將 LangChain 可執行元件和鏈條佈署為 REST API,簡化生產環境中的整合
  • langsmith:創新的測試框架,用於評估語言模型和 AI 應用,協助視覺化鏈條中每個步驟的輸入和輸出
  • langchain-cli:官方命令列介面,便於與 LangChain 專案互動,包括範本使用和快速入門

LangChain 表示式語言 (LCEL)

LangChain 引入了 LangChain 表示式語言 (LCEL),以提高文書處理任務的效率和靈活性。LCEL 的主要特點包括:

  • 串流非同步支援:高效處理資料流
  • 批次處理支援:允許批次處理資料
  • 平行執行:透過並發執行任務提升效能
  • 重試和備用機制:透過優雅處理失敗確保穩健性
  • 動態路由邏輯:根據輸入和輸出的邏輯流程控制

技術要求

要完成本文的實作部分,需要滿足以下前提條件:

  • Hugging Face 帳號和使用者存取令牌
  • OpenAI 帳號和使用者存取令牌
  • Python 3.7.1 或更高版本
  • 必要的 Python 套件:langchainpython-dotenvhuggingface_hubgoogle-search-resultsfaisstiktoken(可透過 pip install 輕鬆安裝)

ReAct 推理方法的力量

在深入 LangChain 實作之前,值得一提的是 ReAct(Reasoning + Acting)這一強大的推理方法。這種方法結合了 LLM 的推理能力和執行能力,使模型能夠在給予回答前進行多次思考和行動迭代。

玄貓曾經實際測試過 ReAct 方法,發現它能有效減少模型的幻覺現象,並提高回答的準確性。例如,在查詢「哪些義大利男性攀巖選手已獲得 2024 年巴黎奧運資格」這類別問題時,模型會先收集資訊,思考已獲得的資料,然後才給出謹慎的答案。

這種一步思考並明確定義每個推理步驟的提示方式,使模型變得更加謹慎和智慧,是防止幻覺的絕佳技術。

展望

隨著我們繼續探索 LangChain 及其在實際應用中的使用,將會看到這些技術如何在現實世界中發揮作用。後續內容將涵蓋如何使用 LangChain 與 Hugging Face 開放原始碼模型來構建功能強大的 LLM 驅動應用。

提示工程作為一門新興學科,正在為一類別新的應用程式鋪平道路。我們已經介紹了提示工程的基本原則和高階技術,包括少量學習、思維鏈和 ReAct 方法,這些都是塑造 LLM 推理方法的重要工具。在接下來的實作中,我們將看到這些技術如何在實際應用中發揮作用。

在 AI 和 LLM 快速發展的時代,掌握這些工具和技術將使開發者能夠建立更人工智慧、更有用的應用程式,為使用者提供真正的價值。讓我們繼續深入探索 LLM 應用開發的奧妙世界。