一文詳解如何使用Java打造更優(yōu)雅的AI代理
在人工智能(AI)代理開發(fā)的浪潮中,Python似乎一直是默認(rèn)的編程語言選擇。然而,Java虛擬機(jī)(JVM)平臺(tái)正在以其強(qiáng)大的類型安全、優(yōu)雅的體系結(jié)構(gòu)和企業(yè)級(jí)生態(tài)系統(tǒng),挑戰(zhàn)這一現(xiàn)狀。Rod Johnson在2025年8月發(fā)表的文章《You Can Build Better AI Agents in Java Than Python》以及Embabel代理框架的GitHub文檔,為我們展示了Java在AI代理開發(fā)中的獨(dú)特優(yōu)勢(shì)。通過一個(gè)具體的書籍寫作案例,我們將深入探索Java如何以更少的代碼、更高的可擴(kuò)展性和更強(qiáng)的類型安全性,超越Python的CrewAI框架,創(chuàng)造出更高效、更優(yōu)雅的AI代理。
從愿景到現(xiàn)實(shí):書籍寫作的AI代理場(chǎng)景
想象一下,你是一位作者,夢(mèng)想創(chuàng)作一本關(guān)于“2025年7月人工智能現(xiàn)狀”的書籍。你需要一個(gè)AI系統(tǒng),能夠自動(dòng)研究主題、生成大綱、撰寫章節(jié),并最終整合成一本完整的Markdown格式書籍。這樣的任務(wù)看似復(fù)雜,但通過AI代理的協(xié)作,可以分解為清晰的步驟,高效完成。Rod Johnson選擇了CrewAI框架中的“Write a Book Flow”示例作為基準(zhǔn),將其用Java的Embabel框架重寫,展示Java在AI代理開發(fā)中的優(yōu)勢(shì)。
什么是“Write a Book Flow”?
這個(gè)流程通過多個(gè)AI代理協(xié)作完成書籍創(chuàng)作:首先,OutlineCrew研究主題并生成書籍大綱;然后,WriteBookChapterCrew為每個(gè)章節(jié)撰寫內(nèi)容;最后,將所有章節(jié)整合為一個(gè)Markdown文件。這是一個(gè)典型的多代理協(xié)作場(chǎng)景,適合展示框架的能力。
CrewAI的Python實(shí)現(xiàn):直觀但繁瑣
CrewAI的核心概念
CrewAI是一個(gè)流行的Python代理框架,通過“crew”(代理團(tuán)隊(duì))組織任務(wù)。每個(gè)crew包含多個(gè)代理(agent),每個(gè)代理有特定的角色(role)、目標(biāo)(goal)和背景故事(backstory)。任務(wù)通過YML文件定義,Python代碼負(fù)責(zé)將代理和任務(wù)連接起來。Pydantic模型用于約束大語言模型(LLM)的輸出,確保結(jié)構(gòu)化數(shù)據(jù)。
在書籍寫作示例中,CrewAI的實(shí)現(xiàn)分為兩個(gè)crew:
1.OutlineCrew:包含兩個(gè)代理:
- Researcher:負(fù)責(zé)研究書籍主題,收集關(guān)鍵信息。
- Outliner:根據(jù)研究結(jié)果生成書籍大綱,包含章節(jié)標(biāo)題和描述。
2.WriteBookChapterCrew:為每個(gè)章節(jié)分配一個(gè)代理,撰寫內(nèi)容并進(jìn)行進(jìn)一步研究。
Python代碼通過@CrewBase裝飾器定義crew,通過@agent和@task裝飾器配置代理和任務(wù),最終在main.py中通過BookFlow類協(xié)調(diào)整個(gè)流程。異步編程(asyncio)用于并行撰寫章節(jié),Pydantic模型(如ChapterOutline和BookOutline)提供數(shù)據(jù)結(jié)構(gòu)支持。
CrewAI的優(yōu)點(diǎn)
CrewAI的實(shí)現(xiàn)直觀且模塊化:
- 任務(wù)分解:將復(fù)雜任務(wù)拆分為研究、大綱生成和章節(jié)撰寫,清晰分工。
- LLM靈活性:每個(gè)代理可以使用不同的LLM和工具(如SerperDevTool進(jìn)行網(wǎng)絡(luò)搜索)。
- 結(jié)構(gòu)化輸出:Pydantic模型確保LLM輸出的數(shù)據(jù)格式一致。
- 并行處理:通過
asyncio實(shí)現(xiàn)章節(jié)的并發(fā)撰寫,提高效率。
比喻:像一個(gè)交響樂團(tuán)
CrewAI就像一個(gè)交響樂團(tuán),每個(gè)代理是樂手,演奏特定樂器(任務(wù))。指揮(Python代碼)協(xié)調(diào)樂手,確保音樂(書籍)和諧完成。然而,樂譜(YML配置)繁瑣,樂手間的協(xié)作(數(shù)據(jù)流)不夠明確。
CrewAI的不足
盡管CrewAI功能強(qiáng)大,但也存在顯著的短板:
- 配置繁瑣:需要多個(gè)YML文件和Python代碼,設(shè)置復(fù)雜,涉及多個(gè)目錄和文件。
- 類型安全性不足:代理和任務(wù)的輸入依賴“魔法字符串”(如
{topic}),容易出錯(cuò),且@listen裝飾器的參數(shù)無類型約束。 - 代理與任務(wù)耦合:代理知道輸入鍵(如
topic),限制了復(fù)用性,代理與任務(wù)的劃分顯得冗余。 - 并發(fā)控制不佳:章節(jié)撰寫的并發(fā)由LLM決定章節(jié)數(shù)量,可能導(dǎo)致速率限制問題。
- 生產(chǎn)環(huán)境適配性:缺乏日志框架支持,難以滿足企業(yè)級(jí)需求。
比喻:拼裝玩具的挑戰(zhàn)
CrewAI就像一套復(fù)雜的拼裝玩具,說明書(YML)冗長(zhǎng),零件(代理和任務(wù))需要手動(dòng)拼接,且容易因?yàn)榱慵?biāo)記不清(魔法字符串)而出錯(cuò)。
Embabel的Java實(shí)現(xiàn):優(yōu)雅與力量的結(jié)合
Embabel是一個(gè)專為JVM設(shè)計(jì)的代理框架,基于Spring框架,利用Java或Kotlin的強(qiáng)類型特性和企業(yè)級(jí)生態(tài),提供了更簡(jiǎn)潔、更安全的AI代理開發(fā)方式。Rod Johnson通過重寫CrewAI的書籍寫作示例,展示了Embabel的優(yōu)越性。
Embabel的核心概念
Embabel通過以下概念組織代理流程:
- 動(dòng)作(Actions):代理執(zhí)行的具體步驟。
- 目標(biāo)(Goals):代理希望實(shí)現(xiàn)的狀態(tài)。
- 條件(Conditions):動(dòng)作執(zhí)行前的狀態(tài)檢查。
- 領(lǐng)域模型(Domain Model):支撐流程的對(duì)象,包含行為。
- 計(jì)劃(Plan):由系統(tǒng)動(dòng)態(tài)生成的動(dòng)作序列,基于目標(biāo)導(dǎo)向動(dòng)作規(guī)劃(GOAP)算法。
什么是GOAP?
GOAP(Goal-Oriented Action Planning)是一種在游戲AI中常用的規(guī)劃算法,允許系統(tǒng)根據(jù)當(dāng)前狀態(tài)和目標(biāo)動(dòng)態(tài)選擇動(dòng)作序列。Embabel利用GOAP實(shí)現(xiàn)智能路徑規(guī)劃,無需開發(fā)者手動(dòng)定義流程順序。
Embabel的關(guān)鍵優(yōu)勢(shì)包括:
- 動(dòng)態(tài)規(guī)劃:系統(tǒng)根據(jù)動(dòng)作的輸入輸出類型自動(dòng)推導(dǎo)執(zhí)行順序,減少手動(dòng)配置。
- 強(qiáng)類型安全:所有提示(prompt)和數(shù)據(jù)流基于領(lǐng)域?qū)ο螅Хㄗ址?/li>
- Spring集成:利用Spring的依賴注入、配置管理和AOP,簡(jiǎn)化開發(fā)并增強(qiáng)生產(chǎn)能力。
- 可測(cè)試性:支持單元測(cè)試和端到端測(cè)試,確保代碼可靠性。
Embabel的代碼實(shí)現(xiàn)
在Embabel中,書籍寫作流程被簡(jiǎn)化為一個(gè)Java類(BookWriter)和一個(gè)YML配置文件(application.yml)。以下是核心實(shí)現(xiàn):
YML配置
注解:YML的優(yōu)雅
與CrewAI的多個(gè)YML文件相比,Embabel的單一application.yml集中配置了LLM模型、超參數(shù)、并發(fā)限制和代理角色,簡(jiǎn)潔且易于維護(hù)。Spring的@ConfigurationProperties注解自動(dòng)將YML映射為Java對(duì)象。
領(lǐng)域模型
record ChapterOutline(String title, String content) {}
record BookOutline(String title, List<ChapterOutline> chapterOutlines) implements PromptContributor {
@NotNull
@Override
public String contribution() {
return "Book Outline:\nTitle: " + title + "\n" + chapterOutlines.stream()
.map(chapter -> chapter.title() + "\n" + chapter.content())
.collect(Collectors.joining("\n\n"));
}
}
record Chapter(String title, String content) {}
record Book(BookRequest request, String title, List<Chapter> chapters) {
public String text() {
return "# " + title() + "\n" + request.goal() + "\n\n" +
chapters().stream()
.map(chapter -> "## " + chapter.title() + "\n" + chapter.content())
.collect(Collectors.joining("\n\n"));
}
}
注解:行為豐富的領(lǐng)域模型
與CrewAI的Pydantic模型(僅作為數(shù)據(jù)結(jié)構(gòu))不同,Embabel的領(lǐng)域?qū)ο螅ㄈ?code>BookOutline和Book)實(shí)現(xiàn)了PromptContributor接口,允許它們參與提示構(gòu)建,并提供格式化輸出方法(如Book.text()),增強(qiáng)了代碼的內(nèi)聚性。
代理實(shí)現(xiàn)
@Agent(description = "Write a book, first creating an outline, then writing the chapters and combining them")
public record BookWriter(BookWriterConfig config) {
@Action
ResearchReport researchTopic(BookRequest bookRequest, OperationContext context) {
return context.ai()
.withLlm(config.researcherLlm())
.withPromptElements(config.researcher(), bookRequest)
.withToolGroup(CoreToolGroups.WEB)
.createObject(
"""
Research the topic to gather the most important information that will
be useful in creating a book outline. Ensure you focus on high-quality, reliable sources.
""",
ResearchReport.class);
}
@Action
BookOutline createOutline(BookRequest bookRequest, ResearchReport researchReport, OperationContext context) {
return context.ai()
.withLlm(config.writerLlm())
.withPromptElements(config.outliner(), bookRequest, researchReport)
.withToolGroup(CoreToolGroups.WEB)
.createObject(
"""
Create a book outline as requested with chapters in sequential order based on the given research findings.
Ensure that each chapter has a title and a brief description that highlights the topics and subtopics to be covered.
""",
BookOutline.class);
}
@Action
Book writeBook(BookRequest bookRequest, BookOutline bookOutline, ResearchReport researchReport, OperationContext context) {
var chapters = context.parallelMap(
bookOutline.chapterOutlines(),
config.maxConcurrency(),
chapterOutline -> writeChapter(bookRequest, bookOutline, chapterOutline, context)
);
return new Book(bookRequest, bookOutline.title(), chapters);
}
@AchievesGoal(description = "Book has been written and published about the requested topic")
@Action
Book publishBook(Book book) {
var path = config.saveContent(book);
logger.info("Book {} written and saved to {}", book.title(), path);
return book;
}
}
注解:類型安全與動(dòng)態(tài)規(guī)劃
每個(gè)@Action方法使用強(qiáng)類型的領(lǐng)域?qū)ο螅ㄈ?code>BookRequest和ResearchReport)作為參數(shù),避免魔法字符串。OperationContext提供對(duì)AI服務(wù)的統(tǒng)一訪問,parallelMap方法通過maxConcurrency控制并發(fā),防止速率限制問題。GOAP算法自動(dòng)推導(dǎo)動(dòng)作順序,簡(jiǎn)化流程設(shè)計(jì)。
Embabel的優(yōu)勢(shì)
與CrewAI相比,Embabel的實(shí)現(xiàn)展現(xiàn)了以下優(yōu)勢(shì):
- 更少的代碼:?jiǎn)我籎ava類和YML文件取代了CrewAI的多個(gè)文件和目錄,代碼量減少。
- 類型安全:所有提示和數(shù)據(jù)流基于領(lǐng)域?qū)ο?,消除了魔法字符串,提高了開發(fā)工具支持(如重構(gòu)和自動(dòng)補(bǔ)全)。
- 可配置性:通過Spring的YML配置,可輕松調(diào)整LLM模型、超參數(shù)和并發(fā)限制。
- 生產(chǎn)就緒:內(nèi)置日志框架(SLF4J),支持單元測(cè)試和端到端測(cè)試,適合企業(yè)級(jí)應(yīng)用。
- 并發(fā)控制:
parallelMap方法通過配置限制并發(fā),避免CrewAI中由LLM決定章節(jié)數(shù)量導(dǎo)致的潛在問題。
比喻:像一架精密的飛船
Embabel就像一架精密的飛船,Spring框架是其引擎,GOAP算法是導(dǎo)航系統(tǒng),領(lǐng)域?qū)ο笫悄K化的組件。開發(fā)者只需設(shè)定目標(biāo)(目標(biāo)和動(dòng)作),飛船便能自動(dòng)規(guī)劃路線,高效到達(dá)目的地。
深入比較:Java vs. Python
代碼量與簡(jiǎn)潔性
令人驚訝的是,Embabel的Java實(shí)現(xiàn)比CrewAI的Python實(shí)現(xiàn)代碼量更少。CrewAI需要多個(gè)YML文件、Python類和裝飾器,而Embabel通過Spring的依賴注入和單一Java類簡(jiǎn)化了配置和實(shí)現(xiàn)。YML配置也更為集中,減少了維護(hù)成本。
類型安全性
CrewAI的提示依賴字符串模板(如{topic}),容易出錯(cuò),且@listen裝飾器的參數(shù)無類型約束。Embabel通過強(qiáng)類型的領(lǐng)域?qū)ο蠛?code>PromptContributor接口,確保提示構(gòu)建和數(shù)據(jù)流的安全性。這種類型安全性不僅降低了錯(cuò)誤風(fēng)險(xiǎn),還提升了IDE支持(如代碼補(bǔ)全和重構(gòu))。
可擴(kuò)展性與復(fù)用性
Embabel的GOAP規(guī)劃算法允許動(dòng)態(tài)生成動(dòng)作序列,開發(fā)者只需添加新的動(dòng)作和目標(biāo)即可擴(kuò)展功能,無需修改現(xiàn)有代碼。CrewAI的流程依賴手動(dòng)定義的@listen裝飾器,擴(kuò)展需要修改多個(gè)文件,復(fù)用性較差。
生產(chǎn)環(huán)境適配性
Embabel利用Spring的生態(tài)系統(tǒng),提供了日志、測(cè)試和配置管理的原生支持。CrewAI依賴print語句和asyncio,缺乏生產(chǎn)級(jí)的日志和并發(fā)控制,難以滿足企業(yè)需求。
比喻:從手工坊到智能工廠
CrewAI像一個(gè)手工坊,工匠(開發(fā)者)需要手動(dòng)拼接零件(YML和Python代碼),流程繁瑣且易出錯(cuò)。Embabel則像一座智能工廠,自動(dòng)化流水線(GOAP和Spring)高效生產(chǎn),開發(fā)者只需提供藍(lán)圖(領(lǐng)域模型和動(dòng)作)。
更廣闊的視野:Embabel的生態(tài)與未來
Spring與JVM的生態(tài)優(yōu)勢(shì)
Embabel基于Spring框架,充分利用了JVM的成熟生態(tài):
- 依賴注入:Spring自動(dòng)管理代理和服務(wù)的生命周期。
- 持久化與事務(wù):輕松集成Spring Data和JPA,適合企業(yè)級(jí)應(yīng)用。
- 測(cè)試支持:內(nèi)置單元測(cè)試和端到端測(cè)試框架,確保代碼質(zhì)量。
比喻:JVM的寶庫
JVM就像一座寶庫,Spring是鑰匙,Embabel是探險(xiǎn)者,帶領(lǐng)開發(fā)者挖掘企業(yè)級(jí)功能(如數(shù)據(jù)庫、事務(wù)和微服務(wù))的無限可能。
Embabel的創(chuàng)新特性
Embabel不僅僅是一個(gè)代理框架,它引入了多項(xiàng)創(chuàng)新:
- 動(dòng)態(tài)規(guī)劃:GOAP算法使流程無需硬編碼,系統(tǒng)可根據(jù)目標(biāo)和狀態(tài)自動(dòng)調(diào)整。
- 多LLM支持:支持混合使用不同LLM(如OpenAI和Anthropic),優(yōu)化成本和性能。
- MCP集成:通過Model Context Protocol(MCP)與外部工具無縫協(xié)作,提供標(biāo)準(zhǔn)化接口。
- 聯(lián)邦支持:未來支持與其他Embabel系統(tǒng)或第三方框架的協(xié)作,增強(qiáng)跨平臺(tái)能力。
未來路線圖
Embabel的GitHub文檔勾勒了宏大的愿景:
- 成為Java應(yīng)用的AI標(biāo)配:尤其是在Spring生態(tài)中,成為Gen AI的首選框架。
- 跨平臺(tái)擴(kuò)展:將Embabel的概念推廣到TypeScript和Python。
- 預(yù)算感知代理:開發(fā)支持預(yù)算限制的代理,如“花費(fèi)不超過20美分進(jìn)行研究”。
- 自然語言動(dòng)作:允許開發(fā)者用自然語言定義動(dòng)作和目標(biāo),進(jìn)一步降低開發(fā)門檻。
結(jié)語:JVM的AI新篇章
通過重寫CrewAI的書籍寫作示例,Embabel展示了Java在AI代理開發(fā)中的優(yōu)雅與力量。它的類型安全、動(dòng)態(tài)規(guī)劃和Spring生態(tài)集成,使其在代碼簡(jiǎn)潔性、可擴(kuò)展性和生產(chǎn)就緒性上超越了Python的CrewAI框架。無論是初學(xué)者還是企業(yè)開發(fā)者,Embabel都提供了一個(gè)強(qiáng)大而靈活的平臺(tái),讓AI代理開發(fā)變得如探險(xiǎn)般引人入勝。
想象一下
你站在一座未來城市的控制中心,JVM是堅(jiān)實(shí)的地基,Spring是智能的管道系統(tǒng),Embabel是指揮AI代理的超級(jí)計(jì)算機(jī)。只需幾行代碼,你就能指揮代理完成從研究到創(chuàng)作的壯舉。Embabel不僅是一個(gè)框架,它是通向AI驅(qū)動(dòng)未來的橋梁。
以上就是一文詳解如何使用Java打造更優(yōu)雅的AI代理的詳細(xì)內(nèi)容,更多關(guān)于Java實(shí)現(xiàn)AI代理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java try catch finally的執(zhí)行順序解讀
這篇文章主要介紹了Java try catch finally的執(zhí)行順序,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-05-05
spring-AOP 及 AOP獲取request各項(xiàng)參數(shù)操作
這篇文章主要介紹了spring-AOP 及 AOP獲取request各項(xiàng)參數(shù)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
一篇文章帶你入門Java數(shù)據(jù)結(jié)構(gòu)
這篇文章主要介紹了Java常見數(shù)據(jù)結(jié)構(gòu)面試題,帶有答案及解釋,希望對(duì)廣大的程序愛好者有所幫助,同時(shí)祝大家有一個(gè)好成績(jī),需要的朋友可以參考下,希望可以幫助到你2021-08-08

