隨著 AI 產業開始意識到大型語言模型(LLM)的推理能力,我們決定讓它們更具備智能體特性,使其能執行更複雜的操作。這類大型語言模型被稱為 智能體(agents)。
因此,單一智能體系統應運而生。但很快人們就發現,為單一智能體分配多項任務並不是構建智能體系統的最優方案。更好的做法是使用多個智能體,每個智能體負責執行特定的任務,協同合作達成使用者定義的目標。
然而,另一個問題隨之出現:管理多個智能體並不像管理單一智能體那樣簡單。為了解決這個問題,市面上推出了多款多智能體系統框架,其中最具潛力的之一就是 CrewAI。
CrewAI 能幫助開發者構建多智能體系統。透過 CrewAI,你可以管理你的智能體、它們的任務以及工作流程。本文中,我們將結合 CrewAI 與 Novita 平台上豐富的 LLM 資源,構建實用且智慧的多智能體系統。
什麼是多智能體系統?我們為什麼需要它?
自從大型語言模型(LLM)問世以來,業界探索了多種方法來提升其自主性。其中最具代表性的方案是論文《在語言模型中協同推理與行動》中提出的 ReAct 模式。LangChain 等框架很快實現了 ReAct 模式,為 LLM 賦予了智能體能力。
AutoGPT 等工具則更進一步,構建了更強大的 AI 智能體,只需一行文字提示就能執行使用者想要的多數任務。雖然這些單一智能體系統展現出了巨大潛力,但它們也存在明顯限制:單一智能體通常依賴單一 LLM 處理所有任務,這會導致幾個關鍵缺點:
- 上下文限制:單一智能體必須用單一的上下文視窗管理所有任務。隨著工作流程推進,智能體最終會耗盡上下文空間。
- 複雜度提升:隨著任務數量增加,推理變得越來越難管理,智能體更容易出現幻覺或執行失敗。
- 單點故障:單一智能體負責所有事務,沒有備援機制。如果它無法處理某項任務,整個系統就會完全失效。
- 缺乏平行處理能力:任務只能逐個處理,沒有內建支援讓智能體平行工作以提升效率。
多智能體系統正是為了解決這些痛點而誕生的。與其依賴單一智能體處理多項任務,多智能體系統將職責分配給多個協同工作的智能體。這樣就能避免上下文長度超限等問題,因為每個智能體只需要管理自己的工作流程部分,整體上下文負載也會降低。
多智能體架構還允許你為不同場景使用不同模型:部分模型可以針對特定任務進行微調,部分可以搭配預設提示詞,部分可以配備專用工具,還有一部分可以針對推理進行優化。這種多樣性不僅能提升效能,還支援平行處理,讓多智能體系統比單一智能體系統更快、更高效。
要構建多智能體系統,你需要兩個核心組件:提供 LLM 的模型供應商,以及用於管理整個智能體工作流程的多智能體框架。本文中,我們將使用 Novita 作為模型供應商,CrewAI 作為我們的首選框架。
為什麼你需要像 CrewAI 這樣的框架?
構建多智能體系統的複雜度遠高於構建單一智能體系統。例如,你可以透過函數呼叫(function calling)功能,輕鬆讓 Novita 上的任何模型成為智能體。但一旦你開始連接多個智能體,複雜度會大幅提升:你現在需要管理多個運作部件,包括:
- 通訊與任務委派:你需要協調智能體之間的溝通方式,以及任務在智能體之間的傳遞邏輯。
- 工具管理:沒有框架的情況下,你需要手動管理工具定義和 JSON 結構描述,這很快就會變得雜亂無章。
- 智能體架構與模式:多智能體框架通常內建支援業界公認的成熟智能體模式。如果你從零開始構建,就需要持續追蹤這些不斷演進的模式,並自行實現。
- 可觀測性:沒有框架的情況下,你還需要自行搭建工具來監控、除錯和視覺化智能體的互動與執行表現。
多智能體框架可以幫助你管理所有這些複雜度。本文中,我們將選擇 CrewAI 作為我們的首選框架。CrewAI 相比其他框架有多項優勢:它以簡潔性脫穎而出,使用直觀的概念來建模多智能體系統;它成熟且穩定;同時還提供了極佳的開發者體驗。
了解 CrewAI 的核心概念
要使用 CrewAI 構建多智能體系統,你需要熟悉該框架引入的幾個核心概念。以下是本文中我們將使用的主要概念的簡要概述:
- 智能體(Agents)
- 任務(Tasks)
- 船員(Crews)
- 流程(Processes)
- 流程圖(Flows)
智能體(Agents)
智能體是 CrewAI 的核心。它們代表由 LLM 驅動的實際 AI 工作者。CrewAI 中的每個智能體都由三個要素定義:角色(role,指導其決策的職責)、目標(goal,指導其行為的方向)以及背景故事(backstory,塑造其行為風格的敘述)。這些要素都以發送給 LLM 的文字提示詞形式呈現。智能體還可以配備工具,它們可以從中選擇工具來執行特定操作。CrewAI 中智能體的主要目標是完成分配給它的單項或多項任務。
任務(Tasks)
任務定義了需要完成的工作。在 CrewAI 中,你可以建立任務,直接將任務分配給特定智能體,或者讓符合任務要求的智能體自動認領任務。每個任務通常包含清晰的描述、預期輸出,以及其他相關參數(例如可選的任務處理智能體)。
船員(Crew)
這是 CrewAI 的核心概念。在 CrewAI 中,一群協同工作以完成任務的智能體被稱為船員(Crew)。船員同時也定義了其中智能體的工作流程。
流程(Processes)
流程 是預定義的工作流程,告訴船員如何執行任務。CrewAI 支援兩種主要流程類型:
- 循序(Sequential):船員中的智能體一次處理一項任務。
- 階層式(Hierarchical):在這種流程中,一個智能體擔任管理者,協調其他智能體並根據需要委派任務。
流程圖(Flows)
流程是預定義的工作流程,而 CrewAI 的流程圖(Flows)則為開發者提供了設計自定義智能體工作流程的彈性。一個流程可以包含智能體、任務,甚至整個船員,支援更複雜的互動邏輯。
使用 Novita 構建船員(Crew)
現在我們已經介紹了 CrewAI 的核心概念,讓我們動手構建一個船員。在本示例中,我們將創建一個專為幫助使用者快速構建最小可行產品(MVP)設計的 船員。這個船員由三個專業智能體組成:
- 架構師(Architect):定義軟體結構並概述 MVP 範圍。這個智能體由託管在 Novita 上的 moonshotai/kimi-k2-instruct 模型驅動。
- 開發者(Coder):實現架構師的計畫並編寫實際程式碼。它使用 FileWriter 工具 創建所有專案檔案,並運行在 Novita 的 qwen/qwen3-coder-480b-a35b-instruct 模型上。
- 審核者(Reviewer):分析開發者生成的程式碼,並使用差異格式提供改進建議。和架構師一樣,它也使用 moonshotai/kimi-k2-instruct 模型。
我們的船員將遵循循序流程執行。
安裝與環境設定
現在計畫已經確定,讓我們先設定環境。首先安裝 CrewAI 及其內建工具支援:
pip install 'crewai[tools]'
接下來,你需要準備 Novita API 金鑰。取得金鑰後,將其作為 NOVITA_API_KEY 加入環境變數中:
export NOVITA_API_KEY=your_api_key_here
完成以上步驟後,我們就可以開始構建船員了。
創建 LLM 實例
首先導入必要的依賴項:
import os
from crewai import Agent, Task, Crew, Process, LLM
from crewai_tools import FileWriterTool
接下來,我們將創建 FileWriterTool 的實例,開發者智能體將使用它來將檔案寫入磁碟:
file_writer_tool = FileWriterTool()
工具準備完成後,我們現在可以為每個智能體初始化對應的 LLM 實例:
architect_llm = LLM(
model="novita/moonshotai/kimi-k2-instruct",
temperature=0.5,
api_base="https://api.novita.ai/v3/openai",
api_key=os.environ['NOVITA_API_KEY']
)
coder_llm = LLM(
model="novita/qwen/qwen3-coder-480b-a35b-instruct",
temperature=0.4,
api_base="https://api.novita.ai/v3/openai",
api_key=os.environ['NOVITA_API_KEY']
)
reviewer_llm = LLM(
model="novita/moonshotai/kimi-k2-instruct",
temperature=0.5,
api_base="https://api.novita.ai/v3/openai",
api_key=os.environ['NOVITA_API_KEY']
)
這三個 LLM 實例對應我們計畫中定義的模型,它們託管在 Novita 上,透過 CrewAI 存取。在底層,CrewAI 使用 LiteLLM 來連接和管理這些模型。
定義智能體
現在讓我們創建三個智能體:
architect = Agent(
role="Software Architect for MVP Projects",
goal="Define a basic system structure and simple feature set to guide MVP development",
backstory="""You specialize in quickly outlining software architectures and project scopes for
minimum viable products. Your plans help guide coders with enough structure to get started while staying lean.""",
llm=architect_llm,
verbose=True
)
coder = Agent(
role="Developer for MVP Projects",
goal="Implement the MVP using simple, clear code, and write all necessary code files using the FileWriter tool",
backstory="""You're a practical developer focused on speed. You prioritize working code over polish.
Simulate any runtime behavior if needed, and make sure to keep code clear and modular.""",
llm=coder_llm,
verbose=True,
tools=[file_writer_tool]
)
reviewer = Agent(
role="Code Reviewer for MVP Projects",
goal="Read the code files, provide helpful feedback, and write improvements as diffs into a markdown file",
backstory="""You're a fast but thoughtful reviewer. You check code for clarity, obvious bugs, and
provide improvements as diffs. Instead of modifying code directly, you
save your suggestions in a markdown file
for easy inspection.""",
llm=reviewer_llm,
verbose=True,
tools=[file_writer_tool]
)
每個智能體都被分配了特定的角色、目標和背景故事。
定義任務
現在讓我們創建對應的任務:
architect_task = Task(
description="""
Create a basic plan for building a simple MVP version of a {project}.
Focus on the core features, basic file structure, and tech stack.
Make the structure minimal but enough to get a working demo.
""",
expected_output="""
A simple architectural overview with:
- Project goals
- Key components or files
- Basic data flow or structure
""",
agent=architect,
output_file="architecture.md"
)
coder_task = Task(
description="""
Based on the architect's plan, implement the core parts of the {project} MVP.
Keep it lean and functional. Use the FileWriter tool to save all your code files.
If you need to simulate behavior (e.g. without a real interpreter), do so with clear comments or mocked logic.
""",
expected_output="""
Working code files saved using the FileWriter tool that implement the key features defined in the plan.
Code should be readable and logically structured.
""",
agent=coder,
context=[architect_task]
)
review_task = Task(
description="""
Review the code files created for the {project} MVP. Read each file using the FileRead tool.
Suggest improvements using diffs. Do not modify the original code files directly.
Instead, save all your suggested diffs into a markdown file using the FileWriter tool.
""",
expected_output="""
A markdown file containing diff-style suggestions for each file reviewed.
""",
agent=reviewer,
context=[coder_task],
output_file="code_review_diffs.md"
)
創建船員
現在我們已經定義了所有智能體、對應的 LLM 以及任務,讓我們將所有組件整合起來,組裝成船員:
code_crew = Crew(
agents=[architect, coder, reviewer],
tasks=[architect_task, coder_task, review_task],
process=Process.sequential,
verbose=True
)
所有設定完成後,我們現在可以運行船員了:
if __name__ == "__main__":
code_crew.kickoff(inputs={"project": "Todo App"})
現在我們已經擁有一個功能完整的船員,可以根據使用者定義的規格生成最小可行產品專案。在上面的示例中,我們要求船員構建一個簡單的待辦事項應用程式。
其運作流程如下:
- 架構師 智能體首先設計軟體架構,並將計畫儲存到名為
architecture.md的檔案中。 - 接著 開發者 智能體會取用架構師的輸出,創建必要的目錄和程式碼檔案來實現待辦事項應用程式。
- 最後,審核者 智能體會審查生成的程式碼,並使用差異格式提供改進建議,將反饋儲存到名為
code_review_diffs.md的檔案中。
這種基於船員的開發工作流程功能強大且模組化,但它也存在一些限制:
- 硬編碼提示詞:將提示詞直接嵌入程式碼中,後續維護或優化提示詞的難度會更高。
- 結構分散:智能體和任務是內聯定義的,隨著專案規模擴大,腳本會變得雜亂且難以導航。
在下一節中,我們將介紹如何透過將智能體定義和任務提示詞外置到 YAML 檔案中,來優化上述結構。
構建基於類的船員
CrewAI 支援我們創建基於類的船員。讓我們更新之前的程式碼以符合這種結構。首先,創建一個名為 config 的資料夾,這個資料夾將包含定義智能體和任務設定的 YAML 檔案。
首先創建一個名為 agents.yaml 的檔案,作為智能體設定檔:
architect:
role: >
最小可行產品專案軟體架構師
goal: >
定義基礎系統結構與簡單功能範圍,以引導最小可行產品開發
backstory: >
你專注於快速勾勒最小可行產品的軟體架構與專案範圍。
你的計畫能為開發者提供足夠的結構指引,同時保持精簡。
coder:
role: >
最小可行產品專案開發者
goal: >
使用簡單清晰的程式碼實現最小可行產品,並使用 FileWriter 工具寫入所有必要的程式碼檔案
backstory: >
你是一個注重效率的實用型開發者。你優先選擇可運行的程式碼而非完美打磨的代碼。
如有需要,可模擬任何執行時期行為,並確保程式碼清晰且模組化。
reviewer:
role: >
最小可行產品專案程式碼審核者
goal: >
閱讀程式碼檔案,提供有幫助的反饋,並將改進建議以差異格式寫入 Markdown 檔案
backstory: >
你是一個快速且細心的審核者。你會檢查程式碼的清晰度、明顯的錯誤,並以差異格式提供改進建議。
你不直接修改原始程式碼,而是將建議儲存在 Markdown 檔案中方便查看。
這個檔案定義了每個智能體的角色、目標和背景故事。
接下來,我們創建一個 tasks.yaml 檔案來存放任務設定:
請改用 FileWriter 工具將所有建議的差異內容儲存到 Markdown 檔案中。
architect_task:
description: >
為構建簡易 {project} 最小可行產品版本建立基礎計畫。
專注於核心功能、基礎檔案結構與技術堆疊。
使結構盡可能精簡,但足以運行演示。
expected_output: >
簡單的架構概述,包含:
- 專案目標
- 關鍵組件或檔案
- 基礎資料流或結構
agent: architect
output_file: architecture.md
coder_task:
description: >
根據架構師的計畫,實現 {project} 最小可行產品的核心部分。
保持精簡且功能完整。使用 FileWriter 工具儲存所有程式碼檔案。
如果需要模擬行為(例如沒有真實直譯器),請使用清晰的註解或模擬邏輯實現。
expected_output: >
使用 FileWriter 工具儲存的可用程式碼檔案,實現計畫中定義的核心功能。
程式碼應易讀且邏輯結構清晰。
agent: coder
context:
- architect_task
review_task:
description: >
審查為 {project} 最小可行產品創建的程式碼檔案。使用 FileRead 工具閱讀每個檔案。
使用差異格式建議改進。不要直接修改原始程式碼檔案。
請改用 FileWriter 工具將所有建議的差異內容儲存到 Markdown 檔案中。
expected_output: >
包含每個審查檔案差異格式建議的 Markdown 檔案。
agent: reviewer
context:
- coder_task
output_file: code_review_diffs.md
接下來,讓我們創建基於類的船員。為此,我們需要定義一個類,並使用 CrewAI 提供的 @CrewBase 裝飾器對其進行修飾:
@CrewBase
class CodeCrew():
"""三智能體程式碼船員:架構師、開發者、審核者"""
@agent
def architect(self) -> Agent:
pass
@agent
def coder(self) -> Agent:
pass
@agent
def reviewer(self) -> Agent:
pass
@task
def architect_task(self) -> Task:
pass
@task
def code_task(self) -> Task:
pass
@task
def review_task(self) -> Task:
pass
@crew
def crew(self) -> Crew:
pass
在這種結構中:
@agent裝飾器用於定義生成智能體的方法。@task裝飾器標記生成任務的方法。@crew裝飾器指定用於組裝整個船員的方法。
現在,讓我們看完整的實現:
import os
from crewai import Agent, Crew, Process, Task, LLM
from crewai.project import CrewBase, agent, crew, task
from crewai.agents.agent_builder.base_agent import BaseAgent
from typing import List
from crewai_tools import FileWriterTool
# 實例化工具
file_writer_tool = FileWriterTool()
@CrewBase
class CodeCrew():
agents: List[BaseAgent]
tasks: List[Task]
agents_config = 'config/agents.yaml'
tasks_config = 'config/tasks.yaml'
@agent
def architect(self) -> Agent:
llm = LLM(
model="novita/moonshotai/kimi-k2-instruct",
temperature=0.5,
api_base="https://api.novita.ai/v3/openai",
api_key=os.environ['NOVITA_API_KEY']
)
return Agent(
config=self.agents_config['architect'],
llm=llm,
verbose=True
)
@agent
def coder(self) -> Agent:
llm = LLM(
model="novita/qwen/qwen3-coder-480b-a35b-instruct",
temperature=0.4,
api_base="https://api.novita.ai/v3/openai",
api_key=os.environ['NOVITA_API_KEY']
)
return Agent(
config=self.agents_config['coder'],
llm=llm,
verbose=True,
tools=[file_writer_tool]
)
@agent
def reviewer(self) -> Agent:
llm = LLM(
model="novita/moonshotai/kimi-k2-instruct",
temperature=0.5,
api_base="https://api.novita.ai/v3/openai",
api_key=os.environ['NOVITA_API_KEY']
)
return Agent(
config=self.agents_config['reviewer'],
llm=llm,
verbose=True,
)
@task
def architect_task(self) -> Task:
return Task(config=self.tasks_config['architect_task'])
@task
def coder_task(self) -> Task:
return Task(config=self.tasks_config['coder_task'])
@task
def review_task(self) -> Task:
return Task(config=self.tasks_config['review_task'])
@crew
def crew(self) -> Crew:
return Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
verbose=True
)
這段程式碼定義了所有必要的方法,包含智能體和任務的屬性,同時指定了設定檔案的路徑,這些路徑會在智能體和方法中用於載入對應的設定。
現在你可以透過在腳本中添加以下程式碼來運行船員:
def main():
code_crew = CodeCrew()
code_crew.crew().kickoff(inputs={"project": "Todo App"})
if __name__ == '__main__':
main()
使用 Novita 構建流程圖(Flows)
我們之前構建的船員遵循循序流程。現在,讓我們探索如何構建遵循自定義工作流程的流程圖。
我們的工作流程
我們希望設計一個客戶支援多智能體系統,由一個主智能體負責分類客戶問題。根據分類結果,系統會判斷哪個專業智能體最適合處理該問題。該設定包含四個智能體:
- 客戶智能體(Customer Agent):這是主智能體,接收客戶的問題並將其分類為以下類別之一:帳務(Billing)、技術(Technical) 或 一般(General)。
- 帳務智能體(Billing Agent):處理所有帳務相關問題。
- 技術智能體(Technical Agent):處理技術問題。
- 一般智能體(General Agent):處理不屬於上述類別的所有問題。

定義流程圖的狀態
CrewAI 中的流程圖擁有共享狀態。該狀態在流程圖中的所有智能體和船員之間均可存取。對於我們的客戶支援流程圖,狀態包含問題標籤和使用者的查詢內容。
讓我們導入必要的模組並定義我們的狀態:
import json
import os
from typing import Literal, Dict, Any
from pydantic import BaseModel, ValidationError
from crewai import Agent, LLM
from crewai.flow.flow import Flow, start, router, listen
# 定義流程圖狀態
class SupportState(BaseModel):
issue: Literal["billing", "technical", "general"] = "general"
message: str = ""
創建流程圖
CrewAI 中的流程圖是基於圖的,使用事件驅動系統來處理節點之間的轉換。要創建我們的流程圖,我們首先需要一個用於分類問題的節點,接著是一個路由器節點,根據分類結果決定將請求路由到哪個處理節點。
class CustomerSupportFlow(Flow[SupportState]):
@start()
def classify_issue(self):
pass
@router(classify_issue)
def route_based_on_issue(self) -> str:
print(f"📨 正在路由到對應問題類型的智能體:{self.state.issue}")
if self.state.issue == "billing":
return "billing"
if self.state.issue == "technical":
return "technical"
else:
return "general"
@listen("billing")
def handle_billing(self):
pass
@listen("technical")
def handle_technical(self):
pass
@listen("general")
def handle_general(self):
pass
使用 @start() 裝飾器修飾的方法是流程圖的入口點。在本例中,它負責問題分類。使用 @router() 裝飾器修飾的方法會在 classify_issue 之後執行,用於判斷要路由到哪個智能體。其他方法使用事件驅動系統,在收到路由信號時觸發執行。
實現流程圖方法
現在讓我們實現每個方法,並為其分配對應的智能體:
class CustomerSupportFlow(Flow[SupportState]):
@start()
def classify_issue(self) -> Dict[str, Any]:
intake_agent = Agent(
role="User Intake Agent",
goal="Classify user support issue and summarize the message",
backstory="You classify the user query into billing, technical, or general categories.",
llm=LLM(
model="novita/qwen/qwen2.5-vl-72b-instruct",
temperature=0.3,
api_base="https://api.novita.ai/v3/openai",
api_key=os.environ["NOVITA_API_KEY"]
),
verbose=True
)
prompt = f"""
使用者提交了以下訊息:"{self.state.message}"
你的任務:
1. 判斷問題屬於「billing」、「technical」還是「general」類別。
2. 重新表述或提取清晰的訊息內容。
請回傳符合以下示例的有效 JSON 格式:
{{
"issue": "billing",
"message": "使用者反映訂閱被重複收費,正在申請退款。"
}}
"""
output = intake_agent.kickoff(prompt, response_format=SupportState)
try:
# 解析 JSON 字串
print(output.raw)
parsed_json = json.loads(output.raw)
# 使用 Pydantic 驗證
validated = SupportState(**parsed_json)
# 儲存到狀態
self.state.issue = validated.issue
self.state.message = validated.message
except (json.JSONDecodeError, ValidationError) as e:
print("❌ 無法解析或驗證回應:", e)
self.state.issue = "general"
@router(classify_issue)
def route_based_on_issue(self) -> str:
print(f"📨 正在路由到對應問題類型的智能體:{self.state.issue}")
if self.state.issue == "billing":
return "billing"
if self.state.issue == "technical":
return "technical"
else:
return "general"
@listen("billing")
def handle_billing(self):
agent = Agent(
role="Billing Agent",
goal="Handle billing questions, refunds, and invoice issues",
backstory="You resolve billing-related queries effectively.",
llm=LLM(
model="novita/meta-llama/llama-3.3-70b-instruct",
temperature=0.5,
api_base="https://api.novita.ai/v3/openai",
api_key=os.environ["NOVITA_API_KEY"]
),
verbose=True
)
result = agent.kickoff(self.state.message)
print("💰 帳務智能體回應:", result)
@listen("technical")
def handle_technical(self):
agent = Agent(
role="Technical Support Agent",
goal="Help users resolve technical issues",
backstory="You're a technical expert providing troubleshooting support.",
llm=LLM(
model="novita/meta-llama/llama-3.1-8b-instruct",
temperature=0.5,
api_base="https://api.novita.ai/v3/openai",
api_key=os.environ["NOVITA_API_KEY"]
),
verbose=True
)
result = agent.kickoff(self.state.message)
print("🛠 技術智能體回應:", result)
@listen("general")
def handle_general(self):
agent = Agent(
role="General Support Agent",
goal="Provide helpful answers to non-technical and non-billing questions",
backstory="You're friendly and well-informed about our services.",
llm=LLM(
model="novita/minimaxai/minimax-m1-80k",
temperature=0.5,
api_base="https://api.novita.ai/v3/openai",
api_key=os.environ["NOVITA_API_KEY"]
),
verbose=True
)
result = agent.kickoff(self.state.message)
print("📋 一般智能體回應:", result)
classify_issue 方法使用 Pydantic 確保模型回傳有效的回應。完成設定後,我們現在可以使用以下程式碼運行流程圖:
def run():
flow = CustomerSupportFlow()
flow.plot("CustomerSupportFlowPlot")
# 示例輸入訊息
example_input = {
"message": "你好,我的訂閱被重複收費了,需要申請退款。"
}
flow.kickoff(inputs=example_input)
if __name__ == "__main__":
run()
結論
構建多智能體系統需要兩個關鍵組件:提供豐富多樣模型選擇的模型供應商,以及用於協調智能體互動的多智能體框架。本文中,我們展示了 Novita 和 CrewAI 如何勝任這兩個角色。想要深入了解 CrewAI,務必參考其官方文件。如果你希望為你的船員實驗更多模型,可以查看 Novita 的LLM 遊樂場。
專案程式碼倉庫 - https://github.com/novitalabs/Novita-CollabHub/tree/main/examples/novita-crewai
關於 Novita AI
Novita AI 是一個 AI 雲端平台,為開發者提供簡單的 API 介面,方便部署 AI 模型,同時也提供平價且可靠的 GPU 雲端服務,用於建構與擴展 AI 應用。
