智慧代理如同一位經驗豐富的廚師,依據顧客需求和可用食材,不斷調整烹飪策略以製作出美味佳餚。代理的認知架構也遵循類別似的迴圈:觀察環境、進行內部推理,並根據推理結果採取行動,最終達成目標。這個迴圈過程的核心在於協調層,它負責維護代理的記憶、狀態、推理和規劃,並利用提示工程技術(如 ReAct、CoT 和 ToT)來引導代理的行為。代理的運作仰賴模型、工具和協調層的緊密合作,模型負責決策,工具提供與外部世界的互動能力,而協調層則負責整體流程的控制和管理。

什麼是代理(Agent)?

在探討人工智慧(AI)的領域中,代理(Agent)是一個能夠觀察周圍環境並根據自身具備的工具採取行動,以達成特定目標的應用程式。代理具備自主性,可以在無需人類干預的情況下獨立運作,尤其是當它們被賦予明確的目標或任務時。即使在缺乏明確的人類指示下,代理也能推理出下一步該採取的行動,以實作其最終目標。

代理的核心組成

要理解代理的內部運作機制,首先需要介紹驅動代理行為、行動和決策的核心組成部分。這些組成的組合可以被描述為認知架構(Cognitive Architecture),而透過這些元件的混合與比對,可以實作多種認知架構。聚焦於核心功能,代理的認知架構中有三個基本組成部分,如圖1所示。

圖1:通用代理架構與組成部分

模型(The Model)

在代理的範疇內,模型指的是將被用作代理程式集中決策者的語言模型(LM)。代理使用的模型可以是一個或多個任何大小的語言模型,只要它們能夠遵循根據指令的推理和邏輯框架,如ReAct、Chain-of-Thought或Tree-of-Thoughts。模型可以是通用、多模態或根據特定代理架構的需求進行微調。為了獲得最佳的生產結果,應利用最適合所需終端應用的模型,理想情況下,該模型應已在與計劃在認知架構中使用的工具相關的資料簽名上進行了訓練。

工具(The Tools)

基礎模型儘管在文字和影像生成方面表現出色,但仍然受到無法與外部世界互動的限制。工具彌補了這一差距,使代理能夠與外部資料和服務互動,從而解鎖了超出基礎模型本身能力的更廣泛的操作範圍。工具可以有多種形式和複雜度,但通常與常見的網頁API方法(如GET、POST、PATCH和DELETE)相一致。例如,工具可以更新客戶資料函式庫中的客戶資訊,或取得天氣資料以影響代理為使用者提供的旅行建議。工具使代理能夠存取和處理現實世界的資訊,從而支援更專業的系統,如檢索增強生成(RAG),這大大擴充套件了代理的能力,使其超越了基礎模型的實作範圍。

協調層(The Orchestration Layer)

協調層描述了一個迴圈過程,該過程控制著代理如何接收資訊、進行內部推理,並利用該推理來指導其下一步的行動或決策。通常,這個迴圈將持續進行,直到代理達到其目標或停止點。協調層的複雜度可以根據代理及其執行的任務有很大差異。一些迴圈可以是簡單的計算與決策規則,而其他的可能包含鏈式邏輯、涉及額外的機器學習演算法,或實施其他機率推理技術。

代理與模型的區別

為了更清楚地理解代理與模型之間的區別,請參考以下對比:

特性模型代理
知識來源訓練資料透過工具與外部系統連線
推理方式單次推斷/預測管理會話歷史,多輪推斷/預測
工具實作無原生工具實作原生工具實作於代理架構中
邏輯層無原生邏輯層原生認知架構,使用推理框架

內容解密:

此表格比較了模型和代理在知識來源、推理方式、工具實作和邏輯層方面的差異。模型主要依賴訓練資料進行單次推斷,而代理則透過與外部系統的連線實作多輪推斷,並具備原生工具實作和認知架構,能夠根據上下文進行更複雜的操作。

認知架構:代理如何運作

想像一位繁忙廚房中的廚師,他們的目標是為餐廳顧客創造美味的菜餚,這涉及到規劃、執行和調整的迴圈過程。同樣地,代理透過其認知架構,不斷迴圈進行觀察、推理和行動,以達成其目標。

此圖示描述了代理運作的基本迴圈過程

內容解密:

此Plantuml圖表展示了代理的基本運作迴圈:首先觀察環境,接著進行內部推理,然後根據推理結果採取行動,最後再回到觀察環境,形成一個持續的迴圈過程。這種迴圈使得代理能夠不斷適應環境變化,朝著其目標邁進。

智慧代理的認知架構與工具整合

在探討智慧代理(Agents)的運作機制時,我們可以從一位廚師的例子開始。廚師在準備一道菜時,會經歷一個資訊收集、內部推理、執行和調整的迴圈過程。這種認知架構使廚師能夠根據客戶的訂單和現有的食材,創造出符合客戶期望的菜餚。同樣地,智慧代理也可以利用認知架構來達成目標,透過不斷處理資訊、做出明智的決定,並根據之前的輸出結果來調整下一步的行動。

認知架構的核心:協調層

智慧代理的認知架構核心在於協調層(Orchestration Layer),負責維護記憶、狀態、推理和規劃。協調層利用快速發展的提示工程(Prompt Engineering)技術和相關框架,引導代理進行推理和規劃,使其能夠更有效地與環境互動並完成任務。

提示工程框架

目前有多種提示工程框架和推理技術可供選擇,包括:

  • ReAct:提供了一種思考過程策略,使語言模型能夠根據使用者查詢進行推理和採取行動。
  • Chain-of-Thought (CoT):透過中間步驟實作推理能力,具有多種子技術,如自我一致性、主動提示和多模態 CoT。
  • Tree-of-Thoughts (ToT):適用於探索或戰略前瞻任務,允許模型探索多種思維鏈作為解決問題的中間步驟。

ReAct 框架例項

讓我們考慮一個使用 ReAct 框架的智慧代理範例。當使用者傳送查詢給代理時,代理開始 ReAct 序列,生成下一步的 ReAct 步驟及其對應的輸出,包括問題、思考、行動、行動輸入和觀察。這個過程可能重複多次,直到代理提供最終答案給使用者。

此圖示說明瞭 ReAct 框架的流程,包括使用者查詢、代理的思考和行動過程,以及最終答案的生成。

工具:連線內外世界的橋樑

雖然語言模型擅長處理資訊,但它們缺乏直接感知和影響真實世界的能力。因此,我們需要工具來提供與外部系統或資料的互動能力。工具可以使代理執行更廣泛的任務,並提高準確性和可靠性。

工具型別

目前有多種工具型別可供選擇,包括:

  • Extensions:橋接代理和 API 之間的差距,使代理能夠無縫地執行 API。
  • Functions:提供特定的功能,使代理能夠執行特定的任務。
  • Data Stores:提供資料儲存和檢索能力,使代理能夠存取和管理資料。

Extensions 的應用

Extensions 可以使代理更容易地與外部 API 互動,無需實作自定義程式碼。透過提供範例和引數,Extensions 可以教導代理如何使用 API 端點。

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title 智慧代理認知架構與工具整合

package "認知架構核心" {
    component [模型 LM] as model
    component [工具 Tools] as tools
    component [協調層] as orchestration
}

package "提示工程框架" {
    component [ReAct] as react
    component [Chain-of-Thought] as cot
    component [Tree-of-Thoughts] as tot
}

package "工具類型" {
    component [Extensions擴展] as extensions
    component [Functions函式] as functions
    component [API整合] as api
}

package "代理運作迴圈" {
    component [觀察環境] as observe
    component [內部推理] as reason
    component [採取行動] as action
    component [達成目標] as goal
}

model --> orchestration : 決策
tools --> orchestration : 能力
orchestration --> observe : 驅動

react --> model : 增強
cot --> model : 增強
tot --> model : 增強

extensions --> api : 連接
functions --> api : 調用

observe --> reason : 輸入
reason --> action : 輸出
action --> goal : 迭代

note right of model : 集中決策者
note right of tools : 外部互動能力
note right of orchestration : 維護記憶/狀態
cv --> eval : 訓練模型
eval --> deploy : 驗證模型
deploy --> monitor : 生產模型

note right of feature
  特徵工程包含:
  - 特徵選擇
  - 特徵轉換
  - 降維處理
end note

note right of eval
  評估指標:
  - 準確率/召回率
  - F1 Score
  - AUC-ROC
end note

@enduml

此圖示說明瞭 Extensions 如何連線代理和外部 API,使代理能夠執行 API 呼叫。

內容解密:

此段落主要闡述了智慧代理如何利用認知架構來達成目標,並介紹了協調層的概念。協調層是智慧代理的核心,負責維護記憶、狀態、推理和規劃。同時,也提到了多種提示工程框架,如 ReAct、CoT 和 ToT,這些框架能夠增強語言模型的推理能力。接著,以 ReAct 框架為例,詳細說明瞭智慧代理如何根據使用者查詢進行推理和採取行動。最後,討論了工具在智慧代理中的重要性,以及如何利用工具來提供與外部系統或資料的互動能力。

程式碼範例與解析

以下是一個簡單的 Python 程式碼範例,展示瞭如何使用 ReAct 框架進行推理和採取行動:

class ReActAgent:
    def __init__(self):
        self.tools = {
            'Flights': self.search_flights,
            'Search': self.search_info,
            'Code': self.execute_code,
            'None': self.no_action
        }

    def react(self, query):
        thought = self.think(query)
        action = self.decide_action(thought)
        action_input = self.get_action_input(action, query)
        observation = self.execute_action(action, action_input)
        return self.final_answer(observation)

    def think(self, query):
        # 根據查詢進行思考
        return "思考結果"

    def decide_action(self, thought):
        # 根據思考結果決定行動
        return "Flights"

    def get_action_input(self, action, query):
        # 取得行動輸入
        return "行動輸入"

    def execute_action(self, action, action_input):
        # 執行行動
        return self.tools[action](action_input)

    def search_flights(self, input_data):
        # 搜尋航班資訊
        return "航班資訊"

    def search_info(self, input_data):
        # 搜尋其他資訊
        return "其他資訊"

    def execute_code(self, input_data):
        # 執行程式碼
        return "程式碼執行結果"

    def no_action(self, input_data):
        # 無行動
        return "無行動"

    def final_answer(self, observation):
        # 提供最終答案
        return "最終答案"

# 使用範例
agent = ReActAgent()
query = "我想預訂從奧斯汀到蘇黎世的航班。"
print(agent.react(query))

內容解密:

此程式碼範例展示了一個簡單的 ReActAgent 類別,該類別使用 ReAct 框架進行推理和採取行動。首先,__init__ 方法初始化了一個包含多種工具的字典。react 方法是主要的推理和行動流程,包括思考、決定行動、取得行動輸入、執行行動和提供最終答案。每個步驟都有對應的方法來實作具體的功能,例如 thinkdecide_actionget_action_inputexecute_actionfinal_answer。這些方法共同工作,完成整個 ReAct 流程。

圖表說明

前文中的 Plantuml 圖表清晰地展示了 ReAct 框架的流程以及 Extensions 如何連線代理和外部 API。這些視覺化表示有助於讀者更好地理解智慧代理的工作原理和工具整合的重要性。

代理(Agents)與擴充套件(Extensions)及函式(Functions)的應用

在軟體開發領域中,開發者會根據使用者的需求選擇適當的API端點來解決問題。舉例來說,若使用者想預訂航班,開發者可能會使用Google Flights API;若使用者想查詢最近的咖啡店位置,開發者可能會使用Google Maps API。同樣地,在代理/模型堆積疊中,會使用一系列已知的擴充套件(Extensions)來決定哪一個擴充套件最適合使用者的查詢。

擴充套件(Extensions)的運作方式

擴充套件允許代理與外部世界進行互動,並且可以根據使用者的查詢選擇最合適的擴充套件。例如,可以在Gemini應用程式中啟用Google Flights擴充套件,然後詢問Gemini「顯示下週五從奧斯汀到蘇黎世的航班。」

範例擴充套件:程式碼直譯器(Code Interpreter)

Google提供了一些開箱即用的擴充套件,可以輕鬆匯入專案並使用,幾乎無需組態。例如,程式碼直譯器擴充套件允許從自然語言描述中生成和執行Python程式碼。

import vertexai
import pprint

PROJECT_ID = "YOUR_PROJECT_ID"
REGION = "us-central1"

vertexai.init(project=PROJECT_ID, location=REGION)

from vertexai.preview.extensions import Extension

extension_code_interpreter = Extension.from_hub("code_interpreter")

CODE_QUERY = """寫一個Python方法以O(n)時間複雜度反轉二元樹。"""

response = extension_code_interpreter.execute(
    operation_id="generate_and_execute",
    operation_params={"query": CODE_QUERY}
)

print("生成的程式碼:")
pprint.pprint(response['generated_code'])

內容解密:

  1. vertexai.init:初始化Vertex AI,指定專案ID和地區。
  2. Extension.from_hub("code_interpreter"):從Vertex AI的擴充套件中心載入程式碼直譯器擴充套件。
  3. extension_code_interpreter.execute:執行程式碼直譯器擴充套件,傳入操作ID和引數。
  4. CODE_QUERY:自然語言描述的問題,要求生成一個反轉二元樹的Python方法。
  5. response['generated_code']:輸出的生成程式碼。

生成的程式碼如下:

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def invert_binary_tree(root):
    """
    反轉二元樹。
    
    Args:
    root: 二元樹的根節點。
    
    Returns:
    反轉後的二元樹的根節點。
    """
    if not root:
        return None
    # 遞迴交換左右子節點
    root.left, root.right = invert_binary_tree(root.right), invert_binary_tree(root.left)
    return root

# 範例用法:
# 建構一個範例二元樹
root = TreeNode(4)
root.left = TreeNode(2)
root.right = TreeNode(7)
root.left.left = TreeNode(1)
root.left.right = TreeNode(3)
root.right.left = TreeNode(6)
root.right.right = TreeNode(9)

# 反轉二元樹
inverted_root = invert_binary_tree(root)

內容解密:

  1. TreeNode類別:定義二元樹節點的結構,包含值、左子節點和右子節點。
  2. invert_binary_tree函式:遞迴地反轉二元樹,透過交換每個節點的左右子節點來實作。
  3. root.left, root.right = invert_binary_tree(root.right), invert_binary_tree(root.left):關鍵的遞迴交換步驟。
  4. 範例用法:展示如何構建一個二元樹並呼叫invert_binary_tree函式進行反轉。

函式(Functions)與擴充套件(Extensions)的比較

在軟體工程領域,函式是定義良好的、可重用的程式碼模組,用於完成特定的任務。代理中的函式與此類別似,但由模型決定何時呼叫哪個函式以及需要哪些引數。函式與擴充套件的主要區別在於:

  1. 模型輸出函式及其引數,但不進行實時的API呼叫。
  2. 函式在客戶端執行,而擴充套件在代理端執行。

使用函式的場景

函式呼叫允許開發者在客戶端應用程式中執行複雜的邏輯,而不必讓語言模型直接管理API執行。例如,在一個旅遊服務代理中,使用者可能會詢問:「我想和家人一起去滑雪,但不知道該去哪裡。」模型可以輸出一個城市列表,但格式可能不利於後續系統解析。透過函式呼叫,可以讓模型輸出結構化的JSON格式,方便後續處理。

{
  "cities": [
    {"name": "Crested Butte", "state": "Colorado", "country": "USA"},
    {"name": "Whistler", "state": "BC", "country": "Canada"},
    {"name": "Zermatt", "country": "Switzerland"}
  ]
}

內容解密:

  1. cities陣列:包含多個城市物件,每個物件代表一個推薦的滑雪地點。
  2. namestatecountry屬性:提供每個城市的詳細資訊,便於後續系統處理。