iT邦幫忙

2024 iThome 鐵人賽

DAY 17
0
生成式 AI

2024 年用 LangGraph 從零開始實現 Agentic AI System系列 第 17

【Day 17】- 多代理系統設計: 監督者模式的應用與實踐

  • 分享至 

  • xImage
  •  

摘要
這篇文章探討了多代理系統設計中監督者模式的應用和實踐。文章首先回顧了多代理系統的基本概念和協作模式,接著介紹了監督者模式的特性,並以台灣棒球和啦啦隊新聞處理系統為例,展示了如何使用 LangGraph 框架實現監督者模式。這個系統包含多個 AI 代理,例如啦啦隊新聞評估器、文章發布性評估器、翻譯器和擴展器,由一個中央控制單元——監督者代理協調和管理。文章最後總結了這個系統的優點和未來改進的方向,並強調了多代理系統在 AI 應用中的重要性。

引言

在我們的上一篇文章《Agentic Pattern:以多代理協作模式革新 AI 系統》中,我們詳細介紹了多代理系統的基本概念以及協作模式的應用。我們探討了如何通過多個專業化的AI代理協同工作來解決複雜問題,並通過一個翻譯系統的案例展示了協作模式的實際應用。

需要放上首圖

然而,多代理系統的設計並不僅限於協作模式。今天,我們將聚焦於另一種平等重要的多代理設計模式——監督者模式。這種模式為我們提供了一種不同的視角來組織和管理多個AI代理,特別適合需要中央協調和決策的複雜任務。

1. 多代理系統設計模式回顧

1.1 多代理系統的核心概念

多代理系統是由多個獨立的AI行為者(Agents)組成的網絡。每個代理都是一個獨立的AI實體,擁有自己的「大腦」(語言模型)和「工具箱」(自定義程式碼)。這種系統的關鍵組成要素包括:

  1. 獨立代理:每個Agent可以擁有專屬提示詞、定制語言模型、特定工具集和自定義程式碼。
  2. 連接機制:定義代理間如何協作和通訊,通常使用圖形理論來描述,其中Agent為節點,連接表示為邊。

1.2 協作模式的特點

協作模式採用「分而治之」的策略,具有以下特點:

  1. 分散式結構:每個代理都是獨立的專家,負責特定的任務領域。
  2. 平等協作:代理之間以平等的身份進行交互和信息交換。
  3. 專業化提示:每個代理可以有獨立的提示詞和微調語言模型。

協作模式特別適合那些可以明確分解為多個相對獨立子任務的問題。正如Wu等學者在《AutoGen: Enabling Next-Gen LLM Applications via Multi-Agent Conversation》中所述,這種模式能夠有效處理跨領域的複雜任務。

1.3 引入監督者模式

而監督者模式則提供了一種不同的組織結構,引入了一個中央控制單元——監督者代理(Supervisor Agent)。這種模式的特點包括:

  1. 中央控制:監督者代理負責整體任務的協調和管理。
  2. 層級結構:監督者代理位於決策層級的頂端,指導其他專業代理的工作。
  3. 動態任務分配:監督者可以根據整體情況做出更優的資源分配和任務安排。

2. 監督者模式 - 台灣棒球與啦啦隊新聞處理系統

2.1 專案概述

本專案旨在開發一個自動化的新聞處理系統,專門針對台灣職業棒球聯盟(CPBL)相關新聞,特別關注球員轉會和啦啦隊成員異動。這個系統利用最新的自然語言處理技術,實現了一個複雜而高效的工作流程。

圖片:系統工作流程概覽

整個工作流程包括以下幾個主要步驟:

  1. 評估文章相關性:
  2. 檢查文章發布標準:
  3. 必要時進行翻譯:
  4. 必要時擴展文章內容:
  5. 再次評估和最終發布決定:

2.2 系統核心組件

2.2.1 啦啦隊新聞評估器

這個組件負責識別與台灣職棒啦啦隊相關的新聞:
用於

  • 協助球迷追蹤他們喜愛的啦啦隊成員的動向。
  • 幫助媒體快速篩選與分類啦啦隊相關的新聞。
  • 為球隊管理層提供關於競爭對手啦啦隊變動的信息。
  • 追蹤啦啦隊在台灣棒球文化中的影響和發展趨勢。
class CheerleaderNewsGrader(BaseModel):
    """評估新聞是否與台灣職業棒球啦啦隊相關的二元評分。"""

    binary_score: str = Field(
        description="文章是否與台灣職業棒球啦啦隊有關,回答 'yes' 或 'no'"
    )

# LLM 設置和評估邏輯
llm = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0)
structured_llm_grader = llm.with_structured_output(CheerleaderNewsGrader)

system = """您是一位評估員,負責判斷新聞文章是否與台灣職業棒球啦啦隊有關。
    請檢查文章是否明確提到:
    1. CPBL(中華職棒)球隊之間的啦啦隊成員轉隊
    2. 啦啦隊新成員招募或退役
    3. 啦啦隊特別表演或活動
    4. 涉及啦啦隊的爭議或重大事件
    5. 啦啦隊領導層或管理變動
    請提供二元評分:'yes' 表示新聞與台灣職業棒球啦啦隊有關,'no' 表示無關。"""

grade_prompt = ChatPromptTemplate.from_messages(
    [("system", system), ("human", "新聞文章:\n\n {article}")]
)
evaluator = grade_prompt | structured_llm_grader

# 測試評估器
result = evaluator.invoke(
    {"震撼彈!知名啦啦隊女神小雨宣布退出Lamigo桃猿,轉戰統一獅啦啦隊"}
)

print(result)

這個評估器能夠快速識別與啦啦隊相關的新聞,為後續處理奠定基礎。

2.2.2 文章發布性評估器

此組件評估新聞文章是否符合發布標準:

包含以下標準

  • 文章是否達到發布標準(包括語法、完整性和適當性)
  • 是否達到 300 字元的最低字數要求
  • 是否使用了誇張的聳動寫作風格
  • 是否使用繁體中文撰寫
class TaiwanArticlePostabilityGrader(BaseModel):
    """評估台灣新聞文章發布性的多維度評分。"""

    can_be_posted: str = Field(
        description="文章是否準備好發布,'yes' 或 'no'"
    )
    meets_word_count: str = Field(
        description="文章是否達到至少 300 字,'yes' 或 'no'"
    )
    is_sensationalistic: str = Field(
        description="文章是否使用聳動的寫作風格,'yes' 或 'no'"
    )
    is_language_traditional_chinese: str = Field(
        description="文章是否使用繁體中文,'yes' 或 'no'"
    )

# LLM 設置和評估邏輯
llm_postability = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0)
structured_llm_postability_grader = llm_postability.with_structured_output(
    TaiwanArticlePostabilityGrader
)

postability_system = """您是一位評估員,負責判斷台灣新聞文章是否準備好發布,是否達到至少 300 字的要求,是否使用聳動的寫作風格,以及是否使用繁體中文。
    請評估文章的語法錯誤、完整性、適合發布的程度,以及是否過度誇張。
    同時確認使用的語言是否為繁體中文,並檢查字數是否符合要求。
    請提供四個二元評分:文章是否可以發布('yes' 或 'no')、字數是否足夠('yes' 或 'no')、是否使用聳動寫作風格('yes' 或 'no'),以及是否使用繁體中文('yes' 或 'no')。
    請特別注意台灣特有的用語、慣用語和寫作風格。"""

postability_grade_prompt = ChatPromptTemplate.from_messages(
    [("system", postability_system), ("human", "新聞文章:\n\n {article}")]
)

news_chef = postability_grade_prompt | structured_llm_postability_grader

# 測試評估器
result = news_chef.invoke(
    {
        "article": "震撼彈!知名啦啦隊女神小雨宣布退出Lamigo桃猿,轉戰統一獅啦啦隊。消息一出,引起球迷熱烈討論。有內部消息指出,小雨此舉可能與新東家開出的天價薪酬有關。究竟是否屬實?本報將持續追蹤報導。敬請球迷朋友們拭目以待,這個夏天的職棒轉會市場肯定會掀起更多驚人巨浪!"
    }
)
print(result)

這個評估器確保文章符合發布標準,包括字數、語言和寫作風格等方面。

2.2.3 文章翻譯器

為了處理可能的英文新聞,我們實現了一個翻譯器:

此翻譯器可用於:

  • 國際新聞社通報台灣事件。
  • 台灣的英文新聞媒體。
  • 需要了解台灣新聞但繁體中文不流利的研究人員或分析師。
  • 對台灣職棒新聞有興趣的運動組織或球迷。
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate

llm_translation = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0)

translation_system = """您是一位將台灣新聞文章翻譯成英文的翻譯員。
請準確翻譯文本,同時保持原文的語氣和風格。
請特別注意台灣文化參考、慣用語和上下文。
確保正確轉寫或翻譯運動隊名、選手姓名和其他專有名詞。
翻譯引用語時,請保持說話者的語氣和意圖。"""

translation_prompt = ChatPromptTemplate.from_messages(
    [("system", translation_system), ("human", "需要翻譯的文章:\n\n {article}")]
)

translator = translation_prompt | llm_translation

# 測試翻譯器
result = translator.invoke(
    {
        "article": "震撼彈!知名啦啦隊女神小雨宣布退出Lamigo桃猿,轉戰統一獅啦啦隊。消息一出,引起球迷熱烈討論。有內部消息指出,小雨此舉可能與新東家開出的天價薪酬有關。究竟是否屬實?本報將持續追蹤報導。敬請球迷朋友們拭目以待,這個夏天的職棒轉會市場肯定會掀起更多驚人巨浪!"
    }
)

print(result)

這個翻譯器能夠處理英文新聞,確保系統可以處理多語言的輸入。

2.2.4 文章擴展器

當文章不夠長或需要更多細節時,這個組件可以擴展文章內容:

該組件可以用於:

  • 快速生成更詳細的新聞稿。
  • 將簡短的新聞線索擴展成完整的報導。
  • 為編輯提供更多素材,以便他們進一步編輯和完善。
  • 在保持原始新聞核心的同時,提供更多上下文和背景信息。
llm_expansion = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0.5)

expansion_system = """您是一位專業的台灣新聞記者,負責將簡短新聞擴展至至少 300 字。擴展時請注意:

1. 保持原文的主題和語氣,同時增加相關背景資訊和細節。
2. 使用台灣讀者熟悉的表達方式和用語。
3. 適當加入一些專家或相關人士的假想評論,以增加新聞深度。
4. 考慮新聞事件可能對台灣社會或特定群體的影響。
5. 在適當處加入台灣特有的文化元素或本地化例子。
6. 確保擴展後的文章保持客觀性和新聞專業性。
7. 使用繁體中文撰寫。"""

expansion_prompt = ChatPromptTemplate.from_messages(
    [("system", expansion_system), ("human", "原始新聞內容:\n\n {article}")]
)

expander = expansion_prompt | llm_expansion

# 測試擴展器
article_content = "知名啦啦隊女神小雨宣布退出Lamigo桃猿,轉戰統一獅啦啦隊。"
result = expander.invoke({"article": article_content})

print(result)

這個擴展器能夠豐富文章內容,使其更加全面和吸引人。

2.3 使用LangGraph框架實現工作流程

LangGraph框架提供了一個強大的工具,用於實現監督者模式in多代理系統中。
以下是使用LangGraph實現監督者模式的關鍵步驟:

2.3.1 狀態定義

我們使用 TypedDict 來定義系統狀態:

from typing import TypedDict

class AgentState(TypedDict):
    article_state: str

這個簡單的狀態定義允許我們在整個工作流程中追踪文章的狀態。

2.3.2 節點函數定義

接下來,我們定義了各個處理節點的函數:

def get_transfer_news_grade(state: AgentState) -> AgentState:
    print(f"get_transfer_news_grade: Current state: {state}")
    print("Evaluator: Reading article but doing nothing to change it...")
    return state

def evaluate_article(state: AgentState) -> AgentState:
    print(f"evaluate_article: Current state: {state}")
    print("News : Reading article but doing nothing to change it...")
    return state

def translate_article(state: AgentState) -> AgentState:
    print(f"translate_article: Current state: {state}")
    article = state["article_state"]
    result = translator.invoke({"article": article})
    state["article_state"] = result.content
    return state

def expand_article(state: AgentState) -> AgentState:
    print(f"expand_article: Current state: {state}")
    article = state["article_state"]
    result = expander.invoke({"article": article})
    state["article_state"] = result.content
    return state

def publisher(state: AgentState) -> AgentState:
    print(f"publisher: Current state: {state}")
    print("FINAL_STATE in publisher:", state)
    return state

這些函數定義了工作流程中的各個處理步驟,包括評估、翻譯、擴展和發布。

2.3.3 路由函數定義

路由函數決定了文章在工作流程中的下一步去向:

from typing import TypedDict, Literal

def evaluator_router(state: AgentState) -> Literal["news_chef", "not_relevant"]:
    article = state["article_state"]
    evaluator = grade_prompt | structured_llm_grader
    result = evaluator.invoke({"article": article})
    print(f"evaluator_router: Current state: {state}")
    print("Evaluator result: ", result)
    if result.binary_score == "yes":
        return "news_chef"
    else:
        return "not_relevant"

def news_chef_router(
    state: AgentState,
) -> Literal["translator", "publisher", "expander"]:
    article = state["article_state"]
    result = news_chef.invoke({"article": article})
    print(f"news_chef_router: Current state: {state}")
    print("News chef result: ", result)
    if result.can_be_posted == "yes":
        return "publisher"
    elif result.is_language_traditional_chinese == "yes":
        if result.meets_word_count == "no" or result.is_sensationalistic == "no":
            return "expander"
    return "translator"

這些路由函數根據文章的當前狀態和評估結果,決定下一步的處理方向。

2.3.4 工作流程圖構建

最後,我們使用 LangGraph 構建完整的工作流程,將所有組件連接成一個完整的工作流程:

from langgraph.graph import StateGraph, END

workflow = StateGraph(AgentState)

# 添加節點
workflow.add_node("evaluator", get_transfer_news_grade)
workflow.add_node("news_chef", evaluate_article)
workflow.add_node("translator", translate_article)
workflow.add_node("expander", expand_article)
workflow.add_node("publisher", publisher)

# 設置入口點
workflow.set_entry_point("evaluator")

# 添加條件邊
workflow.add_conditional_edges(
    "evaluator", evaluator_router, {"news_chef": "news_chef", "not_relevant": END}
)
workflow.add_conditional_edges(
    "news_chef",
    news_chef_router,
    {"translator": "translator", "publisher": "publisher", "expander": "expander"},
)

# 添加一般邊
workflow.add_edge("translator", "news_chef")
workflow.add_edge("expander", "news_chef")
workflow.add_edge("publisher", END)

# 編譯工作流程
app = workflow.compile()

img

這個工作流程圖定義了新聞文章處理的完整路徑,從初始評估到最終發布。

提示:工作流程的可視化有助於理解整個系統的運作方式。可以考慮使用圖表工具來呈現這個流程。

[圖片:工作流程圖示意]

2.3.5系統測試

為了驗證我們的系統,我們設計了三個測試案例,分別針對不同的情景:

案例一:基本啦啦隊新聞處理

test_case_1 = {
    "article_state": "知名啦啦隊女神小雨宣布退出Lamigo桃猿,轉戰統一獅啦啦隊。"
}
result_1 = app.invoke(test_case_1)
print(result_1)

img

這個案例測試系統對於典型啦啦隊新聞的處理能力,包括評估相關性、擴展內容和最終發布決策。

案例二:不相關新聞快速篩選

test_case_2 = {
    "article_state": "台北市今日發布最新空氣品質報告,PM2.5指數持續攀升。"
}
result_2 = app.invoke(test_case_2)
print(result_2)

img
此案例驗證系統能否正確識別和過濾與主題無關的新聞,避免不必要的處理。

案例三:英文新聞翻譯與處理

test_case_3 = {
    "article_state": "CPBL star outfielder Wang Po-Jung considering a return to NPB after successful stint with Lamigo Monkeys."
}
result_3 = app.invoke(test_case_3)
print(result_3)

img
這個案例測試系統處理英文新聞的能力,包括翻譯、評估和可能的內容擴展。

3. 總結與展望

通過這個項目,我們成功構建了一個自動化的新聞處理系統,專門針對台灣職業棒球和啦啦隊相關新聞。該系統具備以下特點:

  1. 智能評估:能夠準確識別相關新聞。
  2. 多語言支持:可處理中英文新聞。
  3. 內容優化:根據需要擴展或調整文章內容。
  4. 靈活工作流:基於 LangGraph 的可配置工作流程。

未來的改進方向可以包括:

  • 擴大支持的新聞類型
  • 整合更多的數據源
  • 提高處理速度和效率
  • 增加更複雜的決策邏輯

最佳實踐:在實際部署時,建議進行更全面的測試,並考慮增加錯誤處理和日誌記錄機制,以確保系統的穩定性和可維護性。

這個項目不僅展示了自然語言處理在新聞行業的應用潛力,也為如何構建複雜的 AI 工作流程提供了一個實用的範例。通過不斷迭代和改進,這樣的系統有望在未來的新聞處理和內容生產中發揮越來越重要的作用。

4. 結語

多代理系統代表了 AI 應用的新前沿。通過協作模式和監督者模式,我們可以構建更智能、更靈活的 AI 系統,以應對日益複雜的現實世界挑戰。LangGraph 框架為實現這些先進概念提供了強大的工具支持,使得複雜的 AI 系統設計變得更加直觀和高效。

即刻前往教學程式碼 Repo,親自動手實作監督者模式吧!別忘了給專案按個星星並持續關注更新,讓我們一起探索AI代理的新境界。

X. 參考資料

  1. agent_supervisor

上一篇
【Day 16】- Agentic Pattern:以多代理協作模式革新 AI 系統
下一篇
【Day 18】- LangGraph 與 LangFuse:打造 Agent 觀測系統全方位指南
系列文
2024 年用 LangGraph 從零開始實現 Agentic AI System31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言