Graphite框架揭秘:如何用它打造可擴展的AI工作流 原創(chuàng)
在當(dāng)今數(shù)字化時代,人工智能(AI)已經(jīng)滲透到我們生活的方方面面,從日常的語音助手到復(fù)雜的企業(yè)級應(yīng)用,AI正在改變我們的工作和生活方式。然而,隨著AI應(yīng)用的不斷擴展,企業(yè)和開發(fā)者們面臨著一個共同的挑戰(zhàn):如何構(gòu)建符合特定業(yè)務(wù)需求的AI解決方案?今天,我們要介紹的Graphite框架,正是為解決這一問題而生。
一、為什么我們需要Graphite?
在AI的世界里,已經(jīng)有許多強大的工具和平臺,比如ChatGPT、Claude等。但這些通用的AI解決方案在處理一些關(guān)鍵任務(wù)時,往往顯得力不從心。例如,在金融、醫(yī)療等對準(zhǔn)確性要求極高的領(lǐng)域,即使是微小的錯誤也可能帶來巨大的損失。這就需要一種更加靈活、可控的AI框架,能夠根據(jù)具體的業(yè)務(wù)需求進行定制。Graphite正是在這樣的背景下誕生的。
Graphite是一個開源框架,專門用于構(gòu)建特定領(lǐng)域的AI助手。它提供了一個高度可擴展的平臺,能夠根據(jù)獨特的企業(yè)需求進行定制,讓開發(fā)者能夠構(gòu)建出符合具體業(yè)務(wù)領(lǐng)域的個性化工作流。用一個形象的比喻來說,Graphite就像是AI領(lǐng)域的“樂高積木”,開發(fā)者可以像搭積木一樣,自由組合各種組件,打造出自己想要的AI應(yīng)用。
二、Graphite的核心架構(gòu):簡單、強大且可組合
Graphite的架構(gòu)設(shè)計非常巧妙,它由三個概念層組成:助手(Assistants)、節(jié)點(Nodes)和工具(Tools)。
- 助手(Assistants):它們是整個工作流的“指揮官”,負(fù)責(zé)協(xié)調(diào)工作流的運行,并管理整個對話的狀態(tài)。你可以把助手想象成一個項目經(jīng)理,它決定著整個項目的進度和方向。
- 節(jié)點(Nodes):節(jié)點是工作流中的一個個“小工人”,每個節(jié)點都有自己的職責(zé),比如調(diào)用一個語言模型或者執(zhí)行一個函數(shù)。它們各司其職,共同完成復(fù)雜的工作。
- 工具(Tools):工具是節(jié)點用來完成具體任務(wù)的“工具箱”,比如調(diào)用一個API或者運行一個Python函數(shù)。這些工具為節(jié)點提供了實際操作的能力。
Graphite還采用了事件溯源模式,這意味著每一次狀態(tài)的變化都會被記錄下來。這就像是給整個系統(tǒng)安裝了一個“黑匣子”,無論何時出現(xiàn)問題,都可以通過這些記錄來追溯原因。
這種架構(gòu)的好處是顯而易見的。首先,它讓整個系統(tǒng)變得非常模塊化,開發(fā)者可以像搭積木一樣,自由地添加、移除節(jié)點,甚至可以在不影響其他部分的情況下,對某個節(jié)點進行修改。其次,這種架構(gòu)提高了系統(tǒng)的靈活性和可擴展性,無論業(yè)務(wù)需求如何變化,都可以輕松地調(diào)整工作流。
三、Graphite的四大核心特性:讓AI應(yīng)用更可靠
(一)可觀察性(Observability)
在復(fù)雜的AI系統(tǒng)中,要找出問題的根源往往像大海撈針一樣困難。Graphite通過事件驅(qū)動的架構(gòu)、日志記錄和追蹤功能,讓開發(fā)者能夠?qū)崟r監(jiān)控系統(tǒng)的運行狀態(tài),快速定位瓶頸或錯誤。這就像是給AI系統(tǒng)安裝了一雙“透視眼”,讓每一個環(huán)節(jié)都變得透明可測。
(二)冪等性(Idempotency)
在異步工作流中,由于網(wǎng)絡(luò)波動或部分失敗等原因,可能需要重復(fù)執(zhí)行某些操作。Graphite的設(shè)計強調(diào)冪等性操作,確保即使重復(fù)調(diào)用,也不會出現(xiàn)數(shù)據(jù)重復(fù)或損壞的情況。這就像是給系統(tǒng)加上了一層“保護罩”,避免了因重復(fù)操作而引發(fā)的混亂。
(三)可審計性(Auditability)
Graphite將事件作為唯一的事實來源,自動記錄每一次狀態(tài)變化和決策路徑。這對于那些需要嚴(yán)格遵守法規(guī)的行業(yè)來說,簡直就是“救星”。無論是為了合規(guī)性檢查,還是為了調(diào)試和追蹤問題,這些詳細(xì)的記錄都提供了有力的支持。
(四)可恢復(fù)性(Restorability)
在長時間運行的AI任務(wù)中,如果中途出現(xiàn)失敗,重新開始可能會浪費大量的時間和資源。Graphite通過檢查點和基于事件的回放功能,讓工作流可以從失敗的那一刻精準(zhǔn)恢復(fù),最大限度地減少了停機時間和資源浪費。
四、動手實踐:用Graphite打造一個“了解你的客戶”AI助手
說了這么多,可能你會問:“聽起來不錯,但是實際操作起來難不難?”別擔(dān)心,接下來我們就通過一個簡單的例子,來實際感受一下Graphite的強大。
假設(shè)我們要為一家健身房打造一個“了解你的客戶”(KYC)AI助手。這個助手的主要任務(wù)是收集客戶的全名和電子郵件地址,完成健身房的注冊流程。如果客戶提供的信息不完整,助手會暫停流程,并要求客戶提供更多信息。
(一)搭建工作流
首先,我們需要安裝Graphite框架。在終端中運行以下命令即可完成安裝:
pip install grafi
接下來,我們需要定義工作流中的各個組件。根據(jù)前面的描述,我們需要創(chuàng)建以下組件:
- 7個主題(Topics):包括用戶輸入主題、用戶信息提取主題、人工干預(yù)主題等。
- 5個節(jié)點(Nodes):包括用戶信息提取節(jié)點、動作節(jié)點、人工干預(yù)節(jié)點、注冊用戶節(jié)點和響應(yīng)用戶節(jié)點。
以下是部分代碼實現(xiàn):
from grafi.common.topics.topic import Topic
from grafi.common.topics.human_request_topic import human_request_topic
from grafi.common.topics.output_topic import agent_output_topic
from grafi.nodes.llm_node import LLMNode
from grafi.nodes.llm_function_call_node import LLMFunctionCallNode
from grafi.commands.llm_response_command import LLMResponseCommand
from grafi.commands.function_calling_command import FunctionCallingCommand
from grafi.tools.openai_tool import OpenAITool
from grafi.common.models.message import Message
from grafi.common.decorators.llm_function import llm_function
from grafi.common.models.execution_context import ExecutionContext
import json
import uuid
# 定義主題
user_info_extract_topic = Topic(name="user_info_extract_topic")
hitl_call_topic = Topic(
name="hitl_call_topic",
cnotallow=lambda msgs: msgs[-1].tool_calls[0].function.name != "register_client",
)
register_user_topic = Topic(
name="register_user_topic",
cnotallow=lambda msgs: msgs[-1].tool_calls[0].function.name == "register_client",
)
register_user_respond_topic = Topic(name="register_user_respond")
# 定義用戶信息提取節(jié)點
user_info_extract_node = (
LLMNode.Builder()
.name("UserInfoExtractNode")
.subscribe(agent_input_topic)
.command(
LLMResponseCommand.Builder()
.llm(
OpenAITool.Builder()
.name("UserInfoExtractLLM")
.api_key("YOUR_OPENAI_API_KEY")
.model("gpt-3.5-turbo")
.system_message("Extract user's full name and email from the input.")
.build()
)
.build()
)
.publish_to(user_info_extract_topic)
.build()
)
# 定義動作節(jié)點
action_node = (
LLMNode.Builder()
.name("ActionNode")
.subscribe(user_info_extract_topic)
.command(
LLMResponseCommand.Builder()
.llm(
OpenAITool.Builder()
.name("ActionLLM")
.api_key("YOUR_OPENAI_API_KEY")
.model("gpt-3.5-turbo")
.system_message("Decide the next action based on the extracted information.")
.build()
)
.build()
)
.publish_to(hitl_call_topic)
.publish_to(register_user_topic)
.build()
)
# 定義人工干預(yù)節(jié)點
human_request_function_call_node = (
LLMFunctionCallNode.Builder()
.name("HumanRequestNode")
.subscribe(hitl_call_topic)
.command(
FunctionCallingCommand.Builder()
.function_tool(ClientInfo())
.build()
)
.publish_to(human_request_topic)
.build()
)
# 定義注冊用戶節(jié)點
register_user_node = (
LLMFunctionCallNode.Builder()
.name("RegisterUserNode")
.subscribe(register_user_topic)
.command(
FunctionCallingCommand.Builder()
.function_tool(RegisterClient())
.build()
)
.publish_to(register_user_respond_topic)
.build()
)
# 定義響應(yīng)用戶節(jié)點
user_reply_node = (
LLMNode.Builder()
.name("UserReplyNode")
.subscribe(register_user_respond_topic)
.command(
LLMResponseCommand.Builder()
.llm(
OpenAITool.Builder()
.name("UserReplyLLM")
.api_key("YOUR_OPENAI_API_KEY")
.model("gpt-3.5-turbo")
.system_message("Generate a response to the user based on the registration result.")
.build()
)
.build()
)
.publish_to(agent_output_topic)
.build()
)
(二)測試助手
現(xiàn)在我們已經(jīng)搭建好了工作流,接下來就可以測試我們的“了解你的客戶”AI助手了。以下是測試代碼:
def test_kyc_assistant():
execution_context = ExecutionContext(
conversation_id="conversation_id",
execution_id=uuid.uuid4().hex,
assistant_request_id=uuid.uuid4().hex,
)
# 初始化助手
assistant = (
KycAssistant.Builder()
.name("KycAssistant")
.api_key("YOUR_OPENAI_API_KEY")
.user_info_extract_system_message(user_info_extract_system_message)
.action_llm_system_message(
"Select the most appropriate tool based on the request."
)
.summary_llm_system_message(
"Response to user with result of registering. You must include 'registered' in the response if succeed."
)
.hitl_request(ClientInfo())
.register_request(RegisterClient())
.build()
)
whileTrue:
# 獲取用戶輸入
user_input = input("User: ")
input_data = [Message(role="user", cnotallow=user_input)]
# 執(zhí)行助手
output = assistant.execute(execution_context, input_data)
# 處理輸出
responses = []
for message in output:
try:
content_json = json.loads(message.content)
responses.append(content_json["question_description"])
except json.JSONDecodeError:
responses.append(message.content)
respond_to_user = " and ".join(responses)
print("Assistant:", respond_to_user)
# 如果注冊成功,結(jié)束循環(huán)
if"registered"in output[0].content:
break
if __name__ == "__main__":
test_kyc_assistant()
運行這段代碼后,你可以通過終端與我們的AI助手進行交互。例如:
User: Hi, I'd like to sign up for your gym. Could you help me with the process?
Assistant: Please provide your full name and email address to sign up for the gym.
User: My name is John Doe, and my email is john.doe@example.com
Assistant: Congratulations, John! You are now registered at our gym. If you have any questions or need assistance, feel free to ask!
五、測試、觀察、調(diào)試與改進:讓助手更完美
在實際使用中,我們可能會遇到各種問題。Graphite通過集成OpenTelemetry和Arize的OpenInference,提供了強大的追蹤和觀察功能。我們可以輕松地捕獲助手的行為數(shù)據(jù),快速定位問題。
例如,假設(shè)我們在測試中發(fā)現(xiàn),當(dāng)用戶輸入與注冊無關(guān)的內(nèi)容時,助手會報錯。通過追蹤工具,我們可以迅速定位到問題的根源——動作LLM沒有正確選擇工具。于是,我們可以更新動作LLM的系統(tǒng)提示,讓它在用戶輸入無關(guān)內(nèi)容時,調(diào)用??request_client_information?
?工具,禮貌地詢問用戶是否需要注冊幫助。
這種快速迭代和改進的過程,正是Graphite的魅力所在。它不僅幫助我們快速搭建AI應(yīng)用,還讓我們能夠持續(xù)優(yōu)化,讓助手變得越來越智能。
六、總結(jié):Graphite,為真實世界AI應(yīng)用而生
Graphite不僅僅是一個框架,它是一種全新的構(gòu)建AI應(yīng)用的思維方式。通過簡單而強大的三層執(zhí)行模型、事件驅(qū)動的編排機制以及對可觀察性、冪等性、可審計性和可恢復(fù)性的支持,Graphite為開發(fā)者提供了一個靈活、可擴展且可靠的平臺。
無論是構(gòu)建對話式助手,還是自動化工作流,Graphite都能滿足你的需求。它讓我們能夠像搭積木一樣,輕松構(gòu)建出符合特定業(yè)務(wù)需求的AI應(yīng)用。如果你也對AI開發(fā)充滿熱情,不妨試試Graphite,或許它就是你一直在尋找的那個“神器”。
本文轉(zhuǎn)載自公眾號Halo咯咯 作者:基咯咯
