# 建立可信賴的 AI 代理

## 介紹

本課程將涵蓋以下內容：

- 如何構建和部署安全且有效的 AI 代理
- 開發 AI 代理時的重要安全考量
- 在開發 AI 代理時如何維護數據和用戶隱私

## 學習目標

完成本課程後，您將能夠：

- 識別並減輕在創建 AI 代理時可能面臨的風險。
- 實施安全措施，確保數據和訪問權限得到妥善管理。
- 創建能維護數據隱私並提供高品質用戶體驗的 AI 代理。

## 安全性

首先，我們來看看如何構建安全的代理應用程序。安全性意味著 AI 代理能按照設計執行其功能。作為代理應用程序的開發者，我們有一些方法和工具可以最大限度地提高安全性：

### 構建 Meta Prompt 系統

如果您曾使用大型語言模型（LLMs）開發過 AI 應用程序，您會知道設計一個穩健的系統提示或系統訊息的重要性。這些提示負責設定元規則、指令和指南，確保 LLM 能夠正確地與用戶和數據互動。

對於 AI 代理來說，系統提示更為重要，因為 AI 代理需要高度具體的指令來完成我們設計的任務。

為了創建可擴展的系統提示，我們可以使用 Meta Prompt 系統來構建應用中的一個或多個代理：

![構建 Meta Prompt 系統](../../../translated_images/building-a-metaprompting-system.aa7d6de2100b0ef48c3e1926dab6903026b22fc9d27fc4327162fbbb9caf960f.tw.png)

#### 步驟 1：創建 Meta 或模板提示

Meta Prompt 將由 LLM 用來生成我們所創建代理的系統提示。我們將其設計為模板，以便在需要時能高效地創建多個代理。

以下是一個我們提供給 LLM 的 Meta Prompt 範例：

```plaintext
You are an expert at creating AI agent assitants.
You will be provided a company name, role, responsibilites and other
information that you will use to provide a system prompt for.
To create the system prompt, be descriptive as possible and provide a structure that a system using an LLM can better understand the role and responsibilites of the AI assistant.
```

#### 步驟 2：創建基礎提示

下一步是創建一個基礎提示來描述 AI 代理。您應包括代理的角色、代理將完成的任務以及代理的其他職責。

以下是一個範例：

```plaintext
You are a travel agent for Contoso Travel with that is great at booking flights for customers. To help customers you can perform the following tasks: lookup available flights, book flights, ask for preferences in seating and times for flights, cancel any previously booked flights and alert customers on any delays or cancellations of flights.
```

#### 步驟 3：將基礎提示提供給 LLM

現在，我們可以通過將 Meta Prompt 作為系統提示並添加我們的基礎提示來優化這個提示。

這將生成一個更適合指導我們 AI 代理的提示：

```markdown
**Company Name:** Contoso Travel
**Role:** Travel Agent Assistant

**Objective:**
You are an AI-powered travel agent assistant for Contoso Travel, specializing in booking flights and providing exceptional customer service. Your main goal is to assist customers in finding, booking, and managing their flights, all while ensuring that their preferences and needs are met efficiently.

**Key Responsibilities:**

1. **Flight Lookup:**

    - Assist customers in searching for available flights based on their specified destination, dates, and any other relevant preferences.
    - Provide a list of options, including flight times, airlines, layovers, and pricing.
2. **Flight Booking:**

    - Facilitate the booking of flights for customers, ensuring that all details are correctly entered into the system.
    - Confirm bookings and provide customers with their itinerary, including confirmation numbers and any other pertinent information.
3. **Customer Preference Inquiry:**

    - Actively ask customers for their preferences regarding seating (e.g., aisle, window, extra legroom) and preferred times for flights (e.g., morning, afternoon, evening).
    - Record these preferences for future reference and tailor suggestions accordingly.
4. **Flight Cancellation:**

    - Assist customers in canceling previously booked flights if needed, following company policies and procedures.
    - Notify customers of any necessary refunds or additional steps that may be required for cancellations.
5. **Flight Monitoring:**

    - Monitor the status of booked flights and alert customers in real-time about any delays, cancellations, or changes to their flight schedule.
    - Provide updates through preferred communication channels (e.g., email, SMS) as needed.

**Tone and Style:**

- Maintain a friendly, professional, and approachable demeanor in all interactions with customers.
- Ensure that all communication is clear, informative, and tailored to the customer's specific needs and inquiries.

**User Interaction Instructions:**

- Respond to customer queries promptly and accurately.
- Use a conversational style while ensuring professionalism.
- Prioritize customer satisfaction by being attentive, empathetic, and proactive in all assistance provided.

**Additional Notes:**

- Stay updated on any changes to airline policies, travel restrictions, and other relevant information that could impact flight bookings and customer experience.
- Use clear and concise language to explain options and processes, avoiding jargon where possible for better customer understanding.

This AI assistant is designed to streamline the flight booking process for customers of Contoso Travel, ensuring that all their travel needs are met efficiently and effectively.

```

#### 步驟 4：迭代與改進

Meta Prompt 系統的價值在於能夠更輕鬆地擴展多個代理的提示創建過程，並隨著時間的推移改進您的提示。很少有提示能在第一次就完全滿足您的使用需求。通過對基礎提示進行小幅調整並通過系統運行，您可以比較和評估結果以進行改進。

## 理解威脅

為了構建可信賴的 AI 代理，理解並減輕 AI 代理可能面臨的風險和威脅是非常重要的。接下來，我們將探討部分 AI 代理可能遭遇的威脅以及如何更好地規劃和應對。

![理解威脅](../../../translated_images/understanding-threats.f8fbe6fe11e025b3085fc91e82d975937ad1d672260a2aeed40458aa41798d0e.tw.png)

### 任務與指令

**描述：** 攻擊者試圖通過提示或操縱輸入來更改 AI 代理的指令或目標。

**緩解措施：** 執行驗證檢查和輸入過濾，以檢測在被 AI 代理處理之前可能存在的危險提示。由於這類攻擊通常需要與代理頻繁交互，限制對話輪次也是防止此類攻擊的另一種方法。

### 訪問關鍵系統

**描述：** 如果 AI 代理可以訪問存儲敏感數據的系統和服務，攻擊者可能會破壞代理與這些服務之間的通信。這些可能是直接攻擊或通過代理間接獲取這些系統信息的嘗試。

**緩解措施：** AI 代理應僅在必要時訪問系統，以防止此類攻擊。代理與系統之間的通信也應保持安全。實施身份驗證和訪問控制是保護此類信息的另一種方法。

### 資源與服務超載

**描述：** AI 代理可以訪問不同的工具和服務來完成任務。攻擊者可能利用這一點通過 AI 代理向這些服務發送大量請求，導致系統故障或高額成本。

**緩解措施：** 實施策略限制 AI 代理向服務發送請求的數量。限制對話輪次和 AI 代理的請求數量也是防止此類攻擊的另一種方法。

### 知識庫污染

**描述：** 這類攻擊不直接針對 AI 代理，而是針對代理將使用的知識庫和其他服務。這可能涉及破壞代理用於完成任務的數據或信息，導致用戶收到偏頗或非預期的回應。

**緩解措施：** 定期驗證 AI 代理在工作流中使用的數據。確保這些數據的訪問權限是安全的，並且只有可信任的人員才能更改，以避免此類攻擊。

### 錯誤連鎖效應

**描述：** AI 代理會訪問各種工具和服務來完成任務。由攻擊者引發的錯誤可能導致代理連接的其他系統失效，使得攻擊範圍擴大且更難排查。

**緩解措施：** 避免此類情況的一種方法是讓 AI 代理在受限環境中運行，例如在 Docker 容器中執行任務，以防止直接系統攻擊。為某些系統出現錯誤時創建備援機制和重試邏輯，也是防止更大範圍系統故障的另一種方法。

## 人類介入

另一種構建可信賴 AI 代理系統的有效方式是引入人類介入（Human-in-the-loop）。這種方式創建了一個流程，允許用戶在代理運行期間提供反饋。用戶本質上充當多代理系統中的一個代理，通過批准或終止正在運行的流程來參與。

![人類介入](../../../translated_images/human-in-the-loop.e9edbe8f6d42041b4213421410823250aa750fe8bdba5601d69ed46f3ff6489d.tw.png)

以下是一段使用 AutoGen 的代碼範例，展示如何實現這一概念：

```python

# Create the agents.
model_client = OpenAIChatCompletionClient(model="gpt-4o-mini")
assistant = AssistantAgent("assistant", model_client=model_client)
user_proxy = UserProxyAgent("user_proxy", input_func=input)  # Use input() to get user input from console.

# Create the termination condition which will end the conversation when the user says "APPROVE".
termination = TextMentionTermination("APPROVE")

# Create the team.
team = RoundRobinGroupChat([assistant, user_proxy], termination_condition=termination)

# Run the conversation and stream to the console.
stream = team.run_stream(task="Write a 4-line poem about the ocean.")
# Use asyncio.run(...) when running in a script.
await Console(stream)

```

**免責聲明**：
本文檔是使用機器翻譯人工智慧服務進行翻譯的。儘管我們努力確保準確性，但請注意，自動翻譯可能包含錯誤或不準確之處。應以原始語言的文件為權威來源。對於關鍵資訊，建議尋求專業人工翻譯。我們對因使用此翻譯而產生的任何誤解或誤讀不承擔責任。


# 規劃設計

## 簡介

本課程將涵蓋以下內容：

* 定義明確的整體目標，並將複雜任務分解為可管理的小任務。
* 利用結構化輸出來實現更可靠且可機器讀取的回應。
* 採用事件驅動的方法來處理動態任務及應對意外輸入。

## 學習目標

完成本課程後，你將能夠：

* 確認並設定 AI 代理的整體目標，確保它明確知道需要完成的工作。
* 將複雜任務分解為可管理的子任務，並將它們組織成邏輯順序。
* 為代理配備適當的工具（例如搜尋工具或數據分析工具），決定何時及如何使用這些工具，並處理可能出現的意外情況。
* 評估子任務的結果、衡量性能，並通過反覆迭代改進最終輸出。

## 定義整體目標並分解任務

![定義目標與任務](../../../translated_images/defining-goals-tasks.dcc1181bbdb194704ae0fb3363371562949e8b03fd2fadc256218aaadf84a9f4.tw.png)

大多數現實世界的任務都過於複雜，無法一步完成。AI 代理需要一個簡潔的目標來指導其規劃和行動。例如，考慮以下目標：

    "生成一個三天的旅行行程。"

雖然這個目標表述簡單，但仍需進一步細化。目標越清晰，代理（以及任何人類協作者）就越能專注於實現正確的結果，例如創建一個包含航班選項、酒店推薦和活動建議的完整行程。

### 任務分解

大型或複雜的任務在被分解為更小的、目標導向的子任務後會更易管理。
以旅行行程為例，你可以將目標分解為：

* 航班預訂
* 酒店預訂
* 租車
* 個性化定制

每個子任務可以由專門的代理或流程處理。一個代理可能專注於搜尋最佳航班優惠，另一個代理則專注於酒店預訂，依此類推。一個協調或“下游”代理可以將這些結果整合成一個連貫的行程提供給最終用戶。

這種模組化方法還允許逐步改進。例如，你可以增加專門的代理來提供餐飲推薦或當地活動建議，並隨著時間推進不斷完善行程。

### 結構化輸出

大型語言模型（LLMs）可以生成結構化輸出（例如 JSON），這更方便下游代理或服務進行解析和處理。這在多代理上下文中特別有用，因為我們可以在規劃輸出完成後執行這些任務。請參考這篇 [blogpost](https://microsoft.github.io/autogen/stable/user-guide/core-user-guide/cookbook/structured-output-agent.html) 以快速了解。

以下是一段示範簡單規劃代理如何將目標分解為子任務並生成結構化計劃的 Python 程式碼片段：

### 使用多代理協作的規劃代理

在此範例中，一個語義路由代理接收到用戶請求（例如，“我需要一個旅行的酒店計劃。”）。

規劃器接下來會執行以下步驟：

* 接收酒店計劃：規劃器接收用戶的訊息，並根據系統提示（包括可用代理的詳細資訊）生成結構化的旅行計劃。
* 列出代理及其工具：代理註冊表保存了代理的清單（例如航班、酒店、租車和活動代理）以及它們提供的功能或工具。
* 將計劃路由至相應的代理：根據子任務數量，規劃器會將訊息直接發送給專門代理（適用於單一任務情境）或通過群組聊天管理器協調多代理合作。
* 總結結果：最後，規劃器為清晰起見總結生成的計劃。

以下是說明這些步驟的 Python 程式碼範例：

```python

from pydantic import BaseModel

from enum import Enum
from typing import List, Optional, Union

class AgentEnum(str, Enum):
    FlightBooking = "flight_booking"
    HotelBooking = "hotel_booking"
    CarRental = "car_rental"
    ActivitiesBooking = "activities_booking"
    DestinationInfo = "destination_info"
    DefaultAgent = "default_agent"
    GroupChatManager = "group_chat_manager"

# Travel SubTask Model

class TravelSubTask(BaseModel):
    task_details: str
    assigned_agent: AgentEnum # we want to assign the task to the agent

class TravelPlan(BaseModel):
    main_task: str
    subtasks: List[TravelSubTask]
    is_greeting: bool
import json
import os
from typing import Optional

from autogen_core.models import UserMessage, SystemMessage, AssistantMessage
from autogen_ext.models.openai import AzureOpenAIChatCompletionClient

# Create the client with type-checked environment variables

client = AzureOpenAIChatCompletionClient(
    azure_deployment=os.getenv("AZURE_OPENAI_DEPLOYMENT_NAME"),
    model=os.getenv("AZURE_OPENAI_DEPLOYMENT_NAME"),
    api_version=os.getenv("AZURE_OPENAI_API_VERSION"),
    azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
    api_key=os.getenv("AZURE_OPENAI_API_KEY"),
)

from pprint import pprint

# Define the user message

messages = [
    SystemMessage(content="""You are an planner agent.
    Your job is to decide which agents to run based on the user's request.
    Below are the available agents specialised in different tasks:
    - FlightBooking: For booking flights and providing flight information
    - HotelBooking: For booking hotels and providing hotel information
    - CarRental: For booking cars and providing car rental information
    - ActivitiesBooking: For booking activities and providing activity information
    - DestinationInfo: For providing information about destinations
    - DefaultAgent: For handling general requests""", source="system"),
    UserMessage(content="Create a travel plan for a family of 2 kids from Singapore to Melbourne", source="user"),
]

response = await client.create(messages=messages, extra_create_args={"response_format": TravelPlan})

# Ensure the response content is a valid JSON string before loading it

response_content: Optional[str] = response.content if isinstance(response.content, str) else None
if response_content is None:
    raise ValueError("Response content is not a valid JSON string")

# Print the response content after loading it as JSON

pprint(json.loads(response_content))
```

以下是上述程式碼的輸出，你可以使用這個結構化輸出路由到 `assigned_agent`，並向最終用戶總結旅行計劃。

```json
{
    "is_greeting": "False",
    "main_task": "Plan a family trip from Singapore to Melbourne.",
    "subtasks": [
        {
            "assigned_agent": "flight_booking",
            "task_details": "Book round-trip flights from Singapore to Melbourne."
        },
        {
            "assigned_agent": "hotel_booking",
            "task_details": "Find family-friendly hotels in Melbourne."
        },
        {
            "assigned_agent": "car_rental",
            "task_details": "Arrange a car rental suitable for a family of four in Melbourne."
        },
        {
            "assigned_agent": "activities_booking",
            "task_details": "List family-friendly activities in Melbourne."
        },
        {
            "assigned_agent": "destination_info",
            "task_details": "Provide information about Melbourne as a travel destination."
        }
    ]
}
```

包含上述程式碼範例的範例筆記本可在 [這裡](../../../07-planning-design/code_samples/07-autogen.ipynb) 獲取。

### 迭代規劃

某些任務需要反覆調整或重新規劃，其中一個子任務的結果可能會影響下一步。例如，如果代理在預訂航班時發現了意外的數據格式，它可能需要調整策略，然後再進行酒店預訂。

此外，用戶反饋（例如人類決定更喜歡早班航班）也可能觸發部分重新規劃。這種動態、迭代的方法確保最終解決方案能夠符合現實約束和不斷變化的用戶偏好。

例如程式碼：

    ```python
    from autogen_core.models import UserMessage, SystemMessage, AssistantMessage
    #.. same as previous code and pass on the user history, current plan
    messages = [
        SystemMessage(content="""You are a planner agent to optimize the
        Your job is to decide which agents to run based on the user's request.
        Below are the available agents specialised in different tasks:
        - FlightBooking: For booking flights and providing flight information
        - HotelBooking: For booking hotels and providing hotel information
        - CarRental: For booking cars and providing car rental information
        - ActivitiesBooking: For booking activities and providing activity information
        - DestinationInfo: For providing information about destinations
        - DefaultAgent: For handling general requests""", source="system"),
        UserMessage(content="Create a travel plan for a family of 2 kids from Singapore to Melboune", source="user"),
        AssistantMessage(content=f"Previous travel plan - {TravelPlan}", source="assistant")
    ]
    # .. re-plan and send the tasks to respective agents
    ```

如需更全面的規劃，請參考 Magnetic One [Blogpost](https://www.microsoft.com/research/articles/magentic-one-a-generalist-multi-agent-system-for-solving-complex-tasks)，以了解如何解決複雜任務。

## 總結

在本文中，我們探討了一個如何創建規劃器的範例，該規劃器可以動態選擇定義的可用代理。規劃器的輸出分解了任務並分配給代理進行執行。假設代理可以訪問執行任務所需的功能/工具。除了代理之外，你還可以包含其他模式，例如反思、摘要器、輪詢聊天，以進一步自定義。

## 其他資源

* 使用 o1 推理模型在規劃複雜任務中已證明相當先進——TODO: 分享範例？

* Autogen Magentic One - 一個通用型多代理系統，用於解決複雜任務，並在多個具有挑戰性的代理基準測試中取得了令人印象深刻的成果。參考資料：[autogen-magentic-one](https://github.com/microsoft/autogen/tree/main/python/packages/autogen-magentic-one)。在此實現中，協作器創建特定任務的計劃，並將這些任務委派給可用的代理。除了規劃之外，協作器還採用跟蹤機制來監控任務進度並在需要時重新規劃。

**免責聲明**：
本文件是使用機器翻譯AI服務進行翻譯的。儘管我們努力確保準確性，但請注意，自動翻譯可能包含錯誤或不準確之處。應以原文文件作為權威來源。對於關鍵資訊，建議尋求專業人工翻譯。我們對因使用此翻譯而引起的任何誤解或錯誤解釋不承擔責任。

10 Lessons to Get Started Building AI Agents


# 多代理設計模式

當你開始進行涉及多個代理的專案時，就需要考慮多代理設計模式。然而，什麼時候需要切換到多代理模式，以及這樣做的優勢，可能並不馬上明顯。

## 簡介

在本課程中，我們將解答以下問題：

- 多代理模式適用於哪些場景？
- 與單一代理執行多任務相比，使用多代理有哪些優勢？
- 實現多代理設計模式的基礎要素是什麼？
- 如何了解多個代理之間的互動情況？

## 學習目標

完成本課程後，你應該能夠：

- 識別多代理模式適用的場景。
- 理解使用多代理相較於單一代理的優勢。
- 掌握實現多代理設計模式的基礎要素。

### 大局觀

*多代理是一種設計模式，讓多個代理共同合作以達成共同目標*。

這種模式廣泛應用於各種領域，包括機器人技術、自主系統和分散式計算。

## 多代理模式適用的場景

那麼，哪些場景適合使用多代理模式呢？答案是，在許多情況下，採用多代理模式是有益的，尤其是以下幾種情況：

- **大量工作負載**：將龐大的工作負載分解成較小的任務，並分配給不同的代理，可以實現並行處理，加快完成速度。例如，大型數據處理任務就適合這種模式。
- **複雜任務**：與大量工作負載類似，複雜任務也可以被分解成小的子任務，並分配給專注於特定任務的代理。例如，在自動駕駛車輛中，不同的代理可以負責導航、障礙物檢測和與其他車輛的通信。
- **多樣化專業技能**：不同的代理可以擁有不同的專業技能，這使得它們能比單一代理更有效地處理任務的不同方面。例如，在醫療領域，代理可以負責診斷、治療計畫和病人監測。

## 使用多代理相較於單一代理的優勢

單一代理系統在處理簡單任務時可能運作良好，但對於更複雜的任務，使用多代理能提供多項優勢：

- **專業化**：每個代理可以專注於特定任務。如果單一代理缺乏專業化，可能會在面對複雜任務時感到困惑，甚至執行不適合它的任務。
- **可擴展性**：透過增加更多代理來擴展系統，比單一代理承擔過多負載更容易。
- **容錯性**：如果某個代理失效，其他代理仍能繼續運作，確保系統的可靠性。

舉個例子，假設幫用戶預訂旅行。一個單一代理系統需要處理整個預訂流程，包括找航班、訂酒店和租車。這樣的系統可能會變得複雜且難以維護。而多代理系統則可以讓不同的代理專注於找航班、訂酒店和租車，這樣系統更模組化、易於維護且具擴展性。

這可以類比為夫妻檔經營的小型旅行社與連鎖經營的旅行社之間的差異。夫妻檔可能由一個人處理所有旅行預訂細節，而連鎖經營則會讓不同人員專注於不同的預訂任務。

## 實現多代理設計模式的基礎要素

在實現多代理設計模式之前，你需要了解構成這種模式的基礎要素。

以用戶預訂旅行為例，以下是可能的基礎要素：

- **代理通信**：負責找航班、訂酒店和租車的代理需要彼此通信，分享用戶的偏好和限制。例如，找航班的代理需要與訂酒店的代理通信，確保酒店的入住日期與航班日期一致。這意味著你需要決定*哪些代理共享資訊以及如何共享*。
- **協調機制**：代理需要協調行動以滿足用戶的偏好和限制。例如，用戶可能偏好靠近機場的酒店，但租車可能只能在機場取得。這就需要訂酒店的代理與租車的代理協調，以滿足用戶需求。這意味著你需要決定*代理如何協調行動*。
- **代理架構**：代理需要具備內部結構，以便做出決策並從與用戶的互動中學習。例如，找航班的代理需要能決定推薦哪個航班給用戶。這意味著你需要決定*代理如何做決策並從互動中學習*。例如，找航班的代理可以使用機器學習模型，根據用戶過去的偏好來推薦航班。
- **多代理互動的可見性**：需要能夠了解多個代理之間的互動情況。這意味著需要有工具和技術來追蹤代理的活動和互動，可能包括日誌記錄、監控工具、可視化工具以及效能指標。
- **多代理模式**：可以選擇不同的架構模式來實現多代理系統，例如集中式、分散式或混合式架構。需要根據具體需求選擇合適的模式。
- **人機協作**：在多數情況下，人類仍需參與其中，因此需要指導代理何時尋求人類的介入。例如，用戶可能會要求推薦特定的酒店或航班，或在預訂前需要確認。

## 多代理互動的可見性

了解多個代理之間的互動情況至關重要，這對於調試、優化以及確保整體系統的效能都非常必要。為此，需要有工具和技術來追蹤代理的活動和互動。例如：

- **日誌記錄與監控工具**：記錄每個代理的行動。例如，記錄代理採取的行動、行動時間及結果。這些資訊可以用於調試和優化。
- **可視化工具**：使用圖形化方式直觀展示代理之間的互動。例如，可以用一個圖表展示代理之間的資訊流，幫助識別瓶頸或系統中的低效部分。
- **效能指標**：追蹤多代理系統的效能。例如，完成任務所需的時間、每單位時間內完成的任務數量，以及代理推薦的準確性。這些資料有助於找出改進的方向。

## 多代理模式

以下是幾個可用於構建多代理應用的具體模式：

### 群組聊天模式

此模式適用於需要創建多代理群組聊天應用的情況，例如團隊協作、客戶支持和社交網絡。

在這種模式中，每個代理代表群組聊天中的一位用戶，並通過消息協議交換訊息。代理可以向群組發送消息、接收消息並回應其他代理的消息。

該模式可以使用集中式架構（所有消息通過中央伺服器傳遞）或分散式架構（代理之間直接交換消息）來實現。

![群組聊天](../../../translated_images/multi-agent-group-chat.82d537c5c8dc833abbd252033e60874bc9d00df7193888b3377f8426449a0b20.tw.png)

### 任務交接模式

此模式適用於需要創建多代理應用，讓代理之間能夠交接任務的情況。

典型用例包括客戶支持、任務管理和工作流程自動化。

在這種模式中，每個代理代表一個任務或工作流程中的一個步驟，代理可以根據預定規則將任務交接給其他代理。

![任務交接](../../../translated_images/multi-agent-hand-off.ed4f0a5a58614a8a3e962fc476187e630a3ba309d066e460f017b503d0b84cfc.tw.png)

### 協同過濾模式

此模式適用於需要創建多代理應用，讓多個代理合作為用戶提供推薦的情況。

使用多個代理合作的原因在於，每個代理可以具備不同的專業知識，並以不同方式為推薦過程做出貢獻。

例如，用戶希望獲得股市最佳股票的推薦：

- **行業專家**：一個代理可能是特定行業的專家。
- **技術分析**：另一個代理可能專精於技術分析。
- **基本面分析**：還有一個代理可能專精於基本面分析。通過合作，這些代理可以為用戶提供更全面的推薦。

![推薦](../../../translated_images/multi-agent-filtering.719217d169391ddb118bbb726b19d4d89ee139f960f8749ccb2400efb4d0ce79.tw.png)

## 案例：退款流程

考慮一個客戶申請退款的場景，這個過程可能涉及許多代理，我們可以將其分為專屬於退款流程的代理和可以用於其他流程的通用代理。

**退款流程專屬代理**：

以下是一些可能涉及的代理：

- **客戶代理**：代表客戶，負責啟動退款流程。
- **賣家代理**：代表賣家，負責處理退款。
- **支付代理**：代表支付流程，負責將款項退還給客戶。
- **解決代理**：代表問題解決流程，負責處理退款過程中出現的問題。
- **合規代理**：代表合規流程，負責確保退款流程符合規定和政策。

**通用代理**：

這些代理可用於業務中的其他部分：

- **運輸代理**：代表運輸流程，負責將產品寄回賣家。此代理既可用於退款流程，也可用於購買流程中的運輸。
- **回饋代理**：代表回饋流程，負責收集客戶意見。回饋可隨時進行，而不僅限於退款流程。
- **升級代理**：代表升級流程，負責將問題升級至更高級別的支持。此類代理可用於任何需要升級問題的流程。
- **通知代理**：代表通知流程，負責在退款流程的各個階段向客戶發送通知。
- **分析代理**：代表分析流程，負責分析與退款相關的數據。
- **審核代理**：代表審核流程，負責檢查退款流程是否正確執行。
- **報告代理**：代表報告流程，負責生成退款流程的報告。
- **知識代理**：代表知識管理，負責維護與退款流程相關的知識庫。此代理也可以涵蓋其他業務領域。
- **安全代理**：代表安全流程，負責確保退款流程的安全性。
- **質量代理**：代表質量控制，負責確保退款流程的質量。

以上列舉了許多代理，既包括專屬於退款流程的代理，也包括可用於其他業務部分的通用代理。希望這能幫助你了解如何選擇在多代理系統中使用哪些代理。

## 作業

設計一個多代理系統來處理客戶支持流程。識別該流程中涉及的代理、它們的角色和職責，以及它們之間的互動方式。同時考慮專屬於客戶支持流程的代理以及可用於其他業務部分的通用代理。

> 在查看以下解答前，先自己思考一下，你可能需要的代理比想像中更多。

> TIP：考慮客戶支持流程的不同階段，並考慮任何系統可能需要的代理。

## 解答

[解答](./solution/solution.md)

## 知識檢查

問題：什麼時候應該考慮使用多代理？

- [] A1: 當你有少量工作負載和簡單任務時。
- [] A2: 當你有大量工作負載時。
- [] A3: 當你有簡單任務時。

[測驗解答](./solution/solution-quiz.md)

## 總結

在本課程中，我們探討了多代理設計模式，包括多代理適用的場景、使用多代理相較於單一代理的優勢、實現多代理設計模式的基礎要素，以及如何了解多個代理之間的互動情況。

## 其他資源

- [Autogen 設計模式](https://microsoft.github.io/autogen/stable/user-guide/core-user-guide/design-patterns/intro.html)
- [Agentic 設計模式](https://www.analyticsvidhya.com/blog/2024/10/agentic-design-patterns/)

**免責聲明**：
本文件使用機器翻譯服務進行翻譯。我們雖然努力確保準確性，但請注意，自動翻譯可能包含錯誤或不準確之處。原文的母語版本應被視為權威來源。如需關鍵資訊，建議尋求專業人工翻譯。我們對因使用此翻譯而產生的任何誤解或錯誤解釋概不負責。


# AI 代理中的後設認知

## 介紹
歡迎來到有關 AI 代理後設認知的課程！本章節專為對 AI 代理如何思考自身思考過程感興趣的初學者設計。完成本課程後，您將了解關鍵概念，並掌握將後設認知應用於 AI 代理設計的實際範例。

## 學習目標
完成本課程後，您將能夠：
1. 理解代理定義中的推理循環影響。
2. 使用規劃和評估技術來幫助自我修正的代理。
3. 創建能夠操作程式碼以完成任務的代理。

## 後設認知介紹
後設認知是指涉及思考自身思考的高階認知過程。對於 AI 代理來說，這意味著能夠基於自我意識和過去經驗評估並調整其行動。

### 什麼是後設認知？
後設認知，或稱「思考的思考」，是一種高階認知過程，涉及對自身認知過程的自我意識和自我調節。在 AI 領域，後設認知使代理能夠評估和調整其策略和行動，從而提高解決問題和決策的能力。通過理解後設認知，您可以設計出更智能、更具適應性和效率的 AI 代理。

### 後設認知在 AI 代理中的重要性
後設認知在 AI 代理設計中具有多方面的重要性：
![後設認知的重要性](../../../translated_images/importance-of-metacognition.e351a5983bb745d60a1a60185391a39a6751d033c8c1948ceb6ad04eff7dbeac.tw.png)
- **自我反思**：代理可以評估自身表現並找出需要改進的地方。
- **適應性**：代理可以根據過去的經驗和變化的環境調整策略。
- **錯誤修正**：代理可以自主檢測並修正錯誤，從而產生更準確的結果。
- **資源管理**：代理可以通過規劃和評估行動來優化資源的使用，如時間和計算能力。

## AI 代理的組成部分
在深入了解後設認知過程之前，必須了解 AI 代理的基本組成部分。AI 代理通常由以下部分組成：
- **角色**：代理的個性和特徵，定義其如何與用戶互動。
- **工具**：代理可以執行的功能和能力。
- **技能**：代理擁有的知識和專業技能。

這些組件協同工作，創建一個可以執行特定任務的「專業單元」。

**範例**：考慮一個旅行代理服務，該服務不僅計劃您的假期，還能根據實時數據和過去的客戶旅程經驗調整其路徑。

### 範例：旅行代理服務中的後設認知
假設您正在設計一個由 AI 驅動的旅行代理服務。這個代理「旅行代理」幫助用戶規劃假期。為了融入後設認知，旅行代理需要基於自我意識和過去的經驗評估並調整其行動。以下是後設認知可能發揮作用的方式：

#### 當前任務
當前任務是幫助用戶規劃巴黎之旅。

#### 完成任務的步驟
1. **收集用戶偏好**：詢問用戶有關旅行日期、預算、興趣（如博物館、美食、購物）及任何特定需求。
2. **檢索信息**：搜索符合用戶偏好的航班選項、住宿、景點和餐廳。
3. **生成建議**：提供包含航班詳情、酒店預訂和建議活動的個性化行程。
4. **根據反饋調整**：詢問用戶對建議的反饋並進行必要調整。

#### 所需資源
- 訪問航班和酒店預訂數據庫。
- 關於巴黎景點和餐廳的信息。
- 來自先前交互的用戶反饋數據。

#### 經驗與自我反思
旅行代理使用後設認知來評估其表現並從過去的經驗中學習。例如：
1. **分析用戶反饋**：旅行代理審查用戶反饋，以確定哪些建議受到好評，哪些不受歡迎，並相應地調整其未來建議。
2. **適應性**：如果用戶之前提到不喜歡人多的地方，旅行代理將避免在高峰時段推薦熱門旅遊景點。
3. **錯誤修正**：如果旅行代理在過去的預訂中出現錯誤，例如建議已滿房的酒店，它將學會在提供建議之前更嚴格地檢查可用性。

#### 實際開發範例
以下是旅行代理代碼如何融入後設認知的簡化範例：
```python
class Travel_Agent:
    def __init__(self):
        self.user_preferences = {}
        self.experience_data = []

    def gather_preferences(self, preferences):
        self.user_preferences = preferences

    def retrieve_information(self):
        # Search for flights, hotels, and attractions based on preferences
        flights = search_flights(self.user_preferences)
        hotels = search_hotels(self.user_preferences)
        attractions = search_attractions(self.user_preferences)
        return flights, hotels, attractions

    def generate_recommendations(self):
        flights, hotels, attractions = self.retrieve_information()
        itinerary = create_itinerary(flights, hotels, attractions)
        return itinerary

    def adjust_based_on_feedback(self, feedback):
        self.experience_data.append(feedback)
        # Analyze feedback and adjust future recommendations
        self.user_preferences = adjust_preferences(self.user_preferences, feedback)

# Example usage
travel_agent = Travel_Agent()
preferences = {
    "destination": "Paris",
    "dates": "2025-04-01 to 2025-04-10",
    "budget": "moderate",
    "interests": ["museums", "cuisine"]
}
travel_agent.gather_preferences(preferences)
itinerary = travel_agent.generate_recommendations()
print("Suggested Itinerary:", itinerary)
feedback = {"liked": ["Louvre Museum"], "disliked": ["Eiffel Tower (too crowded)"]}
travel_agent.adjust_based_on_feedback(feedback)
```

#### 後設認知的重要性
- **自我反思**：代理可以分析其表現並找出需要改進的地方。
- **適應性**：代理可以根據反饋和變化的條件調整策略。
- **錯誤修正**：代理可以自主檢測並修正錯誤。
- **資源管理**：代理可以優化資源使用，例如時間和計算能力。

通過融入後設認知，旅行代理可以提供更個性化和準確的旅行建議，提升整體用戶體驗。

---

## 2. 代理中的規劃
規劃是 AI 代理行為的關鍵組成部分。它涉及在考慮當前狀態、資源和可能的障礙的情況下，概述實現目標所需的步驟。

### 規劃的要素
- **當前任務**：清楚地定義任務。
- **完成任務的步驟**：將任務分解為可管理的步驟。
- **所需資源**：確定必要的資源。
- **經驗**：利用過去的經驗來指導規劃。

**範例**：以下是旅行代理有效協助用戶規劃旅行所需採取的步驟：

### 旅行代理的步驟
1. **收集用戶偏好**
   - 詢問用戶有關旅行日期、預算、興趣及任何特定需求的詳細信息。
   - 範例：「您計劃什麼時候旅行？」、「您的預算範圍是多少？」、「您在假期中喜歡哪些活動？」

2. **檢索信息**
   - 根據用戶偏好搜索相關旅行選項。
   - **航班**：尋找符合用戶預算和偏好日期的可用航班。
   - **住宿**：找到符合用戶對地點、價格和設施偏好的酒店或出租房產。
   - **景點和餐廳**：識別符合用戶興趣的熱門景點、活動和餐飲選項。

3. **生成建議**
   - 將檢索到的信息編輯成個性化行程。
   - 提供詳細信息，例如航班選項、酒店預訂和建議活動，確保建議符合用戶偏好。

4. **向用戶展示行程**
   - 與用戶分享建議的行程以供審查。
   - 範例：「這是您巴黎之旅的建議行程，包括航班詳情、酒店預訂和推薦的活動及餐廳。請告訴我您的想法！」

5. **收集反饋**
   - 詢問用戶對建議行程的反饋。
   - 範例：「您喜歡這些航班選項嗎？」、「這家酒店是否符合您的需求？」、「有沒有您想添加或刪除的活動？」

6. **根據反饋調整**
   - 根據用戶反饋修改行程。
   - 對航班、住宿和活動建議進行必要更改，以更好地符合用戶偏好。

7. **最終確認**
   - 向用戶展示更新後的行程以供最終確認。
   - 範例：「我根據您的反饋進行了調整。這是更新後的行程。您看起來如何？」

8. **預訂並確認預約**
   - 在用戶批准行程後，進行航班、住宿和任何預定活動的預訂。
   - 向用戶發送確認詳細信息。

9. **提供持續支持**
   - 在旅行前和旅行期間隨時協助用戶進行任何更改或額外請求。
   - 範例：「如果您在旅行期間需要進一步協助，請隨時與我聯繫！」

### 範例互動
```python
class Travel_Agent:
    def __init__(self):
        self.user_preferences = {}
        self.experience_data = []

    def gather_preferences(self, preferences):
        self.user_preferences = preferences

    def retrieve_information(self):
        flights = search_flights(self.user_preferences)
        hotels = search_hotels(self.user_preferences)
        attractions = search_attractions(self.user_preferences)
        return flights, hotels, attractions

    def generate_recommendations(self):
        flights, hotels, attractions = self.retrieve_information()
        itinerary = create_itinerary(flights, hotels, attractions)
        return itinerary

    def adjust_based_on_feedback(self, feedback):
        self.experience_data.append(feedback)
        self.user_preferences = adjust_preferences(self.user_preferences, feedback)

# Example usage within a booing request
travel_agent = Travel_Agent()
preferences = {
    "destination": "Paris",
    "dates": "2025-04-01 to 2025-04-10",
    "budget": "moderate",
    "interests": ["museums", "cuisine"]
}
travel_agent.gather_preferences(preferences)
itinerary = travel_agent.generate_recommendations()
print("Suggested Itinerary:", itinerary)
feedback = {"liked": ["Louvre Museum"], "disliked": ["Eiffel Tower (too crowded)"]}
travel_agent.adjust_based_on_feedback(feedback)
```

## 3. 修正型 RAG 系統
首先，讓我們了解 RAG 工具和預先加載上下文之間的區別：
![RAG 與上下文加載的區別](../../../translated_images/rag-vs-context.9bb2b76d17aeba1489ad2a43ddbc9cd20e7ada4e4871cc99c63a498aa0ff70f7.tw.png)

### 檢索增強生成 (RAG)
RAG 將檢索系統與生成模型結合在一起。當進行查詢時，檢索系統從外部來源獲取相關文檔或數據，並將檢索到的信息用於增強生成模型的輸入。這有助於模型生成更準確且上下文相關的響應。

在 RAG 系統中，代理從知識庫中檢索相關信息，並使用它來生成適當的響應或行動。

### 修正型 RAG 方法
修正型 RAG 方法側重於使用 RAG 技術來修正錯誤並提高 AI 代理的準確性。這包括：
1. **提示技術**：使用特定提示來指導代理檢索相關信息。
2. **工具**：實施算法和機制，使代理能夠評估檢索信息的相關性並生成準確的響應。
3. **評估**：持續評估代理的表現並進行調整以提高其準確性和效率。

#### 範例：搜索代理中的修正型 RAG
考慮一個從網絡中檢索信息以回答用戶查詢的搜索代理。修正型 RAG 方法可能包括：
1. **提示技術**：根據用戶輸入制定搜索查詢。
2. **工具**：使用自然語言處理和機器學習算法對搜索結果進行排序和篩選。
3. **評估**：分析用戶反饋以識別並修正檢索信息中的不準確之處。

### 修正型 RAG 在旅行代理中的應用
修正型 RAG（檢索增強生成）增強了 AI 檢索和生成信息的能力，同時修正任何不準確之處。讓我們看看旅行代理如何使用修正型 RAG 方法來提供更準確和相關的旅行建議。這包括：
- **提示技術**：使用特定提示來指導代理檢索相關信息。
- **工具**：實施算法和機制，使代理能夠評估檢索信息的相關性並生成準確的響應。
- **評估**：持續評估代理的表現並進行調整以提高其準確性和效率。

#### 在旅行代理中實施修正型 RAG 的步驟
1. **初始用戶交互**
   - 旅行代理收集用戶的初始偏好，例如目的地、旅行日期、預算和興趣。
   - 範例：```python
     preferences = {
         "destination": "Paris",
         "dates": "2025-04-01 to 2025-04-10",
         "budget": "moderate",
         "interests": ["museums", "cuisine"]
     }
     ```

2. **信息檢索**
   - 旅行代理根據用戶偏好檢索有關航班、住宿、景點和餐廳的信息。
   - 範例：```python
     flights = search_flights(preferences)
     hotels = search_hotels(preferences)
     attractions = search_attractions(preferences)
     ```

3. **生成初始建議**
   - 旅行代理使用檢索到的信息生成個性化行程。
   - 範例：```python
     itinerary = create_itinerary(flights, hotels, attractions)
     print("Suggested Itinerary:", itinerary)
     ```

4. **收集用戶反饋**
   - 旅行代理詢問用戶對初始建議的反饋。
   - 範例：```python
     feedback = {
         "liked": ["Louvre Museum"],
         "disliked": ["Eiffel Tower (too crowded)"]
     }
     ```

5. **修正型 RAG 過程**
   - **提示技術**：
```
```markdown
旅行代理根據用戶反饋制定新的搜索查詢。
- 範例：```python
       if "disliked" in feedback:
           preferences["avoid"] = feedback["disliked"]
       ```
- **工具**：旅行代理使用算法根據用戶反饋對新搜索結果進行排名和篩選，強調相關性。
- 範例：```python
       new_attractions = search_attractions(preferences)
       new_itinerary = create_itinerary(flights, hotels, new_attractions)
       print("Updated Itinerary:", new_itinerary)
       ```
- **評估**：旅行代理通過分析用戶反饋並進行必要的調整，不斷評估其推薦的相關性和準確性。
- 範例：```python
       def adjust_preferences(preferences, feedback):
           if "liked" in feedback:
               preferences["favorites"] = feedback["liked"]
           if "disliked" in feedback:
               preferences["avoid"] = feedback["disliked"]
           return preferences

       preferences = adjust_preferences(preferences, feedback)
       ```

#### 實際範例
以下是一個將改進型 RAG 方法應用於旅行代理的簡化 Python 代碼範例：
```python
class Travel_Agent:
    def __init__(self):
        self.user_preferences = {}
        self.experience_data = []

    def gather_preferences(self, preferences):
        self.user_preferences = preferences

    def retrieve_information(self):
        flights = search_flights(self.user_preferences)
        hotels = search_hotels(self.user_preferences)
        attractions = search_attractions(self.user_preferences)
        return flights, hotels, attractions

    def generate_recommendations(self):
        flights, hotels, attractions = self.retrieve_information()
        itinerary = create_itinerary(flights, hotels, attractions)
        return itinerary

    def adjust_based_on_feedback(self, feedback):
        self.experience_data.append(feedback)
        self.user_preferences = adjust_preferences(self.user_preferences, feedback)
        new_itinerary = self.generate_recommendations()
        return new_itinerary

# Example usage
travel_agent = Travel_Agent()
preferences = {
    "destination": "Paris",
    "dates": "2025-04-01 to 2025-04-10",
    "budget": "moderate",
    "interests": ["museums", "cuisine"]
}
travel_agent.gather_preferences(preferences)
itinerary = travel_agent.generate_recommendations()
print("Suggested Itinerary:", itinerary)
feedback = {"liked": ["Louvre Museum"], "disliked": ["Eiffel Tower (too crowded)"]}
new_itinerary = travel_agent.adjust_based_on_feedback(feedback)
print("Updated Itinerary:", new_itinerary)
```

### 預加載上下文
預加載上下文是指在處理查詢之前將相關的上下文或背景信息加載到模型中。這意味著模型從一開始就可以訪問這些信息，從而在不需要在過程中檢索額外數據的情況下生成更具信息量的響應。以下是一個旅行代理應用中如何進行預加載上下文的簡化 Python 代碼範例：
```python
class TravelAgent:
    def __init__(self):
        # Pre-load popular destinations and their information
        self.context = {
            "Paris": {"country": "France", "currency": "Euro", "language": "French", "attractions": ["Eiffel Tower", "Louvre Museum"]},
            "Tokyo": {"country": "Japan", "currency": "Yen", "language": "Japanese", "attractions": ["Tokyo Tower", "Shibuya Crossing"]},
            "New York": {"country": "USA", "currency": "Dollar", "language": "English", "attractions": ["Statue of Liberty", "Times Square"]},
            "Sydney": {"country": "Australia", "currency": "Dollar", "language": "English", "attractions": ["Sydney Opera House", "Bondi Beach"]}
        }

    def get_destination_info(self, destination):
        # Fetch destination information from pre-loaded context
        info = self.context.get(destination)
        if info:
            return f"{destination}:\nCountry: {info['country']}\nCurrency: {info['currency']}\nLanguage: {info['language']}\nAttractions: {', '.join(info['attractions'])}"
        else:
            return f"Sorry, we don't have information on {destination}."

# Example usage
travel_agent = TravelAgent()
print(travel_agent.get_destination_info("Paris"))
print(travel_agent.get_destination_info("Tokyo"))
```

#### 解釋
1. **初始化 (`__init__` method)**: The `TravelAgent` class pre-loads a dictionary containing information about popular destinations such as Paris, Tokyo, New York, and Sydney. This dictionary includes details like the country, currency, language, and major attractions for each destination.

2. **Retrieving Information (`get_destination_info` method)**: When a user queries about a specific destination, the `get_destination_info` 方法)**：該方法從預加載的上下文字典中獲取相關信息。通過預加載上下文，旅行代理應用可以快速響應用戶查詢，而不需要實時從外部來源檢索信息。這使應用更加高效和快速響應。

### 在迭代前以目標啟動計劃
以目標啟動計劃是指在開始時明確設定一個清晰的目標或期望結果。通過預先定義這個目標，模型可以在整個迭代過程中將其作為指導原則。這有助於確保每次迭代都更接近實現期望結果，使過程更高效且更專注。以下是一個如何在迭代之前以目標啟動旅行計劃的範例：

### 情景
一名旅行代理希望為客戶計劃一個定制的假期。目標是根據客戶的偏好和預算創建一個最大化客戶滿意度的旅行行程。

### 步驟
1. 定義客戶的偏好和預算。
2. 根據這些偏好啟動初始計劃。
3. 迭代以改進計劃，優化客戶滿意度。

#### Python 代碼
```python
class TravelAgent:
    def __init__(self, destinations):
        self.destinations = destinations

    def bootstrap_plan(self, preferences, budget):
        plan = []
        total_cost = 0

        for destination in self.destinations:
            if total_cost + destination['cost'] <= budget and self.match_preferences(destination, preferences):
                plan.append(destination)
                total_cost += destination['cost']

        return plan

    def match_preferences(self, destination, preferences):
        for key, value in preferences.items():
            if destination.get(key) != value:
                return False
        return True

    def iterate_plan(self, plan, preferences, budget):
        for i in range(len(plan)):
            for destination in self.destinations:
                if destination not in plan and self.match_preferences(destination, preferences) and self.calculate_cost(plan, destination) <= budget:
                    plan[i] = destination
                    break
        return plan

    def calculate_cost(self, plan, new_destination):
        return sum(destination['cost'] for destination in plan) + new_destination['cost']

# Example usage
destinations = [
    {"name": "Paris", "cost": 1000, "activity": "sightseeing"},
    {"name": "Tokyo", "cost": 1200, "activity": "shopping"},
    {"name": "New York", "cost": 900, "activity": "sightseeing"},
    {"name": "Sydney", "cost": 1100, "activity": "beach"},
]

preferences = {"activity": "sightseeing"}
budget = 2000

travel_agent = TravelAgent(destinations)
initial_plan = travel_agent.bootstrap_plan(preferences, budget)
print("Initial Plan:", initial_plan)

refined_plan = travel_agent.iterate_plan(initial_plan, preferences, budget)
print("Refined Plan:", refined_plan)
```

#### 代碼解釋
1. **初始化 (`__init__` method)**: The `TravelAgent` class is initialized with a list of potential destinations, each having attributes like name, cost, and activity type.

2. **Bootstrapping the Plan (`bootstrap_plan` method)**: This method creates an initial travel plan based on the client's preferences and budget. It iterates through the list of destinations and adds them to the plan if they match the client's preferences and fit within the budget.

3. **Matching Preferences (`match_preferences` method)**: This method checks if a destination matches the client's preferences.

4. **Iterating the Plan (`iterate_plan` method)**: This method refines the initial plan by trying to replace each destination in the plan with a better match, considering the client's preferences and budget constraints.

5. **Calculating Cost (`calculate_cost` 方法)**：該方法計算當前計劃的總成本，包括潛在的新目的地。

#### 範例使用
- **初始計劃**：旅行代理根據客戶對觀光的偏好和 2000 美元的預算創建初始計劃。
- **改進計劃**：旅行代理通過迭代改進計劃，優化客戶的偏好和預算。

通過以清晰的目標啟動計劃（例如，最大化客戶滿意度）並迭代改進計劃，旅行代理可以為客戶創建定制且優化的旅行行程。這種方法確保旅行計劃從一開始就符合客戶的偏好和預算，並隨著每次迭代而改進。

### 利用 LLM 進行重新排序和評分
大型語言模型（LLM）可以通過評估檢索到的文檔或生成的響應的相關性和質量來進行重新排序和評分。其運作方式如下：

**檢索**：初始檢索步驟根據查詢獲取一組候選文檔或響應。
**重新排序**：LLM 評估這些候選項，並根據其相關性和質量進行重新排序。此步驟確保最相關和高質量的信息首先呈現。
**評分**：LLM 為每個候選項分配分數，反映其相關性和質量。這有助於選擇最佳響應或文檔提供給用戶。

通過利用 LLM 進行重新排序和評分，系統可以提供更準確和上下文相關的信息，改善整體用戶體驗。以下是一個旅行代理如何使用大型語言模型（LLM）根據用戶偏好對旅行目的地進行重新排序和評分的範例：

#### 情景 - 基於偏好的旅行
一名旅行代理希望根據客戶的偏好推薦最佳旅行目的地。LLM 將幫助重新排序和評分目的地，確保呈現最相關的選項。

#### 步驟：
1. 收集用戶偏好。
2. 檢索潛在旅行目的地列表。
3. 使用 LLM 根據用戶偏好重新排序和評分目的地。

以下是如何更新之前的範例以使用 Azure OpenAI Services：

#### 要求
1. 您需要擁有 Azure 訂閱。
2. 創建 Azure OpenAI 資源並獲取您的 API 密鑰。

#### Python 代碼範例
```python
import requests
import json

class TravelAgent:
    def __init__(self, destinations):
        self.destinations = destinations

    def get_recommendations(self, preferences, api_key, endpoint):
        # Generate a prompt for the Azure OpenAI
        prompt = self.generate_prompt(preferences)

        # Define headers and payload for the request
        headers = {
            'Content-Type': 'application/json',
            'Authorization': f'Bearer {api_key}'
        }
        payload = {
            "prompt": prompt,
            "max_tokens": 150,
            "temperature": 0.7
        }

        # Call the Azure OpenAI API to get the re-ranked and scored destinations
        response = requests.post(endpoint, headers=headers, json=payload)
        response_data = response.json()

        # Extract and return the recommendations
        recommendations = response_data['choices'][0]['text'].strip().split('\n')
        return recommendations

    def generate_prompt(self, preferences):
        prompt = "Here are the travel destinations ranked and scored based on the following user preferences:\n"
        for key, value in preferences.items():
            prompt += f"{key}: {value}\n"
        prompt += "\nDestinations:\n"
        for destination in self.destinations:
            prompt += f"- {destination['name']}: {destination['description']}\n"
        return prompt

# Example usage
destinations = [
    {"name": "Paris", "description": "City of lights, known for its art, fashion, and culture."},
    {"name": "Tokyo", "description": "Vibrant city, famous for its modernity and traditional temples."},
    {"name": "New York", "description": "The city that never sleeps, with iconic landmarks and diverse culture."},
    {"name": "Sydney", "description": "Beautiful harbour city, known for its opera house and stunning beaches."},
]

preferences = {"activity": "sightseeing", "culture": "diverse"}
api_key = 'your_azure_openai_api_key'
endpoint = 'https://your-endpoint.com/openai/deployments/your-deployment-name/completions?api-version=2022-12-01'

travel_agent = TravelAgent(destinations)
recommendations = travel_agent.get_recommendations(preferences, api_key, endpoint)
print("Recommended Destinations:")
for rec in recommendations:
    print(rec)
```

#### 代碼解釋 - 偏好預訂器
1. **初始化**：`TravelAgent` class is initialized with a list of potential travel destinations, each having attributes like name and description.

2. **Getting Recommendations (`get_recommendations` method)**: This method generates a prompt for the Azure OpenAI service based on the user's preferences and makes an HTTP POST request to the Azure OpenAI API to get re-ranked and scored destinations.

3. **Generating Prompt (`generate_prompt` method)**: This method constructs a prompt for the Azure OpenAI, including the user's preferences and the list of destinations. The prompt guides the model to re-rank and score the destinations based on the provided preferences.

4. **API Call**: The `requests` library is used to make an HTTP POST request to the Azure OpenAI API endpoint. The response contains the re-ranked and scored destinations.

5. **Example Usage**: The travel agent collects user preferences (e.g., interest in sightseeing and diverse culture) and uses the Azure OpenAI service to get re-ranked and scored recommendations for travel destinations.

Make sure to replace `your_azure_openai_api_key` with your actual Azure OpenAI API key and `https://your-endpoint.com/...` 使用 Azure OpenAI 部署的實際端點 URL 替換。

通過利用 LLM 進行重新排序和評分，旅行代理可以為客戶提供更個性化和相關的旅行推薦，增強其整體體驗。

### RAG：提示技術與工具
檢索增強生成（RAG）既可以作為提示技術，也可以作為 AI 代理開發中的工具。理解這兩者之間的區別可以幫助您在項目中更有效地利用 RAG。

#### RAG 作為提示技術
**它是什麼？**
- 作為提示技術，RAG 涉及制定特定查詢或提示，以指導從大型語料庫或數據庫中檢索相關信息。這些信息隨後用於生成響應或操作。

**如何運作：**
1. **制定提示**：根據手頭的任務或用戶的輸入創建結構良好的提示或查詢。
2. **檢索信息**：使用提示從預先存在的知識庫或數據集中搜索相關數據。
3. **生成響應**：將檢索到的信息與生成式 AI 模型結合，生成全面且連貫的響應。

**旅行代理範例**：
- 用戶輸入："我想參觀巴黎的博物館。"
- 提示："查找巴黎的頂級博物館。"
- 檢索信息：有關盧浮宮、奧賽博物館等的詳細信息。
- 生成響應："以下是巴黎的一些頂級博物館：盧浮宮、奧賽博物館和龐畢度中心。"

#### RAG 作為工具
**它是什麼？**
- 作為工具，RAG 是一個集成系統，自動化檢索和生成過程，使開發人員能夠更輕鬆地實現複雜的 AI 功能，而無需為每個查詢手動編寫提示。

**如何運作：**
1. **集成**：將 RAG 嵌入到 AI 代理的架構中，使其能夠自動處理檢索和生成任務。
2. **自動化**：該工具管理從接收用戶輸入到生成最終響應的整個過程，而無需為每個步驟顯式提示。
3. **高效性**：通過簡化檢索和生成過程，提高代理的性能，實現更快更準確的響應。

**旅行代理範例**：
- 用戶輸入："我想參觀巴黎的博物館。"
- RAG 工具：自動檢索有關博物館的信息並生成響應。
- 生成響應："以下是巴黎的一些頂級博物館：盧浮宮、奧賽博物館和龐畢度中心。"

### 比較

| 方面                 | 提示技術                                           | 工具                                       |
|----------------------|---------------------------------------------------|-------------------------------------------|
| **手動與自動**       | 為每個查詢手動制定提示。                           | 自動化檢索和生成過程。                     |
| **控制**             | 提供更多對檢索過程的控制。                        | 簡化並自動化檢索和生成。                   |
| **靈活性**           | 允許根據特定需求自定義提示。                      | 更適合大規模實施。                         |
| **複雜性**           | 需要編寫和調整提示。                              | 更易於集成到 AI 代理架構中。               |

### 實際範例
**提示技術範例：**
```python
def search_museums_in_paris():
    prompt = "Find top museums in Paris"
    search_results = search_web(prompt)
    return search_results

museums = search_museums_in_paris()
print("Top Museums in Paris:", museums)
```
**工具範例：**
```python
class Travel_Agent:
    def __init__(self):
        self.rag_tool = RAGTool()

    def get_museums_in_paris(self):
        user_input = "I want to visit museums in Paris."
        response = self.rag_tool.retrieve_and_generate(user_input)
        return response

travel_agent = Travel_Agent()
museums = travel_agent.get_museums_in_paris()
print("Top Museums in Paris:", museums)
```
```
```markdown
巴黎最好的博物館？")。
- **導航意圖**：使用者希望導航到特定的網站或頁面（例如，「羅浮宮官方網站」）。
- **交易意圖**：使用者目的是進行交易，例如預訂航班或購買商品（例如，「預訂飛往巴黎的航班」）。

2. **上下文感知**：
   - 分析使用者查詢的上下文有助於準確識別其意圖，包括考慮先前的互動、使用者偏好以及當前查詢的具體細節。

3. **自然語言處理 (NLP)**：
   - 採用 NLP 技術理解並解釋使用者提供的自然語言查詢，包括實體識別、情感分析和查詢解析等任務。

4. **個性化**：
   - 根據使用者的歷史記錄、偏好和反饋個性化搜尋結果，提升檢索資訊的相關性。

#### 實際範例：在旅行代理中基於意圖搜尋
以下以旅行代理為例，說明如何實現基於意圖的搜尋。

1. **收集使用者偏好**
```python
   class Travel_Agent:
       def __init__(self):
           self.user_preferences = {}

       def gather_preferences(self, preferences):
           self.user_preferences = preferences
   ```

2. **理解使用者意圖**
```python
   def identify_intent(query):
       if "book" in query or "purchase" in query:
           return "transactional"
       elif "website" in query or "official" in query:
           return "navigational"
       else:
           return "informational"
   ```

3. **上下文感知**
```python
   def analyze_context(query, user_history):
       # Combine current query with user history to understand context
       context = {
           "current_query": query,
           "user_history": user_history
       }
       return context
   ```

4. **搜尋並個性化結果**
```python
   def search_with_intent(query, preferences, user_history):
       intent = identify_intent(query)
       context = analyze_context(query, user_history)
       if intent == "informational":
           search_results = search_information(query, preferences)
       elif intent == "navigational":
           search_results = search_navigation(query)
       elif intent == "transactional":
           search_results = search_transaction(query, preferences)
       personalized_results = personalize_results(search_results, user_history)
       return personalized_results

   def search_information(query, preferences):
       # Example search logic for informational intent
       results = search_web(f"best {preferences['interests']} in {preferences['destination']}")
       return results

   def search_navigation(query):
       # Example search logic for navigational intent
       results = search_web(query)
       return results

   def search_transaction(query, preferences):
       # Example search logic for transactional intent
       results = search_web(f"book {query} to {preferences['destination']}")
       return results

   def personalize_results(results, user_history):
       # Example personalization logic
       personalized = [result for result in results if result not in user_history]
       return personalized[:10]  # Return top 10 personalized results
   ```

5. **範例用法**
```python
   travel_agent = Travel_Agent()
   preferences = {
       "destination": "Paris",
       "interests": ["museums", "cuisine"]
   }
   travel_agent.gather_preferences(preferences)
   user_history = ["Louvre Museum website", "Book flight to Paris"]
   query = "best museums in Paris"
   results = search_with_intent(query, preferences, user_history)
   print("Search Results:", results)
   ```

---

## 4. 作為工具生成程式碼
程式碼生成代理使用 AI 模型編寫並執行程式碼，解決複雜問題並自動化任務。

### 程式碼生成代理
程式碼生成代理使用生成式 AI 模型來編寫並執行程式碼。這些代理可以通過生成並運行多種程式語言的程式碼來解決複雜問題、自動化任務並提供有價值的洞察。

#### 實際應用
1. **自動化程式碼生成**：生成特定任務的程式碼片段，例如數據分析、網頁抓取或機器學習。
2. **SQL 作為 RAG**：使用 SQL 查詢檢索和操作數據庫中的數據。
3. **問題解決**：創建並執行程式碼解決特定問題，例如優化算法或分析數據。

#### 範例：用於數據分析的程式碼生成代理
假設您正在設計一個程式碼生成代理，以下是其工作方式：

1. **任務**：分析數據集以識別趨勢和模式。
2. **步驟**：
   - 將數據集加載到數據分析工具中。
   - 生成 SQL 查詢以篩選和聚合數據。
   - 執行查詢並檢索結果。
   - 使用結果生成可視化和洞察。
3. **所需資源**：訪問數據集、數據分析工具和 SQL 功能。
4. **經驗**：使用過去的分析結果提高未來分析的準確性和相關性。

### 範例：用於旅行代理的程式碼生成代理
在此範例中，我們將設計一個程式碼生成代理「旅行代理」，通過生成和執行程式碼來協助使用者規劃旅行。此代理可處理檢索旅行選項、篩選結果和使用生成式 AI 編譯行程等任務。

#### 程式碼生成代理概述
1. **收集使用者偏好**：收集使用者輸入的目的地、旅行日期、預算和興趣等。
2. **生成程式碼以檢索數據**：生成程式碼片段檢索航班、酒店和景點的數據。
3. **執行生成的程式碼**：運行生成的程式碼以獲取實時資訊。
4. **生成行程**：將檢索到的數據編譯成個性化的旅行計劃。
5. **基於反饋調整**：接收使用者反饋，必要時重新生成程式碼以優化結果。

#### 分步實施
1. **收集使用者偏好**
```python
   class Travel_Agent:
       def __init__(self):
           self.user_preferences = {}

       def gather_preferences(self, preferences):
           self.user_preferences = preferences
   ```

2. **生成程式碼以檢索數據**
```python
   def generate_code_to_fetch_data(preferences):
       # Example: Generate code to search for flights based on user preferences
       code = f"""
       def search_flights():
           import requests
           response = requests.get('https://api.example.com/flights', params={preferences})
           return response.json()
       """
       return code

   def generate_code_to_fetch_hotels(preferences):
       # Example: Generate code to search for hotels
       code = f"""
       def search_hotels():
           import requests
           response = requests.get('https://api.example.com/hotels', params={preferences})
           return response.json()
       """
       return code
   ```

3. **執行生成的程式碼**
```python
   def execute_code(code):
       # Execute the generated code using exec
       exec(code)
       result = locals()
       return result

   travel_agent = Travel_Agent()
   preferences = {
       "destination": "Paris",
       "dates": "2025-04-01 to 2025-04-10",
       "budget": "moderate",
       "interests": ["museums", "cuisine"]
   }
   travel_agent.gather_preferences(preferences)

   flight_code = generate_code_to_fetch_data(preferences)
   hotel_code = generate_code_to_fetch_hotels(preferences)

   flights = execute_code(flight_code)
   hotels = execute_code(hotel_code)

   print("Flight Options:", flights)
   print("Hotel Options:", hotels)
   ```

4. **生成行程**
```python
   def generate_itinerary(flights, hotels, attractions):
       itinerary = {
           "flights": flights,
           "hotels": hotels,
           "attractions": attractions
       }
       return itinerary

   attractions = search_attractions(preferences)
   itinerary = generate_itinerary(flights, hotels, attractions)
   print("Suggested Itinerary:", itinerary)
   ```

5. **基於反饋調整**
```python
   def adjust_based_on_feedback(feedback, preferences):
       # Adjust preferences based on user feedback
       if "liked" in feedback:
           preferences["favorites"] = feedback["liked"]
       if "disliked" in feedback:
           preferences["avoid"] = feedback["disliked"]
       return preferences

   feedback = {"liked": ["Louvre Museum"], "disliked": ["Eiffel Tower (too crowded)"]}
   updated_preferences = adjust_based_on_feedback(feedback, preferences)

   # Regenerate and execute code with updated preferences
   updated_flight_code = generate_code_to_fetch_data(updated_preferences)
   updated_hotel_code = generate_code_to_fetch_hotels(updated_preferences)

   updated_flights = execute_code(updated_flight_code)
   updated_hotels = execute_code(updated_hotel_code)

   updated_itinerary = generate_itinerary(updated_flights, updated_hotels, attractions)
   print("Updated Itinerary:", updated_itinerary)
   ```

### 利用環境感知和推理
基於表格的結構模式可以通過利用環境感知和推理來增強查詢生成過程。以下是一個範例：

1. **理解結構模式**：系統將理解表格的結構模式並使用此資訊作為查詢生成的基礎。
2. **基於反饋調整**：系統根據反饋調整使用者偏好並推理需要更新的結構模式欄位。
3. **生成並執行查詢**：系統生成並執行查詢，以根據新偏好檢索更新的航班和酒店數據。

以下是一個包含這些概念的更新 Python 程式碼範例：
```python
def adjust_based_on_feedback(feedback, preferences, schema):
    # Adjust preferences based on user feedback
    if "liked" in feedback:
        preferences["favorites"] = feedback["liked"]
    if "disliked" in feedback:
        preferences["avoid"] = feedback["disliked"]
    # Reasoning based on schema to adjust other related preferences
    for field in schema:
        if field in preferences:
            preferences[field] = adjust_based_on_environment(feedback, field, schema)
    return preferences

def adjust_based_on_environment(feedback, field, schema):
    # Custom logic to adjust preferences based on schema and feedback
    if field in feedback["liked"]:
        return schema[field]["positive_adjustment"]
    elif field in feedback["disliked"]:
        return schema[field]["negative_adjustment"]
    return schema[field]["default"]

def generate_code_to_fetch_data(preferences):
    # Generate code to fetch flight data based on updated preferences
    return f"fetch_flights(preferences={preferences})"

def generate_code_to_fetch_hotels(preferences):
    # Generate code to fetch hotel data based on updated preferences
    return f"fetch_hotels(preferences={preferences})"

def execute_code(code):
    # Simulate execution of code and return mock data
    return {"data": f"Executed: {code}"}

def generate_itinerary(flights, hotels, attractions):
    # Generate itinerary based on flights, hotels, and attractions
    return {"flights": flights, "hotels": hotels, "attractions": attractions}

# Example schema
schema = {
    "favorites": {"positive_adjustment": "increase", "negative_adjustment": "decrease", "default": "neutral"},
    "avoid": {"positive_adjustment": "decrease", "negative_adjustment": "increase", "default": "neutral"}
}

# Example usage
preferences = {"favorites": "sightseeing", "avoid": "crowded places"}
feedback = {"liked": ["Louvre Museum"], "disliked": ["Eiffel Tower (too crowded)"]}
updated_preferences = adjust_based_on_feedback(feedback, preferences, schema)

# Regenerate and execute code with updated preferences
updated_flight_code = generate_code_to_fetch_data(updated_preferences)
updated_hotel_code = generate_code_to_fetch_hotels(updated_preferences)

updated_flights = execute_code(updated_flight_code)
updated_hotels = execute_code(updated_hotel_code)

updated_itinerary = generate_itinerary(updated_flights, updated_hotels, feedback["liked"])
print("Updated Itinerary:", updated_itinerary)
```

#### 說明 - 基於反饋的預訂
1. **結構模式感知**：`schema` dictionary defines how preferences should be adjusted based on feedback. It includes fields like `favorites` and `avoid`, with corresponding adjustments.
2. **Adjusting Preferences (`adjust_based_on_feedback` method)**: This method adjusts preferences based on user feedback and the schema.
3. **Environment-Based Adjustments (`adjust_based_on_environment` 方法）**：此方法基於結構模式和反饋定制調整。
4. **生成並執行查詢**：系統生成程式碼以根據調整後的偏好檢索更新的航班和酒店數據，並模擬執行這些查詢。
5. **生成行程**：系統基於新的航班、酒店和景點數據創建更新的行程。

通過使系統具備環境感知能力並基於結構模式推理，它可以生成更準確和相關的查詢，從而提供更好的旅行建議和更個性化的使用者體驗。

### 使用 SQL 作為檢索增強生成 (RAG) 技術
SQL（結構化查詢語言）是一種強大的數據庫交互工具。作為檢索增強生成 (RAG) 方法的一部分，SQL 可以從數據庫中檢索相關數據，以便在 AI 代理中生成回應或執行操作。以下探討如何在旅行代理的上下文中使用 SQL 作為 RAG 技術。

#### 關鍵概念
1. **數據庫交互**：
   - 使用 SQL 查詢數據庫，檢索相關資訊並操作數據。
   - 範例：從旅行數據庫中檢索航班詳情、酒店資訊和景點資料。
2. **與 RAG 集成**：
   - 根據使用者輸入和偏好生成 SQL 查詢。
   - 然後使用檢索到的數據生成個性化建議或操作。
3. **動態查詢生成**：
   - AI 代理根據上下文和使用者需求生成動態 SQL 查詢。
   - 範例：定制 SQL 查詢以根據預算、日期和興趣篩選結果。

#### 應用
- **自動化程式碼生成**：生成特定任務的程式碼片段。
- **SQL 作為 RAG**：使用 SQL 查詢操作數據。
- **問題解決**：創建並執行程式碼解決問題。

**範例**：數據分析代理：
1. **任務**：分析數據集以發現趨勢。
2. **步驟**：
   - 加載數據集。
   - 生成 SQL 查詢以篩選數據。
   - 執行查詢並檢索結果。
   - 生成可視化和洞察。
3. **資源**：數據集訪問、SQL 功能。
4. **經驗**：使用過去的結果改進未來分析。

#### 實際範例：在旅行代理中使用 SQL
1. **收集使用者偏好**
```python
   class Travel_Agent:
       def __init__(self):
           self.user_preferences = {}

       def gather_preferences(self, preferences):
           self.user_preferences = preferences
   ```

2. **生成 SQL 查詢**
```python
   def generate_sql_query(table, preferences):
       query = f"SELECT * FROM {table} WHERE "
       conditions = []
       for key, value in preferences.items():
           conditions.append(f"{key}='{value}'")
       query += " AND ".join(conditions)
       return query
   ```

3. **執行 SQL 查詢**
```python
   import sqlite3

   def execute_sql_query(query, database="travel.db"):
       connection = sqlite3.connect(database)
       cursor = connection.cursor()
       cursor.execute(query)
       results = cursor.fetchall()
       connection.close()
       return results
   ```

4. **生成建議**
```python
   def generate_recommendations(preferences):
       flight_query = generate_sql_query("flights", preferences)
       hotel_query = generate_sql_query("hotels", preferences)
       attraction_query = generate_sql_query("attractions", preferences)

       flights = execute_sql_query(flight_query)
       hotels = execute_sql_query(hotel_query)
       attractions = execute_sql_query(attraction_query)

       itinerary = {
           "flights": flights,
           "hotels": hotels,
           "attractions": attractions
       }
       return itinerary

   travel_agent = Travel_Agent()
   preferences = {
       "destination": "Paris",
       "dates": "2025-04-01 to 2025-04-10",
       "budget": "moderate",
       "interests": ["museums", "cuisine"]
   }
   travel_agent.gather_preferences(preferences)
   itinerary = generate_recommendations(preferences)
   print("Suggested Itinerary:", itinerary)
   ```

#### 範例 SQL 查詢
1. **航班查詢**
```sql
   SELECT * FROM flights WHERE destination='Paris' AND dates='2025-04-01 to 2025-04-10' AND budget='moderate';
   ```

2. **酒店查詢**
```sql
   SELECT * FROM hotels WHERE destination='Paris' AND budget='moderate';
   ```

3. **景點查詢**
```sql
   SELECT * FROM attractions WHERE destination='Paris' AND interests='museums, cuisine';
   ```

通過將 SQL 作為檢索增強生成 (RAG) 方法的一部分，像旅行代理這樣的 AI 代理可以動態檢索和利用相關數據，提供準確且個性化的建議。

### 結論
元認知是一種強大的工具，可以顯著增強 AI 代理的能力。通過結合元認知過程，您可以設計出更加智能、適應性更強且更高效的代理。使用附加資源進一步探索 AI 代理中元認知的迷人世界。
```

**免責聲明**：
本文件使用基於機器的人工智能翻譯服務進行翻譯。儘管我們努力確保準確性，但請注意，自動翻譯可能包含錯誤或不準確之處。應以原文文件作為權威來源。對於關鍵信息，建議尋求專業人工翻譯。我們對因使用本翻譯而產生的任何誤解或誤讀不承擔責任。


# AI Agents in Production

## 簡介

本課程將涵蓋以下內容：

- 如何有效地規劃將 AI Agent 部署到生產環境的流程。
- 部署 AI Agent 到生產環境時可能遇到的常見錯誤與問題。
- 如何在保持 AI Agent 性能的同時管理成本。

## 學習目標

完成本課程後，您將能夠掌握以下內容：

- 提升生產環境中 AI Agent 系統的性能、成本效益及整體效能的技巧。
- 如何評估 AI Agent 及其運行系統。
- 部署 AI Agent 至生產環境時如何控制成本。

部署值得信賴的 AI Agent 至關重要。請參閱「Building Trustworthy AI Agents」課程以獲取更多相關資訊。

## 評估 AI Agents

在部署 AI Agent 的過程中（包括部署前、中、後），建立完善的評估系統至關重要。這能確保系統與您及用戶的目標保持一致。

要評估 AI Agent，不僅需要檢視 Agent 的輸出，還需要評估整個 AI Agent 所運行的系統。這包括但不限於：

- 初始模型請求。
- Agent 判斷用戶意圖的能力。
- Agent 判斷正確工具以完成任務的能力。
- 工具對 Agent 請求的回應。
- Agent 解讀工具回應的能力。
- 用戶對 Agent 回應的反饋。

這樣可以更模組化地識別需要改進的地方，並能更有效地監控模型、提示、工具及其他組件的變更影響。

## AI Agents 的常見問題及潛在解決方案

| **問題**                                     | **潛在解決方案**                                                                                |
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| AI Agent 任務執行不一致                     | - 優化給予 AI Agent 的提示；明確設定目標。
- 確認是否可以將任務分解為子任務，並由多個 Agent 處理。                                                                                |
| AI Agent 陷入持續迴圈                       | - 確保設置明確的終止條件，讓 Agent 知道何時停止流程。
- 對於需要推理與規劃的複雜任務，考慮使用專門針對推理任務的大型模型。                                                            |
| AI Agent 工具調用表現不佳                   | - 在 Agent 系統外測試並驗證工具的輸出結果。
- 優化工具的參數設置、提示及命名方式。                                                                                |
| 多 Agent 系統表現不一致                     | - 優化每個 Agent 的提示，確保它們具體且互相區分明確。
- 構建一個層級系統，使用「路由」或控制 Agent 來決定哪個 Agent 是適合的執行者。                                                |

## 成本管理

以下是一些管理 AI Agent 部署成本的策略：

- **緩存回應** - 辨識常見請求與任務，並在這些請求進入 Agent 系統前提供回應，是減少相似請求量的好方法。您甚至可以實現一個流程，利用更基本的 AI 模型來判斷某請求與緩存請求的相似程度。

- **使用較小的模型** - 小型語言模型 (SLMs) 在某些 Agent 用例中表現良好，且能顯著降低成本。如前所述，建立評估系統來判斷並比較小型模型與大型模型的效能，是了解小型模型在您的用例中表現的最佳方式。

- **使用路由模型** - 類似的策略是使用多樣化的模型和尺寸。您可以使用 LLM/SLM 或無伺服器函數，根據請求的複雜性將其路由到最適合的模型。這樣不僅能降低成本，還能確保在適當的任務上保持性能。

## 恭喜

這是「AI Agents for Beginners」課程的最後一課。

我們計劃根據回饋與這個快速發展的行業變化，持續新增課程內容，因此請隨時回來查看。

如果您想繼續學習並構建 AI Agent，歡迎加入 [Azure AI Community Discord](https://discord.gg/kzRShWzttr)。

我們在那裡舉辦工作坊、社群圓桌會議及「問我任何事」的活動。

此外，我們還有一個 Learn 資源集合，其中包含幫助您開始在生產環境中構建 AI Agent 的額外材料。

**免責聲明**:
本文件使用機器翻譯服務進行翻譯。我們努力確保準確性，但請注意，自動翻譯可能包含錯誤或不準確之處。應以原語言的原始文件為權威來源。對於關鍵資訊，建議尋求專業人工翻譯。我們對因使用此翻譯而引起的任何誤解或誤讀不承擔責任。


# 课程设置

## 简介

本课将讲解如何运行本课程的代码示例。

## 需求

- 一个 GitHub 账户
- Python 3.12+

## 克隆或派生此仓库

首先，请克隆或派生（Fork）GitHub 仓库。这将创建您自己的课程材料副本，方便您运行、测试和调整代码！

您可以通过点击此链接 [fork the repo](https://github.com/microsoft/ai-agents-for-beginners/fork) 来完成。

完成后，您将拥有如下所示的课程副本：

![Forked Repo](../../../translated_images/forked-repo.eea246a73044cc984a1e462349e36e7336204f00785e3187b7399905feeada07.zh.png)

## 获取您的 GitHub 个人访问令牌 (PAT)

目前，本课程使用 GitHub Models Marketplace 提供对大语言模型（LLMs）的免费访问，这些模型将用于创建 AI Agent。

要访问此服务，您需要创建一个 GitHub 个人访问令牌。

您可以在 GitHub 账户的 [Personal Access Tokens settings](https://github.com/settings/personal-access-tokens) 页面创建。

在屏幕左侧选择 `Fine-grained tokens` 选项。

然后选择 `Generate new token`。

![Generate Token](../../../translated_images/generate-token.361ec40abe59b84ac68d63c23e2b6854d6fad82bd4e41feb98fc0e6f030e8ef7.zh.png)

复制您刚刚创建的新令牌。接下来，您需要将此令牌添加到课程中的 `.env` 文件中。

## 添加到您的环境变量中

要创建 `.env` 文件，请在终端中运行以下命令：

```bash
cp .env.example .env
```

此命令会复制示例文件并在您的目录中创建一个 `.env` 文件。

打开该文件，并将您创建的令牌粘贴到 .env 文件中的 `GITHUB_TOKEN=` 字段。

## 安装所需的依赖包

为了确保您拥有运行代码所需的所有 Python 依赖包，请在终端中运行以下命令。

我们建议创建一个 Python 虚拟环境，以避免潜在的冲突和问题。

```bash
pip install -r requirements.txt
```

此命令将安装所需的 Python 包。

现在，您已经准备好运行本课程的代码了，祝您在 AI Agent 世界的学习中玩得开心！

如果在设置过程中遇到任何问题，请加入我们的 [Azure AI Community Discord](https://discord.gg/kzRShWzttr) 或 [创建一个问题](https://github.com/microsoft/ai-agents-for-beginners/issues?WT.mc_id=academic-105485-koreyst)。

**免责声明**：
本文件使用基于机器的人工智能翻译服务进行翻译。虽然我们努力确保准确性，但请注意，自动翻译可能包含错误或不准确之处。应以原始语言的文件为权威来源。对于关键信息，建议寻求专业人工翻译。因使用本翻译而引起的任何误解或误读，我们概不负责。


# AI代理和应用场景简介

欢迎参加“AI 代理入门”课程！本课程将为您提供构建 AI 代理的基础知识和实践示例。

加入 [Azure AI Discord 社区](https://discord.gg/kzRShWzttr)，与其他学习者和 AI 代理构建者交流，并提出您在课程中遇到的任何问题。

为了开始这门课程，我们将首先更好地理解什么是 AI 代理，以及如何在我们构建的应用程序和工作流中使用它们。

## 课程简介

本节课程内容包括：

- 什么是 AI 代理？有哪些不同类型的代理？
- AI 代理适用于哪些用例？它们如何帮助我们？
- 设计代理解决方案时需要了解的基本构建块有哪些？

## 学习目标

完成本节课程后，您将能够：

- 理解 AI 代理的概念及其与其他 AI 解决方案的区别。
- 高效应用 AI 代理。
- 为用户和客户高效设计代理解决方案。

## 定义 AI 代理及其类型

### 什么是 AI 代理？

AI代理是通过为 **大语言模型（LLMs）** 提供 **工具** 和 **知识** 的访问权限，从而扩展其能力以 **执行操作** 的 **系统**。

我们将这一定义拆解为几个部分：

- **系统** - 需要将代理视为由多个组件组成的系统，而不是单一组件。AI代理的基本组件包括：
  - **环境** - 定义 AI 代理运行的空间。例如，如果我们有一个旅游预订 AI 代理，环境可能是 AI 代理用于完成任务的旅游预订系统。
  - **传感器** - 环境提供信息和反馈。AI 代理使用传感器来收集和解释有关环境当前状态的信息。在旅游预订代理的例子中，旅游预订系统可以提供酒店可用性或航班价格等信息。
  - **执行器** - 一旦 AI 代理接收到环境的当前状态信息，它会根据当前任务决定执行什么操作以改变环境。例如，旅游预订代理可能为用户预订一个可用的房间。

![什么是AI代理？](../../../translated_images/what-are-ai-agents.125520f55950b252a429b04a9f41e0152d4dafa1f1bd9081f4f574631acb759e.zh.png?WT.mc_id=academic-105485-koreyst)

**大语言模型** - 在大语言模型出现之前，代理的概念已经存在。利用 LLMs 构建AI 代理的优势在于它们能够解释人类语言和数据。这种能力使 LLMs 能够解释环境信息并制定改变环境的计划。

**执行操作** - 在 AI 代理系统之外，LLMs 的操作通常仅限于根据用户提示生成内容或信息。在AI代理系统中，LLMs 可以通过解释用户请求并利用环境中可用的工具来完成任务。

**工具访问** - LLM 可以访问哪些工具由两个因素决定：1）它运行的环境；2）AI代理开发者。例如，在旅游代理的例子中，代理的工具可能仅限于预订系统中的操作，或者开发者可以限制代理的工具访问权限，仅限于航班预订。

**知识** - 除了环境提供的信息外，AI 代理还可以从其他系统、服务、工具，甚至其他代理中检索知识。在旅游代理的例子中，这些知识可能包括存储在客户数据库中的用户旅游偏好信息。

### 不同类型的代理

现在我们已经了解了 AI 代理的一般定义，让我们来看一些具体的代理类型，以及它们如何应用于旅游预订 AI 代理。

| **代理类型**                   | **描述**                                                                                | **示例**                                                                                |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **简单反射代理**              | 根据预定义规则执行即时操作。                                                                                | 旅游代理解析邮件上下文并将旅行投诉转发给客户服务部门。                                                                                |
| **基于模型的反射代理**        | 根据世界模型及其变化执行操作。                                                                                | 旅游代理根据历史价格数据的访问优先考虑价格变化显著的路线。                                                                                |
| **基于目标的代理**            | 通过解释目标并决定实现目标的操作来创建计划。                                                                                | 旅游代理通过确定从当前位置到目的地所需的旅行安排（如汽车、公共交通、航班）来预订行程。                                                                                |
| **基于效用的代理**            | 考虑偏好并通过数值权衡如何实现目标。                                                                                | 旅游代理在预订旅行时，通过权衡便利性与成本来最大化效用。                                                                                |
| **学习型代理**                | 通过响应反馈并相应调整操作来随着时间推移不断改进。                                                                               | 旅游代理通过使用客户在行程结束后的反馈调查结果来调整未来的预订，从而不断改进。                                                                                |
| **分层代理**                  | 包含多级代理系统，高级代理将任务分解为子任务，由低级代理完成。                                                                    | 旅游代理通过将取消行程的任务分解为子任务（如取消特定预订）并让低级代理完成这些任务，再向高级代理汇报完成情况。                                                                                |
| **多代理系统（MAS）**         | 代理可以独立完成任务，无论是合作还是竞争。                                                                                | 合作：多个代理分别预订特定的旅行服务，如酒店、航班和娱乐活动。竞争：多个代理管理并竞争共享的酒店预订日历，为客户预订酒店。                                                                                |

## 何时使用 AI 代理

在前面的部分中，我们使用旅游代理的用例解释了如何在不同的旅行预订场景中使用不同类型的代理。在整个课程中，我们将继续使用这一应用。

让我们来看一下 AI 代理最适合使用的用例类型：

![何时使用AI代理？](../../../translated_images/when-to-use-ai-agents.912b9a02e9e0e2af45a3e24faa4e912e334ec23f21f0cf5cb040b7e899b09cd0.zh.png?WT.mc_id=academic-105485-koreyst)

- **开放性问题** - 允许 LLM 决定完成任务所需的步骤，因为这些步骤无法始终硬编码到工作流中。
- **多步骤流程** - 需要一定复杂度的任务，AI 代理需要在多个回合中使用工具或信息，而不是单次检索。
- **逐步改进** - 代理可以通过从环境或用户接收反馈来改进，以提供更好的效用。

在“构建可信的 AI 代理”课程中，我们将进一步探讨使用AI代理的考虑因素。

## 代理解决方案的基础知识

### 代理开发

设计 AI 代理系统的第一步是定义工具、操作和行为。在本课程中，我们重点使用 **Azure AI Agent Service** 来定义我们的代理。它提供以下功能：

- 选择开放模型，如 OpenAI、Mistral 和 Llama
- 使用提供商（如 Tripadvisor ）提供的授权数据
- 使用标准化的 OpenAPI 3.0 工具

### 代理模式

与 LLM 的通信是通过提示完成的。鉴于 AI 代理的半自主特性，在环境发生变化后，手动重新提示 LLM 并非总是必要或可行。我们使用 **代理模式**，以更可扩展的方式在多个步骤中提示 LLM。

本课程分为当前流行的几种代理模式。

### 代理框架

代理框架允许开发者通过代码实现代理模式。这些框架提供模板、插件和工具，以促进AI 代理的协作。这些优势为 AI 代理系统提供了更好的可观察性和故障排除能力。

在本课程中，我们将探讨以研究为驱动的 AutoGen 框架，以及 Semantic Kernel 提供的面向生产的 Agent 框架。

**免责声明**：
本文件使用基于机器的人工智能翻译服务进行翻译。尽管我们努力确保准确性，但请注意，自动翻译可能包含错误或不准确之处。应以原始语言的文件作为权威来源。对于关键信息，建议寻求专业人工翻译。我们对于因使用此翻译而产生的任何误解或错误解读不承担责任。


# 探索 AI Agent 框架

AI Agent 框架是专为简化 AI Agent 的创建、部署和管理而设计的软件平台。这些框架为开发者提供了预构建的组件、抽象和工具，从而简化了复杂 AI 系统的开发流程。

通过为 AI Agent 开发中的常见挑战提供标准化的方法，这些框架帮助开发者专注于应用的独特部分。它们提升了构建 AI 系统的可扩展性、可访问性和效率。

## 简介

本课程将涵盖以下内容：

- 什么是 AI Agent 框架？它能让开发者实现什么？
- 团队如何利用这些框架快速原型设计、迭代并提升 Agent 的能力？
- 微软开发的框架和工具（[Autogen](https://aka.ms/ai-agents/autogen) / [Semantic Kernel](https://aka.ms/ai-agents-beginners/semantic-kernel) / [Azure AI Agent Service](https://aka.ms/ai-agents-beginners/ai-agent-service)）之间有什么区别？
- 我可以直接集成现有的 Azure 生态系统工具，还是需要独立的解决方案？
- 什么是 Azure AI Agent Service？它如何帮助我？

## 学习目标

本课程的目标是帮助你理解：

- AI Agent 框架在 AI 开发中的作用。
- 如何利用 AI Agent 框架构建智能 Agent。
- AI Agent 框架所支持的关键功能。
- Autogen、Semantic Kernel 和 Azure AI Agent Service 之间的差异。

## 什么是 AI Agent 框架？它能让开发者实现什么？

传统的 AI 框架可以帮助你将 AI 集成到应用中，并通过以下方式提升应用性能：

- **个性化**：AI 可以分析用户行为和偏好，提供个性化的推荐、内容和体验。
  示例：流媒体服务（如 Netflix）利用 AI 根据观看历史推荐电影和节目，从而提升用户参与度和满意度。
- **自动化和效率**：AI 能够自动化重复性任务、优化工作流程并提高运营效率。
  示例：客户服务应用利用 AI 驱动的聊天机器人处理常见查询，从而减少响应时间，并将人类员工解放出来处理更复杂的问题。
- **增强用户体验**：AI 可以通过语音识别、自然语言处理和预测性文本等智能功能提升整体用户体验。
  示例：虚拟助手（如 Siri 和 Google Assistant）利用 AI 理解并响应语音命令，使用户更容易与设备互动。

### 听起来很棒，对吧？那么为什么我们还需要 AI Agent 框架？

AI Agent 框架不仅仅是 AI 框架。它们旨在支持创建能够与用户、其他 Agent 和环境交互以实现特定目标的智能 Agent。这些 Agent 可以表现出自主行为、做出决策并适应变化的条件。以下是 AI Agent 框架所支持的一些关键功能：

- **Agent 协作与协调**：支持创建多个 AI Agent，能够协作、沟通并协调以解决复杂任务。
- **任务自动化与管理**：提供自动化多步骤工作流、任务分配和动态任务管理的机制。
- **上下文理解与适应**：使 Agent 具备理解上下文、适应变化的环境并基于实时信息做出决策的能力。

总结来说，Agent 让你可以做得更多，提升自动化水平，创建能够从环境中学习和适应的更智能的系统。

## 如何快速原型设计、迭代并提升 Agent 的能力？

这是一个快速发展的领域，但大多数 AI Agent 框架都具备一些共性，可以帮助你快速原型设计和迭代，主要包括模块化组件、协作工具和实时学习。让我们深入探讨这些内容：

- **使用模块化组件**：AI 框架提供预构建的组件，例如提示、解析器和内存管理。
- **利用协作工具**：为 Agent 设计特定的角色和任务，测试并优化协作工作流。
- **实时学习**：实现反馈循环，使 Agent 从交互中学习并动态调整行为。

### 使用模块化组件

像 LangChain 和 Microsoft Semantic Kernel 这样的框架提供了预构建的组件，例如提示、解析器和内存管理。

**团队如何使用这些组件**：团队可以快速组装这些组件，创建一个功能性原型，而无需从头开始，从而实现快速实验和迭代。

**实际工作原理**：你可以使用预构建的解析器从用户输入中提取信息、使用内存模块存储和检索数据，并使用提示生成器与用户交互，而无需从头构建这些组件。

**示例代码**：以下是一个使用预构建解析器从用户输入中提取信息的示例：

```python
from langchain import Parser

parser = Parser()
user_input = "Book a flight from New York to London on July 15th"

parsed_data = parser.parse(user_input)

print(parsed_data)
# Output: {'origin': 'New York', 'destination': 'London', 'date': 'July 15th'}
```

从这个示例中可以看出，你可以利用预构建的解析器从用户输入中提取关键信息，例如航班预订请求的出发地、目的地和日期。这种模块化方法使你可以专注于高层逻辑。

### 利用协作工具

像 CrewAI 和 Microsoft Autogen 这样的框架可以帮助创建能够协作的多个 Agent。

**团队如何使用这些工具**：团队可以为 Agent 设计特定的角色和任务，从而测试和优化协作工作流，提高整体系统效率。

**实际工作原理**：你可以创建一个 Agent 团队，其中每个 Agent 都有特定的功能，例如数据检索、分析或决策。这些 Agent 可以通过通信和信息共享来实现共同目标，例如回答用户查询或完成任务。

**示例代码（Autogen）**：

```python
# creating agents, then create a round robin schedule where they can work together, in this case in order

# Data Retrieval Agent
# Data Analysis Agent
# Decision Making Agent

agent_retrieve = AssistantAgent(
    name="dataretrieval",
    model_client=model_client,
    tools=[retrieve_tool],
    system_message="Use tools to solve tasks."
)

agent_analyze = AssistantAgent(
    name="dataanalysis",
    model_client=model_client,
    tools=[analyze_tool],
    system_message="Use tools to solve tasks."
)

# conversation ends when user says "APPROVE"
termination = TextMentionTermination("APPROVE")

user_proxy = UserProxyAgent("user_proxy", input_func=input)

team = RoundRobinGroupChat([agent_retrieve, agent_analyze, user_proxy], termination_condition=termination)

stream = team.run_stream(task="Analyze data", max_turns=10)
# Use asyncio.run(...) when running in a script.
await Console(stream)
```

上述代码展示了如何创建一个任务，该任务涉及多个 Agent 协作分析数据。每个 Agent 执行特定功能，通过协调这些 Agent 来实现预期结果。通过为每个 Agent 分配专门的角色，可以提升任务效率和性能。

### 实时学习

高级框架提供了实时上下文理解和适应的能力。

**团队如何使用这些能力**：团队可以实现反馈循环，使 Agent 从交互中学习并动态调整行为，从而不断改进和优化功能。

**实际工作原理**：Agent 可以分析用户反馈、环境数据和任务结果，更新知识库、调整决策算法并随着时间的推移提升性能。这种迭代学习过程使 Agent 能够适应变化的条件和用户偏好，从而增强整体系统的有效性。

## Autogen、Semantic Kernel 和 Azure AI Agent Service 框架之间的差异是什么？

可以通过多种方式比较这些框架，但我们将从设计、功能和目标使用场景的角度来分析它们的主要区别：

### Autogen

由 Microsoft Research 的 AI Frontiers Lab 开发的开源框架，专注于事件驱动的分布式 *agentic* 应用，支持多个 LLM 和 SLM、工具以及高级多 Agent 设计模式。

Autogen 的核心理念是基于 Agent，这些 Agent 是可以感知环境、做出决策并采取行动以实现特定目标的自主实体。Agent 通过异步消息进行通信，使它们能够独立并行工作，从而增强系统的可扩展性和响应性。

Agent 基于 [Actor 模型](https://en.wikipedia.org/wiki/Actor_model)。根据 Wikipedia 的定义，Actor 是 _并发计算的基本构建块。Actor 在接收到消息时，可以：做出本地决策、创建更多 Actor、发送更多消息以及决定如何响应接收到的下一条消息_。

**使用场景**：自动化代码生成、数据分析任务，以及为规划和研究功能构建自定义 Agent。

Autogen 的一些核心概念包括：

- **Agent**：Agent 是一个软件实体，能够：
  - **通过消息通信**，这些消息可以是同步的或异步的。
  - **维护自己的状态**，状态可以通过接收到的消息进行修改。
  - **执行操作**，这些操作可能会修改 Agent 的状态并产生外部效果，例如更新消息日志、发送新消息、执行代码或进行 API 调用。

  以下是一个创建具有聊天功能的 Agent 的简短代码片段：

    ```python
    from autogen_agentchat.agents import AssistantAgent
    from autogen_agentchat.messages import TextMessage
    from autogen_ext.models.openai import OpenAIChatCompletionClient

    class MyAssistant(RoutedAgent):
        def __init__(self, name: str) -> None:
            super().__init__(name)
            model_client = OpenAIChatCompletionClient(model="gpt-4o")
            self._delegate = AssistantAgent(name, model_client=model_client)

        @message_handler
        async def handle_my_message_type(self, message: MyMessageType, ctx: MessageContext) -> None:
            print(f"{self.id.type} received message: {message.content}")
            response = await self._delegate.on_messages(
                [TextMessage(content=message.content, source="user")], ctx.cancellation_token
            )
            print(f"{self.id.type} responded: {response.chat_message.content}")
    ```

    在上述代码中，`MyAssistant` has been created and inherits from `RoutedAgent`. It has a message handler that prints the content of the message and then sends a response using the `AssistantAgent` delegate. Especially note how we assign to `self._delegate` an instance of `AssistantAgent` 是一个预构建的 Agent，能够处理聊天完成任务。

  接下来，让 Autogen 知道这种 Agent 类型并启动程序：

    ```python

    # main.py
    runtime = SingleThreadedAgentRuntime()
    await MyAgent.register(runtime, "my_agent", lambda: MyAgent())

    runtime.start()  # Start processing messages in the background.
    await runtime.send_message(MyMessageType("Hello, World!"), AgentId("my_agent", "default"))
    ```

    在上述代码中，Agent 被注册到运行时，并向 Agent 发送了一条消息，产生如下输出：

    ```text
    # Output from the console:
    my_agent received message: Hello, World!
    my_assistant received message: Hello, World!
    my_assistant responded: Hello! How can I assist you today?
    ```

- **多 Agent 支持**：Autogen 支持创建多个 Agent，它们可以协作以更高效地解决复杂任务。通过定义具有专门功能和角色的不同类型的 Agent，例如数据检索、分析、决策和用户交互，可以创建一个多 Agent 系统。以下是一个这样的创建示例：

    ```python
    editor_description = "Editor for planning and reviewing the content."

    # Example of declaring an Agent
    editor_agent_type = await EditorAgent.register(
    runtime,
    editor_topic_type,  # Using topic type as the agent type.
    lambda: EditorAgent(
        description=editor_description,
        group_chat_topic_type=group_chat_topic_type,
        model_client=OpenAIChatCompletionClient(
            model="gpt-4o-2024-08-06",
            # api_key="YOUR_API_KEY",
        ),
        ),
    )

    # remaining declarations shortened for brevity

    # Group chat
    group_chat_manager_type = await GroupChatManager.register(
    runtime,
    "group_chat_manager",
    lambda: GroupChatManager(
        participant_topic_types=[writer_topic_type, illustrator_topic_type, editor_topic_type, user_topic_type],
        model_client=OpenAIChatCompletionClient(
            model="gpt-4o-2024-08-06",
            # api_key="YOUR_API_KEY",
        ),
        participant_descriptions=[
            writer_description,
            illustrator_description,
            editor_description,
            user_description
        ],
        ),
    )
    ```

    上述代码中，我们有一个 `GroupChatManager`，它被注册到运行时。此管理器负责协调不同类型 Agent（如撰稿人、插画师、编辑和用户）之间的交互。

- **Agent 运行时**：框架提供了一个运行时环境，用于支持 Agent 之间的通信、管理其身份和生命周期，并执行安全和隐私边界。这意味着你可以在一个安全且受控的环境中运行 Agent，确保它们能够安全高效地交互。以下是两种运行时的介绍：
  - **独立运行时**：适用于单进程应用，其中所有 Agent 都用同一种编程语言实现并运行在同一进程中。以下是其工作原理的示意图：

    ![独立运行时](https://microsoft.github.io/autogen/stable/_images/architecture-standalone.svg)
    应用栈

    *Agent 通过运行时通过消息进行通信，运行时管理 Agent 的生命周期。*

  - **分布式运行时**：适用于多进程应用，其中 Agent 可以用不同的编程语言实现并运行在不同的机器上。以下是其工作原理的示意图：

    ![分布式运行时](https://microsoft.github.io/autogen/stable/_images/architecture-distributed.svg)

### Semantic Kernel + Agent Framework

Semantic Kernel 包含两部分：Semantic Kernel Agent Framework 和 Semantic Kernel 本身。

先谈谈 Semantic Kernel 的核心概念：

- **连接**：与外部 AI 服务和数据源的接口。

    ```csharp
    using Microsoft.SemanticKernel;

    // Create kernel
    var builder = Kernel.CreateBuilder();

    // Add a chat completion service:
    builder.Services.AddAzureOpenAIChatCompletion(
        "your-resource-name",
        "your-endpoint",
        "your-resource-key",
        "deployment-model");
    var kernel = builder.Build();
    ```

    这里是一个简单的示例，展示了如何创建一个 Kernel 并添加一个聊天完成服务。Semantic Kernel 创建了一个与外部 AI 服务（此处为 Azure OpenAI Chat Completion）的连接。

- **插件**：封装了应用程序可以使用的功能。既有现成的插件，也可以创建自定义插件。这里还有一个“语义函数”的概念。之所以称为语义函数，是因为你提供了语义信息，帮助 Semantic Kernel 决定需要调用该函数。以下是一个示例：

    ```csharp
    var userInput = Console.ReadLine();

    // Define semantic function inline.
    string skPrompt = @"Summarize the provided unstructured text in a sentence that is easy to understand.
                        Text to summarize: {{$userInput}}";

    // Register the function
    kernel.CreateSemanticFunction(
        promptTemplate: skPrompt,
        functionName: "SummarizeText",
        pluginName: "SemanticFunctions"
    );
    ```

    在此示例中，你首先有一个模板提示 `skPrompt` that leaves room for the user to input text, `$userInput`. Then you register the function `SummarizeText` with the plugin `SemanticFunctions`。注意函数的名称，它帮助 Semantic Kernel 理解该函数的用途以及何时应该调用它。

- **本地函数**：框架还可以直接调用本地函数来执行任务。以下是一个检索文件内容的本地函数示例：

    ```csharp
    public class NativeFunctions {

        [SKFunction, Description("Retrieve content from local file")]
        public async Task<string> RetrieveLocalFile(string fileName, int maxSize = 5000)
        {
            string content = await File.ReadAllTextAsync(fileName);
            if (content.Length <= maxSize) return content;
            return content.Substring(0, maxSize);
        }
    }

    //Import native function
    string plugInName = "NativeFunction";
    string functionName = "RetrieveLocalFile";

    var nativeFunctions = new NativeFunctions();
    kernel.ImportFunctions(nativeFunctions, plugInName);
    ```

- **规划器**：规划器根据用户输入协调执行计划和策略。规划器的作用是表达任务的执行方式，然后作为 Semantic Kernel 的执行指令。它随后调用必要的函数来完成任务。以下是一个计划示例：

    ```csharp
    string planDefinition = "Read content from a local file and summarize the content.";
    SequentialPlanner sequentialPlanner = new SequentialPlanner(kernel);

    string assetsFolder = @"../../assets";
    string fileName = Path.Combine(assetsFolder,"docs","06_SemanticKernel", "aci_documentation.txt");

    ContextVariables contextVariables = new ContextVariables();
    contextVariables.Add("fileName", fileName);

    var customPlan = await sequentialPlanner.CreatePlanAsync(planDefinition);

    // Execute the plan
    KernelResult kernelResult = await kernel.RunAsync(contextVariables, customPlan);
    Console.WriteLine($"Summarization: {kernelResult.GetValue<string>()}");
    ```

    特别注意 `planDefinition` which is a simple instruction for the planner to follow. The appropriate functions are then called based on this plan, in this case our semantic function `SummarizeText` and the native function `RetrieveLocalFile`。
- **内存**：抽象并简化 AI 应用的上下文管理。内存的概念是 LLM 应该了解的信息。你可以将这些信息存储在向量存储中，最终可以是内存数据库、向量数据库或类似数据库。以下是一个非常简化的场景示例，其中将 *事实* 添加到内存中：

    ```csharp
    var facts = new Dictionary<string,string>();
    facts.Add(
        "Azure Machine Learning; https://learn.microsoft.com/azure/machine-learning/",
        @"Azure Machine Learning is a cloud service for accelerating and
        managing the machine learning project lifecycle. Machine learning professionals,
        data scientists, and engineers can use it in their day-to-day workflows"
    );

    facts.Add(
        "Azure SQL Service; https://learn.microsoft.com/azure/azure-sql/",
        @"Azure SQL is a family of managed, secure, and intelligent products
        that use the SQL Server database engine in the Azure cloud."
    );

    string memoryCollectionName = "SummarizedAzureDocs";

    foreach (var fact in facts) {
        await memoryBuilder.SaveReferenceAsync(
            collection: memoryCollectionName,
            description: fact.Key.Split(";")[1].Trim(),
            text: fact.Value,
            externalId: fact.Key.Split(";")[2].Trim(),
            externalSourceName: "Azure Documentation"
        );
    }
    ```

    这些事实随后存储在内存集合 `SummarizedAzureDocs` 中。这是一个非常简化的示例，但你可以看到如何将信息存储到内存中供 LLM 使用。

这就是 Semantic Kernel 框架的基础知识，那么它的 Agent Framework 是什么？

### Azure AI Agent Service

Azure AI Agent Service 是一个较新的补充，于 Microsoft Ignite 2024 上推出。它支持开发和部署更灵活的 AI Agent，例如直接调用开源 LLM（如 Llama 3、Mistral 和 Cohere）。

Azure AI Agent Service 提供更强的企业安全机制和数据存储方法，非常适合企业应用。

它可以与 Autogen 和 Semantic Kernel 等多 Agent 协作框架无缝协作。

该服务目前处于公测阶段，支持用 Python 和 C# 构建 Agent。

#### 核心概念

Azure AI Agent Service 的核心概念包括：

- **Agent**：Azure AI Agent Service 与 Azure AI Foundry 集成。在 AI Foundry 中，AI Agent 充当“智能”微服务，可以用于回答问题（RAG）、执行操作或完全自动化工作流。它通过结合生成式 AI 模型的能力与访问和交互真实数据源的工具实现这些目标。以下是一个 Agent 示例：

    ```python
    agent = project_client.agents.create_agent(
        model="gpt-4o-mini",
        name="my-agent",
        instructions="You are helpful agent",
        tools=code_interpreter.definitions,
        tool_resources=code_interpreter.resources,
    )
    ```

    在此示例中，创建了一个模型为 `gpt-4o-mini`, a name `my-agent`, and instructions `You are helpful agent` 的 Agent。该 Agent 配备了工具和资源，用于执行代码解释任务。

- **线程和消息**：线程是另一个重要概念。它表示 Agent 和用户之间的对话或交互。线程可用于跟踪对话进度、存储上下文信息以及管理交互的状态。以下是一个线程示例：

    ```python
    thread = project_client.agents.create_thread()
    message = project_client.agents.create_message(
        thread_id=thread.id,
        role="user",
        content="Could you please create a bar chart for the operating profit using the following data and provide the file to me? Company A: $1.2 million, Company B: $2.5 million, Company C: $3.0 million, Company D: $1.8 million",
    )

    # Ask the agent to perform work on the thread
    run = project_client.agents.create_and_process_run(thread_id=thread.id, agent_id=agent.id)

    # Fetch and log all messages to see the agent's response
    messages = project_client.agents.list_messages(thread_id=thread.id)
    print(f"Messages: {messages}")
    ```

    在上述代码中，创建了一个线程。然后向线程发送了一条消息。通过调用 `create_and_process_run`，要求 Agent 在该线程上执行任务。最后，获取并记录消息以查看 Agent 的响应。这些消息表明用户与 Agent 之间对话的进展。还需要注意的是，消息可以是文本、图像或文件等不同类型，例如 Agent 的工作结果可能是图像或文本响应。作为开发者，你可以利用这些信息进一步处理响应或将其呈现给用户。

- **与其他 AI 框架集成**：Azure AI Agent Service 可以与其他框架（如 Autogen 和 Semantic Kernel）交互，这意味着你可以在这些框架之一中构建应用的一部分，并例如将 Agent Service 用作协调器，或者完全使用 Agent Service 构建应用。

**使用场景**：Azure AI Agent Service 专为需要安全、可扩展且灵活的 AI Agent 部署的企业应用设计。

## 这些框架之间的区别是什么？

虽然这些框架之间似乎有很多重叠，但在设计、功能和目标使用场景方面，它们仍然有一些关键区别：

- **Autogen**：专注于事件驱动的分布式 Agentic 应用，支持多个 LLM 和 SLM、工具以及高级多 Agent 设计模式。
- **Semantic Kernel**：专注于理解和生成类人文本内容，通过捕捉更深层次的语义意义来实现。它旨在自动化复杂的工作流并根据项目目标启动任务。
- **Azure AI Agent Service**：提供更灵活的模型，例如直接调用开源 LLM（如 Llama 3、Mistral 和 Cohere）。它提供更强的企业安全机制和数据存储方法，非常适合企业应用。

仍然不确定该选择哪个？

### 使用场景

让我们通过一些常见的使用场景来帮助你选择：

> **问**：我的团队正在开发一个项目，涉及自动化代码生成和数据分析任务。我们应该选择哪个框架？
>
> **答**：Autogen 是一个不错的选择，因为它专注于事件驱动的分布式 Agentic 应用，并支持高级多 Agent 设计模式。

> **问**：在这个使用场景中，Autogen 比 Semantic Kernel 和 Azure AI Agent Service 更好的原因是什么？
>
> **答**：Autogen 专为事件驱动的分布式 Agentic 应用设计，非常适合自动化代码生成和数据分析任务。它提供了必要的工具和功能，可以高效地构建复杂的多 Agent 系统。

> **问**：听起来 Azure AI Agent Service 也适合这个场景，它也有代码生成工具，对吗？
>
> **答**：是的，Azure AI Agent Service 也支持代码生成和数据分析任务，但它可能更适合需要安全、可扩展且灵活的 AI Agent 部署的企业应用。Autogen 更专注于事件驱动的分布式 Agentic 应用和高级多 Agent 设计模式。

> **问**：所以你的意思是，如果我想要企业级的解决方案，我应该选择 Azure AI Agent Service？
>
> **答**：是的，Azure AI Agent Service 专为需要安全、可扩展且灵活的 AI Agent 部署的企业应用设计。它提供更强的企业安全机制和数据存储方法，非常适合企业使用场景。

### 总结关键差异表格

| 框架             | 重点                         | 核心概念                     | 使用场景                     |
| ---------------- | ---------------------------- | ---------------------------- | ---------------------------- |
| Autogen          | 事件驱动的分布式 Agentic 应用 | Agent、角色、功能、数据       | 代码生成、数据分析任务       |
| Semantic Kernel  | 理解和生成类人文本内容        | Agent、模块化组件、协作       | 自然语言理解、内容生成       |
| Azure AI Agent Service | 灵活的模型、企业安全、工具调用 | 模块化、协作、流程协调         | 安全、可扩
根据项目目标。适用于自然语言理解、内容生成。
- **Azure AI Agent Service**：灵活的模型、企业级安全机制、数据存储方法。非常适合在企业应用中实现安全、可扩展和灵活的 AI 代理部署。

## 我可以直接集成现有的 Azure 生态系统工具，还是需要独立的解决方案？
答案是肯定的，您可以将现有的 Azure 生态系统工具直接与 Azure AI Agent Service 集成，尤其是因为它已被设计为能够与其他 Azure 服务无缝协作。例如，您可以集成 Bing、Azure AI Search 和 Azure Functions。此外，它还与 Azure AI Foundry 有深度集成。

对于 Autogen 和 Semantic Kernel，您也可以与 Azure 服务集成，但可能需要从代码中调用 Azure 服务。另一种集成方式是使用 Azure SDK，通过您的代理与 Azure 服务交互。此外，如前所述，您可以使用 Azure AI Agent Service 作为在 Autogen 或 Semantic Kernel 中构建的代理的协调器，这将使您轻松访问 Azure 生态系统。

## 参考
- [1] - [Azure Agent Service](https://techcommunity.microsoft.com/blog/azure-ai-services-blog/introducing-azure-ai-agent-service/4298357)
- [2] - [Semantic Kernel and Autogen](https://devblogs.microsoft.com/semantic-kernel/microsofts-agentic-ai-frameworks-autogen-and-semantic-kernel/)
- [3] - [Semantic Kernel Agent Framework](https://learn.microsoft.com/semantic-kernel/frameworks/agent/?pivots=programming-language-csharp)
- [4] - [Azure AI Agent service](https://learn.microsoft.com/azure/ai-services/agents/overview)
- [5] - [Using Azure AI Agent Service with AutoGen / Semantic Kernel to build a multi-agent's solution](https://techcommunity.microsoft.com/blog/educatordeveloperblog/using-azure-ai-agent-service-with-autogen--semantic-kernel-to-build-a-multi-agen/4363121)

**免责声明**:
本文档使用基于机器的人工智能翻译服务进行翻译。尽管我们努力确保准确性，但请注意，自动翻译可能包含错误或不准确之处。应以原文的母语版本为权威来源。对于关键信息，建议寻求专业人工翻译。因使用本翻译而引起的任何误解或误读，我们概不负责。


# AI 代理设计原则

## 简介

关于构建 AI 代理系统，有许多不同的思考方式。由于在生成式 AI 设计中，模糊性是一种特性而非缺陷，因此工程师有时会难以确定从哪里开始。我们制定了一套以人为中心的用户体验设计原则，旨在帮助开发者构建以客户为中心的代理系统，以满足他们的业务需求。这些设计原则并不是一种规定性的架构，而是为定义和构建代理体验的团队提供的起点。

一般来说，代理系统应该：

- 扩展和增强人类能力（如头脑风暴、解决问题、自动化等）
- 弥补知识空白（例如帮助快速了解某一知识领域、翻译等）
- 促进并支持我们个人偏好的协作方式
- 让我们成为更好的自己（例如，作为生活教练/任务管理者，帮助我们学习情绪调节和正念技巧，建立韧性等）

## 本课内容

- 什么是代理设计原则
- 实施这些设计原则时需要遵循的指导方针
- 使用这些设计原则的一些示例

## 学习目标

完成本课后，您将能够：

1. 解释什么是代理设计原则
2. 解释使用代理设计原则的指导方针
3. 理解如何使用代理设计原则构建一个代理

## 代理设计原则

![代理设计原则](../../../translated_images/agentic-design-principles.9f32a64bb6e2aa5a1bdffb70111aa724058bc248b1a3dd3c6661344015604cff.zh.png?WT.mc_id=academic-105485-koreyst)

### 代理（空间）

这是代理运行的环境。这些原则指导我们如何设计能够在物理和数字世界中互动的代理。

- **连接而非取代** – 帮助人们与其他人、事件和可操作的知识建立联系，从而促进协作和交流。
  - 代理帮助连接事件、知识和人。
  - 代理拉近人与人之间的距离，而不是取代或贬低人类。
- **易于访问但偶尔隐形** – 代理主要在后台运行，只有在相关且适当的时候才会提醒我们。
  - 代理可在任何设备或平台上轻松被授权用户发现和访问。
  - 代理支持多模态输入和输出（如声音、语音、文本等）。
  - 代理可以在前台与后台之间无缝切换；根据用户需求的感知，在主动和被动模式之间切换。
  - 代理可能以隐形形式运行，但其后台处理路径及与其他代理的协作对用户是透明且可控的。

### 代理（时间）

这是代理如何随着时间运作的方式。这些原则指导我们如何设计跨越过去、现在和未来的代理互动。

- **过去**：回顾包含状态和上下文的历史。
  - 代理通过分析丰富的历史数据（不仅仅是事件、人员或状态）提供更相关的结果。
  - 代理从过去的事件中创建连接，并积极反思记忆以应对当前情境。
- **现在**：更多地引导，而非简单通知。
  - 代理体现了一种全面的互动方式。当事件发生时，代理超越静态通知或其他形式化方式。代理可以简化流程或动态生成提示，在合适的时机引导用户注意。
  - 代理根据上下文环境、社会和文化变化以及用户意图提供信息。
  - 代理的互动可以是渐进的，随着时间的推移在复杂性上演变和成长，从而赋能用户。
- **未来**：适应和进化。
  - 代理适应各种设备、平台和模式。
  - 代理适应用户行为、无障碍需求，并可自由定制。
  - 代理通过持续的用户交互来塑造和进化。

### 代理（核心）

这些是代理设计核心中的关键要素。

- **接受不确定性但建立信任**。
  - 某种程度的代理不确定性是可以预期的。不确定性是代理设计的关键元素。
  - 信任和透明是代理设计的基础层。
  - 用户可以控制代理的开/关状态，并且代理的状态始终清晰可见。

## 实施这些原则的指导方针

在使用上述设计原则时，请遵循以下指导方针：

1. **透明性**：告知用户 AI 的参与方式及其工作原理（包括过去的操作），以及如何提供反馈和修改系统。
2. **控制权**：允许用户自定义、指定偏好和个性化，并对系统及其属性进行控制（包括遗忘功能）。
3. **一致性**：在设备和终端之间提供一致的多模态体验。尽量使用熟悉的 UI/UX 元素（例如，语音交互使用麦克风图标），并尽可能降低用户的认知负担（例如，提供简明的回复、视觉辅助和“了解更多”内容）。

## 如何使用这些原则和指导方针设计一个旅游代理

假设您正在设计一个旅游代理，以下是您可以如何应用设计原则和指导方针的思路：

1. **透明性** – 让用户知道这个旅游代理是由 AI 驱动的代理。提供一些基本的使用说明（例如，一条“你好”消息，示例提示）。在产品页面上清楚记录这一点。显示用户过去提出的提示列表。明确说明如何提供反馈（如点赞或点踩、发送反馈按钮等）。清楚说明代理是否存在使用或主题限制。
2. **控制权** – 确保用户可以清楚地了解如何修改已创建的代理，例如通过系统提示。允许用户选择代理的详细程度、写作风格，以及代理不应讨论的主题。让用户查看并删除任何相关文件或数据、提示以及过去的对话。
3. **一致性** – 确保用于分享提示、添加文件或照片、标记某人或某物的图标是标准且易于识别的。使用回形针图标表示文件上传/共享，使用图片图标表示上传图形。

## 其他资源
- [Practices for Governing Agentic AI Systems | OpenAI](https://openai.com)
- [The HAX Toolkit Project - Microsoft Research](https://microsoft.com)
- [Responsible AI Toolbox](https://responsibleaitoolbox.ai)

**免责声明**：
本文件使用基于机器的人工智能翻译服务进行翻译。尽管我们尽力确保准确性，但请注意，自动翻译可能包含错误或不准确之处。应以原始语言的文件为权威来源。对于关键信息，建议寻求专业人工翻译。对于因使用本翻译而引起的任何误解或误读，我们概不负责。


# 工具使用设计模式

## 简介

在本课程中，我们将探索以下问题：

- 什么是工具使用设计模式？
- 它可以应用于哪些使用场景？
- 实现这一设计模式需要哪些关键元素/构件？
- 使用工具使用设计模式构建可信赖的 AI 代理需要注意哪些特殊事项？

## 学习目标

完成本课程后，您将能够：

- 定义工具使用设计模式及其目的。
- 识别适用于工具使用设计模式的使用场景。
- 理解实现该设计模式所需的关键元素。
- 认识在使用此设计模式的 AI 代理中确保可信赖性需要考虑的因素。

## 什么是工具使用设计模式？

**工具使用设计模式**的核心是赋予大型语言模型（LLM）与外部工具交互的能力，以完成特定目标。工具是代理可以执行的代码，可以是简单的函数（如计算器），也可以是调用第三方服务的 API（如股票价格查询或天气预报）。在 AI 代理的上下文中，工具是设计用来响应**模型生成的函数调用**而执行的。

## 它可以应用于哪些使用场景？

AI 代理可以利用工具完成复杂任务、检索信息或做出决策。工具使用设计模式通常应用于需要动态与外部系统交互的场景，例如数据库、Web 服务或代码解释器。这种能力在以下多种场景中非常有用：

- **动态信息检索**：代理可以查询外部 API 或数据库以获取最新数据（例如，查询 SQLite 数据库进行数据分析、获取股票价格或天气信息）。
- **代码执行和解释**：代理可以执行代码或脚本来解决数学问题、生成报告或进行模拟。
- **工作流自动化**：通过集成任务调度器、电子邮件服务或数据管道等工具，自动化重复性或多步骤的工作流。
- **客户支持**：代理可以与 CRM 系统、工单平台或知识库交互，以解决用户问题。
- **内容生成与编辑**：代理可以利用语法检查器、文本摘要工具或内容安全评估器等工具，协助完成内容创建任务。

## 实现工具使用设计模式需要哪些元素/构件？

### 函数/工具调用

函数调用是使大型语言模型（LLM）能够与工具交互的主要方式。您会发现“函数”和“工具”这两个术语常常互换使用，因为“函数”（可重用代码块）就是代理用于执行任务的“工具”。为了让函数的代码能够被调用，LLM 需要将用户的请求与函数的描述进行匹配。为此，需要向 LLM 提供包含所有可用函数描述的架构。LLM 会选择最适合任务的函数，并返回其名称和参数。选定的函数被调用，其响应会发送回 LLM，LLM 再利用这些信息回复用户的请求。

要为代理实现函数调用，开发者需要：

1. 支持函数调用的 LLM 模型
2. 包含函数描述的架构
3. 每个描述中提到的函数代码

以下通过获取某城市当前时间的示例来说明：

- **初始化支持函数调用的 LLM：**

    并非所有模型都支持函数调用，因此需要确认您使用的 LLM 是否支持。[Azure OpenAI](https://learn.microsoft.com/azure/ai-services/openai/how-to/function-calling) 支持函数调用。我们可以从初始化 Azure OpenAI 客户端开始。

    ```python
    # Initialize the Azure OpenAI client
    client = AzureOpenAI(
        azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT"),
        api_key=os.getenv("AZURE_OPENAI_API_KEY"),
        api_version="2024-05-01-preview"
    )
    ```

- **创建函数架构：**

    接下来，我们将定义一个包含函数名称、功能描述以及参数名称和描述的 JSON 架构。然后将此架构与用户请求（例如查找旧金山的时间）一起传递给上述创建的客户端。需要注意的是，返回的是一个**工具调用**，而不是问题的最终答案。如前所述，LLM 返回其为任务选择的函数名称及其参数。

    ```python
    # Function description for the model to read
    tools = [
        {
            "type": "function",
            "function": {
                "name": "get_current_time",
                "description": "Get the current time in a given location",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "The city name, e.g. San Francisco",
                        },
                    },
                    "required": ["location"],
                },
            }
        }
    ]
    ```

    ```python

    # Initial user message
    messages = [{"role": "user", "content": "What's the current time in San Francisco"}]

    # First API call: Ask the model to use the function
      response = client.chat.completions.create(
          model=deployment_name,
          messages=messages,
          tools=tools,
          tool_choice="auto",
      )

      # Process the model's response
      response_message = response.choices[0].message
      messages.append(response_message)

      print("Model's response:")

      print(response_message)

    ```

    ```bash
    Model's response:
    ChatCompletionMessage(content=None, role='assistant', function_call=None, tool_calls=[ChatCompletionMessageToolCall(id='call_pOsKdUlqvdyttYB67MOj434b', function=Function(arguments='{"location":"San Francisco"}', name='get_current_time'), type='function')])
    ```

- **执行任务所需的函数代码：**

    现在，LLM 已经选择了需要运行的函数，接下来需要实现并执行完成任务的代码。我们可以用 Python 实现获取当前时间的代码，同时编写代码从 response_message 中提取函数名称和参数，以获得最终结果。

    ```python
      def get_current_time(location):
        """Get the current time for a given location"""
        print(f"get_current_time called with location: {location}")
        location_lower = location.lower()

        for key, timezone in TIMEZONE_DATA.items():
            if key in location_lower:
                print(f"Timezone found for {key}")
                current_time = datetime.now(ZoneInfo(timezone)).strftime("%I:%M %p")
                return json.dumps({
                    "location": location,
                    "current_time": current_time
                })

        print(f"No timezone data found for {location_lower}")
        return json.dumps({"location": location, "current_time": "unknown"})
    ```

    ```python
     # Handle function calls
      if response_message.tool_calls:
          for tool_call in response_message.tool_calls:
              if tool_call.function.name == "get_current_time":

                  function_args = json.loads(tool_call.function.arguments)

                  time_response = get_current_time(
                      location=function_args.get("location")
                  )

                  messages.append({
                      "tool_call_id": tool_call.id,
                      "role": "tool",
                      "name": "get_current_time",
                      "content": time_response,
                  })
      else:
          print("No tool calls were made by the model.")

      # Second API call: Get the final response from the model
      final_response = client.chat.completions.create(
          model=deployment_name,
          messages=messages,
      )

      return final_response.choices[0].message.content
     ```

    ```bash
      get_current_time called with location: San Francisco
      Timezone found for san francisco
      The current time in San Francisco is 09:24 AM.
     ```

函数调用是大多数代理工具使用设计的核心，但从零开始实现可能会有一定挑战。正如我们在 [第 2 课](../../../02-explore-agentic-frameworks) 中所学到的，代理框架为我们提供了预构建的模块，用于实现工具使用。

### 使用代理框架的工具使用示例

- ### **[Semantic Kernel](https://learn.microsoft.com/azure/ai-services/agents/overview)**

    Semantic Kernel 是一个面向 .NET、Python 和 Java 开发者的开源 AI 框架，专注于与大型语言模型（LLM）协作。它通过一个称为[序列化](https://learn.microsoft.com/semantic-kernel/concepts/ai-services/chat-completion/function-calling/?pivots=programming-language-python#1-serializing-the-functions)的过程，自动向模型描述函数及其参数，从而简化了函数调用的使用。此外，它还处理模型与代码之间的交互。使用像 Semantic Kernel 这样的代理框架的另一个好处是，它允许您访问预构建的工具，例如 [文件搜索](https://github.com/microsoft/semantic-kernel/blob/main/python/samples/getting_started_with_agents/openai_assistant/step4_assistant_tool_file_search.py) 和 [代码解释器](https://github.com/microsoft/semantic-kernel/blob/main/python/samples/getting_started_with_agents/openai_assistant/step3_assistant_tool_code_interpreter.py)。

    以下图示展示了使用 Semantic Kernel 进行函数调用的流程：

    ![函数调用](../../../translated_images/functioncalling-diagram.b5493ea5154ad8e3e4940d2e36a49101eec1398948e5d1039942203b4f5a4209.zh.png)

    在 Semantic Kernel 中，函数/工具被称为 [插件](https://learn.microsoft.com/semantic-kernel/concepts/plugins/?pivots=programming-language-python)。我们可以将 `get_current_time` function we saw earlier into a plugin by turning it into a class with the function in it. We can also import the `kernel_function` 装饰器用于函数描述。当您创建包含 GetCurrentTimePlugin 的内核时，内核会自动序列化函数及其参数，从而创建发送给 LLM 的架构。

    ```python
    from semantic_kernel.functions import kernel_function

    class GetCurrentTimePlugin:
        async def __init__(self, location):
            self.location = location

        @kernel_function(
            description="Get the current time for a given location"
        )
        def get_current_time(location: str = ""):
            ...

    ```

    ```python
    from semantic_kernel import Kernel

    # Create the kernel
    kernel = Kernel()

    # Create the plugin
    get_current_time_plugin = GetCurrentTimePlugin(location)

    # Add the plugin to the kernel
    kernel.add_plugin(get_current_time_plugin)
    ```

- ### **[Azure AI Agent Service](https://learn.microsoft.com/azure/ai-services/agents/overview)**

    Azure AI Agent Service 是一个较新的代理框架，旨在帮助开发者安全地构建、部署和扩展高质量、可扩展的 AI 代理，而无需管理底层的计算和存储资源。它特别适用于企业应用，因为它是一个具有企业级安全性的完全托管服务。

    与直接使用 LLM API 开发相比，Azure AI Agent Service 提供了一些优势，包括：
  - 自动工具调用——无需解析工具调用、调用工具以及处理响应；所有这些都在服务器端完成。
  - 安全管理数据——无需自行管理会话状态，您可以依赖线程存储所需的所有信息。
  - 开箱即用的工具——可用于与数据源交互的工具，例如 Bing、Azure AI 搜索和 Azure Functions。

    Azure AI Agent Service 中的工具可分为两类：

    1. 知识工具：
        - [通过 Bing 搜索进行信息获取](https://learn.microsoft.com/azure/ai-services/agents/how-to/tools/bing-grounding?tabs=python&pivots=overview)
        - [文件搜索](https://learn.microsoft.com/azure/ai-services/agents/how-to/tools/file-search?tabs=python&pivots=overview)
        - [Azure AI 搜索](https://learn.microsoft.com/azure/ai-services/agents/how-to/tools/azure-ai-search?tabs=azurecli%2Cpython&pivots=overview-azure-ai-search)

    2. 操作工具：
        - [函数调用](https://learn.microsoft.com/azure/ai-services/agents/how-to/tools/function-calling?tabs=python&pivots=overview)
        - [代码解释器](https://learn.microsoft.com/azure/ai-services/agents/how-to/tools/code-interpreter?tabs=python&pivots=overview)
        - [OpenAI 定义的工具](https://learn.microsoft.com/azure/ai-services/agents/how-to/tools/openapi-spec?tabs=python&pivots=overview)
        - [Azure Functions](https://learn.microsoft.com/azure/ai-services/agents/how-to/tools/azure-functions?pivots=overview)

    Agent Service 允许我们将这些工具组合为一个 `toolset`. It also utilizes `threads` which keep track of the history of messages from a particular conversation.

    Imagine you are a sales agent at a company called Contoso. You want to develop a conversational agent that can answer questions about your sales data.

    The image below illustrates how you could use Azure AI Agent Service to analyze your sales data:

    ![Agentic Service In Action](../../../translated_images/agent-service-in-action.8c2d8aa8e9d91feeb29549b3fde529f8332b243875154d03907616a69198afbc.zh.jpg?WT.mc_id=academic-105485-koreyst)

    To use any of these tools with the service we can create a client and define a tool or toolset. To implement this practically we can use the Python code below. The LLM will be able to look at the toolset and decide whether to use the user created function, `fetch_sales_data_using_sqlite_query`，或者根据用户请求使用预构建的代码解释器。

    ```python
    import os
    from azure.ai.projects import AIProjectClient
    from azure.identity import DefaultAzureCredential
    from fecth_sales_data_functions import fetch_sales_data_using_sqlite_query # fetch_sales_data_using_sqlite_query function which can be found in a fecth_sales_data_functions.py file.
    from azure.ai.projects.models import ToolSet, FunctionTool, CodeInterpreterTool

    project_client = AIProjectClient.from_connection_string(
        credential=DefaultAzureCredential(),
        conn_str=os.environ["PROJECT_CONNECTION_STRING"],
    )

    # Initialize function calling agent with the fetch_sales_data_using_sqlite_query function and adding it to the toolset
    fetch_data_function = FunctionTool(fetch_sales_data_using_sqlite_query)
    toolset = ToolSet()
    toolset.add(fetch_data_function)

    # Initialize Code Interpreter tool and adding it to the toolset.
    code_interpreter = code_interpreter = CodeInterpreterTool()
    toolset = ToolSet()
    toolset.add(code_interpreter)

    agent = project_client.agents.create_agent(
        model="gpt-4o-mini", name="my-agent", instructions="You are helpful agent",
        toolset=toolset
    )
    ```

## 使用工具使用设计模式构建可信赖 AI 代理需要注意哪些特殊事项？

使用 LLM 动态生成 SQL 时，常见的担忧是安全性，尤其是 SQL 注入或恶意操作（如删除或篡改数据库）的风险。虽然这些担忧是合理的，但通过正确配置数据库访问权限可以有效缓解这些问题。对于大多数数据库，这包括将数据库配置为只读模式。对于 PostgreSQL 或 Azure SQL 等数据库服务，应用程序应被分配一个只读（SELECT）角色。

在安全环境中运行应用程序可以进一步增强保护。在企业场景中，通常会从操作系统中提取和转换数据到一个只读数据库或数据仓库中，并采用用户友好的架构。这种方法确保数据安全、性能优化且易于访问，同时限制了应用程序的只读访问权限。

## 其他资源

- [Azure AI Agents Service Workshop](https://microsoft.github.io/build-your-first-agent-with-azure-ai-agent-service-workshop/)
- [Contoso Creative Writer Multi-Agent Workshop](https://github.com/Azure-Samples/contoso-creative-writer/tree/main/docs/workshop)
- [Semantic Kernel Function Calling Tutorial](https://learn.microsoft.com/semantic-kernel/concepts/ai-services/chat-completion/function-calling/?pivots=programming-language-python#1-serializing-the-functions)
- [Semantic Kernel Code Interpreter](https://github.com/microsoft/semantic-kernel/blob/main/python/samples/getting_started_with_agents/openai_assistant/step3_assistant_tool_code_interpreter.py)
- [Autogen Tools](https://microsoft.github.io/autogen/dev/user-guide/core-user-guide/components/tools.html)

**免责声明**:
本文件使用基于机器的人工智能翻译服务进行翻译。尽管我们努力确保准确性，但请注意，自动翻译可能包含错误或不准确之处。应以原始语言的原始文件作为权威来源。对于关键信息，建议寻求专业人工翻译服务。因使用本翻译而引起的任何误解或误读，我们概不负责。