在開發 AI 應用時,為 AI 代理賦予執行實際行動的能力是關鍵的突破點。透過 Microsoft 的 Semantic Kernel (SK),我們可以建立語意函式 (Semantic Functions) 和原生函式 (Native Functions),讓 AI 不僅能理解使用者需求,還能採取具體行動。
語意函式與原生函式:AI 能力的兩大支柱
在深入技術細節前,讓我們先明確兩種核心功能型別的區別:
- 語意函式:本質上是基於提示工程的函式,它透過精心設計的提示範本引導 LLM 完成特定任務,如電影推薦、文字摘要等。
- 原生函式:是實際的程式碼函式(如 Python),可以執行任何程式邏輯,包括讀寫檔案、API 呼叫、資料處理等。
這兩種函式的結合,讓 AI 代理能夠跨越純文字理解的限制,實現與真實世界的互動。
Semantic Kernel 外掛架構圖
此圖展示了一個典型的 SK 外掛(Plugin/Skill)內部如何同時包含語意函式和原生函式。
實戰:構建電影推薦代理
讓我們透過一個電影推薦系統的例子,來看看這兩種函式如何協同工作。
1. 使用原生函式獲取資料
首先,我們建立一個原生函式,用於從檔案中讀取使用者已經看過的電影清單。這個任務需要精確的檔案操作,非常適合用原生函式來實現。
# seen_movies.py
from semantic_kernel.functions import kernel_function
class MySeenMoviesDatabase:
"""描述:管理使用者已觀看電影的列表。"""
@kernel_function(
description="從檔案載入使用者已觀看的電影列表",
name="LoadSeenMovies",
)
def load_seen_movies(self) -> str:
"""從 seen_movies.txt 檔案讀取電影清單,並以逗號分隔的字串形式返回。"""
try:
with open("seen_movies.txt", 'r') as file:
lines = [line.strip() for line in file.readlines()]
return ', '.join(lines)
except Exception as e:
return f"讀取檔案時發生錯誤: {e}"
這裡,@kernel_function
裝飾器將一個普通的 Python 方法標記為 SK 可以識別的原生函式。
2. 在語意函式中嵌入原生函式
接下來,我們建立一個語意函式,它的任務是根據使用者已觀看的電影列表,推薦一部新電影。我們將在提示中直接嵌入對上述原生函式的呼叫。
// skprompt.txt
You are a wise movie recommender. You have been asked to recommend a movie to a user based on a list of movies they have watched before.
You must recommend a movie that the user has not watched before.
Movie List: {{MySeenMoviesDatabase.LoadSeenMovies}}.
這個提示範本的關鍵在於 {{MySeenMoviesDatabase.LoadSeenMovies}}
。這是一個嵌入式函式呼叫,它告訴 SK 在執行這個語意函式之前,首先要執行名為 MySeenMoviesDatabase.LoadSeenMovies
的原生函式,並將其結果填充到提示中。
3. 註冊外掛並執行
最後,我們將這兩個函式作為外掛註冊到 Kernel 中,並執行推薦流程。
import semantic_kernel as sk
import asyncio
# 初始化 Kernel 和服務 (此處省略)
kernel = sk.Kernel()
# ... 加入 OpenAI 服務 ...
# 註冊原生函式外掛
from seen_movies import MySeenMoviesDatabase
kernel.import_plugin_from_object(MySeenMoviesDatabase(), "MySeenMoviesDatabase")
# 註冊語意函式外掛
recommender_plugin = kernel.import_plugin_from_prompt_directory("plugins", "Recommender")
recommend_function = recommender_plugin["Recommend_Movies"]
# 執行函式
async def run_recommendation():
result = await kernel.invoke(recommend_function)
print(result)
asyncio.run(run_recommendation())
函式協同工作流程圖
此時序圖展示了當 Recommend_Movies
語意函式被呼叫時,其內部如何觸發原生函式的執行流程。
結論
Semantic Kernel 的語意函式和原生函式為構建 AI 應用提供了強大而靈活的工具組。透過在語意函式中嵌入原生函式,我們可以將 LLM 的理解能力與程式碼的精確執行能力無縫結合,構建出既智慧又實用的 AI 代理系統。
在實際開發中,找到語意和原生功能的正確平衡點是關鍵。有些任務完全可以透過精心設計的提示來完成,而其他任務則需要確定性的程式碼執行。掌握這種平衡,將幫助你構建出既能發揮 LLM 創造力,又能保持高效執行的下一代 AI 應用。