自主代理與大語言模型(LLM)的結合,為複雜任務的自動化處理提供了新的解決方案。LLM賦予代理理解和生成文字的能力,而代理則為LLM提供了與環境互動的途徑。本文重點介紹ReAct框架,它是一種增強LLM回應能力的代理框架,允許LLM在採取行動後觀察結果,並根據觀察結果調整後續步驟。此方法透過迭代式的思考迴圈,有效地解決了複雜問題,並提高了LLM在特定任務上的表現。此外,正規表示式在解析LLM輸出中扮演著關鍵角色,它能夠精確地提取關鍵資訊,例如動作和動作輸入,從而實作更精細的控制和流程自動化。
自主代理與大語言模型(LLM)的協同運作
在探討自主代理(Agents)與大語言模型(LLM)如GPT的整合應用時,我們需要了解自主代理的基本構成及其在LLM中的特殊表現形式。自主代理是一種能夠感知環境、做出決策並採取行動以達成預設目標的實體。在LLM的背景下,這些代理透過文字輸入進行互動,利用LLM的強大處理能力來執行複雜任務。
自主代理的核心組成要素
輸入(Inputs):代理接收來自環境的資料或訊號,這些輸入可以是多樣化的,包括文字、影像、音訊等。在LLM的場景中,輸入主要透過文字形式呈現,但可以透過適當的轉換(如影片的文字轉錄)來處理多模態資料。
目標或獎勵函式(Goal or Reward Function):這定義了代理的行為準則。在根據目標的框架中,代理旨在達到特定的終態;在根據獎勵的設定中,代理則試圖最大化累積獎勵。例如,無人駕駛汽車的主要目標是安全有效地從A點導航到B點,其獎勵函式可能與保持安全距離、遵守速度限制和遵循交通規則相關。
可用行動(Available Actions):這指的是代理在任何給定時刻可以採取的操作範圍。對於無人駕駛汽車來說,可用行動包括加速、減速、轉向、變換車道等。在LLM中,可用行動可以透過整合現成的工具或自定義開發的工具來擴充套件,例如API呼叫、資料函式庫互動或外部系統的協調。
LLM中的自主代理
在LLM的背景下,自主代理的概念被重新詮釋以適應文字驅動的互動模式。這包括:
透過文字輸入進行互動:LLM主要透過文字提示來接收輸入和提供輸出。這要求將多樣化的資料轉換為適合LLM處理的文字表示形式。
利用目標驅動的指令:透過精心設計的提示,LLM能夠解析複雜目標並將其分解為系統性的步驟,從而指導模型達到預期的結果。
透過功能性工具實作行動:LLM不僅限於文字生成,還可以透過整合各種工具來執行多樣化的任務,從而擴充套件其行動空間。
ReAct框架:一種增強LLM回應的代理框架
ReAct框架是原始的CoT(Chain-of-Thought)方法的改進版本,允許LLM在採取行動後建立觀察結果,並根據這些觀察結果決定下一步驟。這個過程持續進行,直到達到最終答案或達到最大迭代次數為止。
ReAct框架的工作原理
初始提示:提供一個初始提示給LLM,定義任務目標。
行動與觀察:LLM根據提示採取行動(例如,呼叫工具),並觀察結果。
迭代過程:根據觀察結果,LLM決定下一步的行動,直到達成最終答案或達到停止條件。
ReAct框架展示瞭如何透過自主代理與LLM的結合來增強模型的回應能力和執行複雜任務的能力。這種方法不僅提高了LLM在特定任務上的表現,也為開發更為智慧和自主的系統提供了新的途徑。
技術深度探討
在實作自主代理與LLM的整合時,開發者需要考慮以下幾個技術層面的挑戰:
輸入資料的多樣性處理:如何有效地將不同型別的資料轉換為LLM可以理解的文字格式。
目標和獎勵函式的定義:如何設計有效的目標或獎勵機制,以引導LLM朝著預期的方向發展。
擴充套件LLM的行動空間:透過整合更多的工具和功能,來增強LLM執行多樣化任務的能力。
程式碼範例:ReAct框架的基本實作
def react_framework(llm, initial_prompt, max_iterations=10):
current_prompt = initial_prompt
iteration = 0
while iteration < max_iterations:
action = llm.get_action(current_prompt)
observation = execute_action(action)
if is_final_answer(observation):
return observation
current_prompt = update_prompt(current_prompt, action, observation)
iteration += 1
return "Maximum iterations reached."
# #### 內容解密:
# 此程式碼範例展示了ReAct框架的基本實作邏輯。首先,它定義了一個函式`react_framework`,該函式接受一個LLM例項、初始提示和最大迭代次數作為引數。然後,它進入一個迴圈,在每次迭代中,LLM根據當前提示採取行動,並觀察結果。如果觀察結果是最終答案,則傳回;否則,更新提示並繼續下一次迭代,直到達到最大迭代次數。
## ReAct框架的深入解析與實作
ReAct框架結合任務分解、思考迴圈及多工具運用來解決複雜問題。本文將探討ReAct框架的核心概念及其Python實作。
### ReAct的思考迴圈機制
ReAct的核心在於其思考迴圈(thought loop),這個過程包括以下步驟:
1. **觀察環境**:接收並理解輸入的問題或環境資訊。
2. **解釋環境**:根據觀察結果進行思考和分析。
3. **決定行動**:選擇適當的工具或行動方案。
4. **執行行動**:使用選定的工具或方法來執行決定的行動。
5. **重複迴圈**:持續執行上述步驟直到找到解決方案或達到迭代次數上限。
#### 實務應用中的思考迴圈範例
在實際應用中,思考迴圈可能涉及多個不同的工具和複雜的決策過程。以下是一個簡化的範例來說明這個過程:
1. **觀察原始問題**:理解輸入的問題內容。
2. **產生觀察結果**:根據對問題的理解產生初步的觀察結果。
3. **形成思考**:根據觀察結果進行深入的思考和分析。
4. **選擇並執行行動**:利用可用的工具來執行決定的行動。
5. **評估結果並重複**:根據執行動動後的結果進行評估,並決定是否需要重複迴圈。
### ReAct提示詞的設計
要實作ReAct框架,需要精心設計提示詞(prompt)來引導大語言模型(LLM)按照預定的思考迴圈進行問題解決。一個典型的ReAct提示詞包含以下元素:
- **問題陳述**:明確需要解決的問題。
- **可用工具**:列出可以使用的工具及其功能描述。
- **思考迴圈指示**:引導LLM按照觀察、思考、行動的步驟進行問題解決。
#### ReAct提示詞範例
```plaintext
你將嘗試解決找到問題答案的任務。使用鏈式思考推理來解決問題,遵循以下模式:
1. 觀察原始問題:original_question: 原始問題文字
2. 建立觀察結果:observation: 觀察結果文字
3. 根據觀察結果建立思考:thought: 思考文字
4. 使用工具對思考採取行動:action: 工具名稱,action_input: 工具輸入
不要猜測或假設工具的結果。相反,提供一個結構化的輸出,包括action和action_input。
你有權存取以下工具:{tools}。
原始問題:{question}
根據提供的工具結果:
要麼提供下一個觀察結果、action、action_input,要麼提供最終答案(如果可用)。
如果您提供最終答案,則必須傳回以下模式:
"我已找到答案:最終答案"
ReAct的Python實作
為了更好地理解ReAct框架的工作原理,我們可以建立一個簡化的Python實作。這個實作將重點放在提取LLM回應中的action和action_input。
程式碼實作
import re
def extract_action_and_input(text):
# 編譯正規表示式模式
action_pattern = re.compile(r"(?i)action\s*:\s*([^\n]+)", re.MULTILINE)
action_input_pattern = re.compile(r"(?i)action\s*_*input\s*:\s*([^\n]+)", re.MULTILINE)
# 查詢所有action和action_input的出現
actions = action_pattern.findall(text)
action_inputs = action_input_pattern.findall(text)
# 提取最後一次出現的action和action_input
last_action = actions[-1] if actions else None
last_action_input = action_inputs[-1] if action_inputs else None
return last_action, last_action_input
# 範例文字
text = """
Action: search_on_google
Action_Input: Tom Hanks's current wife
action: search_on_wikipedia
action_input: How old is Rita Wilson in 2023
action : search_on_google
action input: some other query
"""
last_action, last_action_input = extract_action_and_input(text)
print("Last Action:", last_action)
print("Last Action Input:", last_action_input)
#### 內容解密:
此段程式碼主要功能是從給定的文字中提取最後一次出現的action
和action_input
。首先,我們使用正規表示式來匹配文字中的action
和action_input
模式。然後,透過findall
方法查詢所有匹配的結果。最後,提取最後一次匹配的action
和action_input
並傳回。
import re
:匯入Python的正規表示式模組,用於模式匹配。extract_action_and_input
函式:定義了一個函式來提取action
和action_input
。- 使用
re.compile
編譯兩個正規表示式模式,分別用於匹配action
和action_input
。 - 使用
findall
方法在給定文字中查詢所有匹配的結果。 - 傳回最後一次匹配的
action
和action_input
。
- 使用
- 範例文字:提供了一個包含多個
action
和action_input
的示例文字,用於測試函式功能。
Mermaid圖表示例
graph LR A[開始] --> B[觀察原始問題] B --> C[建立觀察結果] C --> D[根據觀察結果建立思考] D --> E[使用工具對思考採取行動] E --> F[評估結果] F -->|需要重複| B F -->|已找到答案| G[提供最終答案] G --> H[結束]
圖表翻譯:
此圖表呈現了ReAct框架的思考迴圈流程。首先,從觀察原始問題開始,然後建立觀察結果。接著,根據觀察結果進行深入思考,並使用適當的工具採取行動。完成行動後,評估結果以決定是否需要重複迴圈或已找到最終答案。如果需要重複,則回到觀察階段;如果已找到答案,則提供最終答案並結束流程。
正規表示式在大語言模型(LLM)輸出解析中的應用
在處理大語言模型(LLM)的輸出時,經常需要解析複雜的文字結構以提取關鍵資訊。正規表示式(Regular Expression, Regex)是實作此目標的有效工具。本文將探討正規表示式在LLM輸出解析中的具體應用,特別是在提取動作(action)和動作輸入(action_input)等資訊方面的實踐。
正規表示式基礎
在探討具體應用之前,我們先簡要回顧正規表示式的基礎知識。正規表示式是一種強大的文書處理工具,能夠對字串進行搜尋、匹配和提取操作。其基本構成包括:
- 文字匹配:直接匹配指定的文字。
- 特殊字元:如
.
、^
、$
、[
、]
、(
、)
、|
、?
、*
、+
、{
、}
等,具有特殊含義。 - 字元類別:如
\s
(空白字元)、\w
(單詞字元)、\d
(數字字元)等,用於匹配特定類別的字元。 - 重複符號:如
*
(零次或多次)、+
(一次或多次)、?
(零次或一次)等,用於指定匹配的重複次數。
解析LLM輸出的正規表示式模式
在LLM輸出的解析中,我們經常需要提取特定的資訊,如動作(action)和動作輸入(action_input)。以下是一個典型的正規表示式模式,用於匹配這類別資訊:
action_pattern = re.compile(r"(?i)action\s*:\s*([^\n]+)", re.MULTILINE)
action_input_pattern = re.compile(r"(?i)action\s*_*input\s*:\s*([^\n]+)", re.MULTILINE)
模式解析
(?i)
:這是一個內嵌標誌,表示後續的模式匹配是大小寫不敏感的。- 作用:確保能夠匹配不同大小寫形式的「action」或「action_input」。
action
和action\s*_*input
:這兩個部分分別匹配文字「action」和「action_input」。\s*
和_*
:匹配零個或多個空白字元和下劃線,確保能夠處理格式上的變化。
\s*:\s*
:匹配冒號前後的零個或多個空白字元。- 作用:容忍冒號周圍可能出現的空白字元。
([^\n]+)
:捕捉組,用於提取冒號後直到行尾的內容。[^\n]
:匹配任何非換行符的字元。+
:表示至少匹配一個字元。
re.MULTILINE
:使^
和$
匹配每一行的開始和結束,而不僅僅是整個字串的開始和結束。
實作範例
下面是一個完整的Python函式,利用上述正規表示式模式來提取LLM輸出中的最後一個動作和動作輸入:
import re
def extract_last_action_and_input(text):
# 編譯正規表示式模式
action_pattern = re.compile(r"(?i)action\s*:\s*([^\n]+)", re.MULTILINE)
action_input_pattern = re.compile(r"(?i)action\s*_*input\s*:\s*([^\n]+)", re.MULTILINE)
# 查詢所有符合的動作和動作輸入
actions = action_pattern.findall(text)
action_inputs = action_input_pattern.findall(text)
# 提取最後一個符合的動作和動作輸入
last_action = actions[-1] if actions else None
last_action_input = action_inputs[-1] if action_inputs else None
return {"action": last_action, "action_input": last_action_input}
# 示例文字
text = """
action: search_on_google
action_input: some query
...
action: search_on_google
action_input: some other query
"""
# 提取資訊
result = extract_last_action_and_input(text)
print(result) # {'action': 'search_on_google', 'action_input': 'some other query'}
程式碼解說
extract_last_action_and_input
函式:- 接收一個文字字串
text
作為輸入。 - 使用
re.compile
編譯兩個正規表示式模式,分別用於匹配「action」和「action_input」。
- 接收一個文字字串
findall
方法:- 對輸入的
text
使用編譯好的模式進行全部匹配,傳回所有符合條件的字串列表。
- 對輸入的
提取最後一個匹配結果:
- 從
actions
和action_inputs
列表中提取最後一個元素,若列表為空則傳回None
。
- 從
傳回結果:
- 以字典形式傳回最後一個「action」和「action_input」。
處理正規表示式解析錯誤
由於LLM的輸出可能不完全符合預期,正規表示式解析可能會遇到錯誤。常見的處理方法包括:
- 使用LLM修正前一次的輸出:將解析錯誤的輸出回饋給LLM,讓其進行修正。
- 發起新的LLM請求:根據前一次的狀態,重新生成輸出。
這些方法能夠提高系統的穩健性,確保在面對不確定性輸出時仍能有效運作。
結合其他元件實作完整功能
在實際應用中,我們通常需要結合多個元件來實作完整的功能。例如,利用 ChatOpenAI
進行模型互動,並定義可用的工具集:
from langchain_openai.chat_models import ChatOpenAI
from langchain.prompts.chat import SystemMessagePromptTemplate
# 初始化 ChatOpenAI 例項
chat = ChatOpenAI(model_kwargs={"stop": ["tool_result:"]})
# 定義可用工具
tools = {
"search_on_google": {
"function": lambda query: f"Jason Derulo doesn't have a wife or partner.",
"description": "Searches on google for a query",
}
}
# 設定基礎提示範本
base_prompt = """
You will attempt to solve the problem of finding the answer to a question.
...
"""
# 生成模型輸出
output = chat.invoke(SystemMessagePromptTemplate.from_template(template=base_prompt).format_messages(tools=tools, question="Is Jason Derulo with a partner?"))
print(output)
#### 內容解密:
此段程式碼展示瞭如何結合 ChatOpenAI
和正規表示式解析來實作完整的LLM輸出處理流程。首先,定義了一個 ChatOpenAI
例項,並設定停止序列以避免無謂的生成。接著,定義了可用的工具集及其描述。然後,利用 SystemMessagePromptTemplate
設定提示範本,並將工具集和問題傳入模型進行生成。最終輸出模型的回應結果。透過這種方式,可以有效地引導LLM生成結構化的輸出,便於後續的正規表示式解析。
正規表示式在LLM輸出解析中的流程圖示
graph LR; A[接收LLM輸出] --> B[編譯正規表示式模式]; B --> C[執行正規表示式匹配]; C --> D[提取關鍵資訊]; D --> E[處理解析錯誤]; E --> F[傳回解析結果];
圖表翻譯: 此圖示展示了使用正規表示式解析LLM輸出的流程。首先接收LLM生成的文字輸出,然後編譯適當的正規表示式模式,接著執行匹配操作以提取所需的結構化資訊。若遇到解析錯誤,則進行相應的錯誤處理。最終,將解析得到的資訊以結構化的形式傳回,供後續應用使用。透過這個流程,能夠有效地從LLM的非結構化輸出中抽取出有價值的資料。