智能體開發(fā)實戰(zhàn) | 基于Dify自定義工作流工具構(gòu)建游戲智能體
前言
Dify是一款開源的大語言模型應用開發(fā)平臺,旨在降低AI應用的開發(fā)門檻,幫助開發(fā)者和企業(yè)快速構(gòu)建、部署及管理生成式AI應用。
Dify允許用戶在畫布上構(gòu)建和測試功能強大的AI工作流。工作流通過將復雜任務分解為更小的步驟(節(jié)點),有效降低了系統(tǒng)的復雜度。這種方法減少了對提示詞技術(shù)和模型推理能力的依賴,從而提升了 LLM 在處理復雜任務時的性能,同時增強了系統(tǒng)的可解釋性、穩(wěn)定性和容錯性。
本文以實現(xiàn)24點游戲為例。24點的游戲規(guī)則:給出一組4個隨機整數(shù)(1至13之間,且不重復),用加、減、乘、除(可加括號)把給出的4個數(shù)字算成24,每個數(shù)必須用一次且只能用一次。
這個智能體需要具備如下能力:
- 出題:生成一組4個隨機整數(shù)(1至13之間,且不重復),并確保生成的隨機數(shù)能計算出24。
- 校驗用戶輸入的表達式計算結(jié)果是否為24。
- 解題:根據(jù)用戶給出的隨機數(shù),生成答案。
通過設(shè)置合適的提示詞,為智能體設(shè)定角色和處理邏輯。智能體會根據(jù)大語言模型對人物設(shè)定和回復邏輯的理解,來響應用戶問題。因此提示詞編寫的越清晰明確,智能體的回復也會越符合預期??梢栽谔崾驹~中指定用工作流作邏輯處理,實現(xiàn)通過prompt無法實現(xiàn)的功能。
創(chuàng)建工作流工具
在http://localhost/apps頁面點擊“創(chuàng)建空白應用”,選擇“工作流”。填寫應用名,點擊創(chuàng)建。依次創(chuàng)建三個工作流:
- generate_random_numbers:為24點游戲生成一組隨機數(shù)
- check_answer:校驗表達式計算結(jié)果是否為24
- generate_answer:根據(jù)一組隨機數(shù)生成24點游戲的答案
工作流1:generate_random_numbers
整體流程如下圖:
- 名稱:generate_random_numbers
- 描述:為24點游戲生成一組隨機數(shù)
- 開始節(jié)點: 用默認配置,無需添加輸入字段
- 代碼執(zhí)行節(jié)點
- 輸入變量:無
- 輸出變量:numbers,類型為Array[Number]
- 代碼:
import random
from itertools import permutations, product
def main() -> dict:
while True:
numbers = []
while len(numbers) < 4:
num = random.randint(1, 13)
if num not in numbers:
numbers.append(num)
res = generate_answer(numbers)
# 確保生成的隨機數(shù)能計算出24
if res['code'] == 'ok':
return {'numbers': numbers}
def generate_answer(numbers):
if len(numbers) != 4:
return {'code': 'error', 'msg': "隨機數(shù)個數(shù)不正確"}
operations = ['+', '-', '*', '/']
for num_perm in permutations(numbers):
for ops in product(operations, repeat=3):
# 嘗試所有不同的括號組合
expressions = [
f'(({num_perm[0]} {ops[0]} {num_perm[1]}) {ops[1]} {num_perm[2]}) {ops[2]} {num_perm[3]}',
f'({num_perm[0]} {ops[0]} ({num_perm[1]} {ops[1]} {num_perm[2]})) {ops[2]} {num_perm[3]}',
f'({num_perm[0]} {ops[0]} {num_perm[1]}) {ops[1]} ({num_perm[2]} {ops[2]} {num_perm[3]})',
f'{num_perm[0]} {ops[0]} (({num_perm[1]} {ops[1]} {num_perm[2]}) {ops[2]} {num_perm[3]})',
f'{num_perm[0]} {ops[0]} ({num_perm[1]} {ops[1]} ({num_perm[2]} {ops[2]} {num_perm[3]}))',
]
for expr in expressions:
try:
if eval(expr) == 24:
return {'code': 'ok', 'answer': expr}
except ZeroDivisionError:
continue
return {'code': 'error'}
- 結(jié)束節(jié)點輸出變量numbers的參數(shù)值為引用“代碼執(zhí)行”節(jié)點的輸出變量numbers。
- 運行點擊右上角的“運行”,驗證是否可以正確輸出一組隨機數(shù)
- 發(fā)布工作流測試通過后,點擊右上角的“發(fā)布”按鈕。
- 發(fā)布為工具發(fā)布成功后,點擊“發(fā)布為工具”
填入工具調(diào)用名稱和工具描述,并保存。
工作流2:check_answer
整體流程如下圖:
- 名稱:check_answer
- 描述:校驗表達式計算結(jié)果是否為24
- 開始節(jié)點
輸入?yún)?shù)
expression:類型為String,顯示名稱為“表達式”
? 代碼執(zhí)行節(jié)點
? 輸入變量:
expression,引用開始節(jié)點的expression變量
? 輸出變量:
code,類型為String
msg, 類型為String
- 代碼
def main(expression:str) -> dict:
try:
val = eval(expression)
if val == 24:
return {'code': 'ok', 'msg':'ok'}
else:
return {'code': 'error', 'msg': f"表達式{expression}計算結(jié)果為{val}, 不是24"}
except Exception as e:
return {'code': 'error', 'msg': f"計算出錯。{e}"}
- 結(jié)束節(jié)點
輸出變量
code,引用代碼執(zhí)行節(jié)點的code輸出變量
msg, 引用代碼執(zhí)行節(jié)點的msg輸出變量
- 測試并發(fā)布工作流
- 發(fā)布為工具
發(fā)布成功后,點擊”發(fā)布為工具“。填入工具調(diào)用名稱和工具描述,并保存。
工作流3:generate_answer
整體流程如下圖:
- 名稱:generate_answer
- 描述:根據(jù)一組隨機數(shù)生成24點游戲的答案
開始節(jié)點
輸入?yún)?shù)
numbers:類型為String,顯示名稱為“一組隨機整數(shù),JSON格式”
- 代碼執(zhí)行節(jié)點
- 輸入變量
numbers,引用開始節(jié)點的numbers變量
? 輸出變量
code,類型為String
msg, 類型為String
answer, 類型為String
? 代碼
from itertools import permutations, product
import json
def main(numbers:str) -> dict:
numbersArray = json.loads(numbers)
if len(numbersArray) != 4:
return {'code': 'error', 'msg': "隨機數(shù)個數(shù)不正確", 'answer':''}
operations = ['+', '-', '*', '/']
for num_perm in permutations(numbersArray):
for ops in product(operations, repeat=3):
# 嘗試所有不同的括號組合
expressions = [
f'(({num_perm[0]} {ops[0]} {num_perm[1]}) {ops[1]} {num_perm[2]}) {ops[2]} {num_perm[3]}',
f'({num_perm[0]} {ops[0]} ({num_perm[1]} {ops[1]} {num_perm[2]})) {ops[2]} {num_perm[3]}',
f'({num_perm[0]} {ops[0]} {num_perm[1]}) {ops[1]} ({num_perm[2]} {ops[2]} {num_perm[3]})',
f'{num_perm[0]} {ops[0]} (({num_perm[1]} {ops[1]} {num_perm[2]}) {ops[2]} {num_perm[3]})',
f'{num_perm[0]} {ops[0]} ({num_perm[1]} {ops[1]} ({num_perm[2]} {ops[2]} {num_perm[3]}))',
]
for expr in expressions:
try:
if eval(expr) == 24:
return {'code': 'ok', 'msg':'ok', 'answer': expr}
except ZeroDivisionError:
continue
return {'code': 'error', 'msg': 'error', 'answer':''}
- 結(jié)束節(jié)點
- 輸出變量
code,引用代碼執(zhí)行節(jié)點的code輸出變量
msg, 引用代碼執(zhí)行節(jié)點的msg輸出變量
answer, 引用代碼執(zhí)行節(jié)點的answer輸出變量
- 測試并發(fā)布工作流
- 發(fā)布為工具
發(fā)布成功后,點擊”發(fā)布為工具“。填入工具調(diào)用名稱和工具描述,并保存。
創(chuàng)建Agent應用
在http://localhost/apps頁面點擊“創(chuàng)建空白應用”,選擇“Agent”。填寫應用名,點擊創(chuàng)建,進入編排界面。編排界面如下:
- 設(shè)置提示詞內(nèi)容為:
你是一個24點游戲助手。
- 開始游戲時,你需要生成一組隨機數(shù),提示用戶回答,然后使用工作流check_answer校驗用戶的回答。
- 如果用戶表示回答不了問題,請使用工作流generate_answer生成答案。
- 用戶可以向你提供一組數(shù)字提問如何計算,你需要使用工作流generate_answer生成答案。
- 添加工具把3個工作流添加為工具。
- 選擇模型使用qwen-plus
- 調(diào)試和預覽在下方輸入內(nèi)容和Agent進行游戲互動
- 測試通過后,點擊右上角的“發(fā)布”按鈕。
- 發(fā)布后,點擊“運行”即可打開應用的訪問鏈接。
總結(jié)
本文以24點游戲智能體為案例,展示了Dify基于工作流的Agent應用開發(fā)。通過把工作流發(fā)布為工具,Agent通過推理可以智能調(diào)用相應工作流解決問題。