這是蒼何的第 445 篇原創(chuàng)!
大家好,我是刷 GitHub 停不下來的蒼何。
刷了很久的 GitHub,發(fā)現(xiàn)個有意思的開源項目。
![]()
看了下,這是京東開源的 joycode-agent,目前在 SWE-Bench Verified 基準測試中憑借 74.6% 的高通過率位居榜單全球 Top3。
![]()
SWE-Bench Verified 是通過使用真實世界開源項目中的 Bug 報告和 Issue 來測試 Agent 從理解問題到自主生成、集成和驗證修復(fù)代碼的完整端到端能力,是 AI Coding 技術(shù)走向和產(chǎn)品落地的行業(yè)風(fēng)向標之一。
從跑分和能力上來看,JoyCode 針對的應(yīng)該是企業(yè)級研發(fā)場景。
我點進去他們官網(wǎng),就可以直接下載 JoyCode 這款智能編碼工具。
![]()
進入后,導(dǎo)入 vscode 配置,做下簡單設(shè)置,然后用京東賬號登錄。
![]()
可以看到,JoyCode 內(nèi)置了很多的資源和 MCP 工具。
![]()
也內(nèi)置了很多主流的大模型,都可以直接使用,也可自定義添加模型,集成了 Git 做代碼的版本管理,自動生成 commit message 信息。
看了 JoyCode 設(shè)置,可以開啟代碼評審,針對每次提交的代碼,自動進行質(zhì)量、安全、編碼規(guī)范、邏輯錯誤等多維度的掃描,并提供修復(fù)建議。
![]()
稍微總結(jié)下它的核心能力:
1、多智能體架構(gòu):可定制智能體,通過”先規(guī)劃、后執(zhí)行”的策略,以團隊協(xié)作方式智能拆解復(fù)雜任務(wù)。
2、支持規(guī)約編程:基于需求、設(shè)計、實施的三階段工作流程,可實現(xiàn)從需求到交付的端到端覆蓋。
3、CSR上下文引擎:通過對代碼倉庫的深度解析,全面理解代碼倉庫上下文等集成開發(fā)環(huán)境信息。
4、可一鍵云端部署。
看了京東云官方公眾號消息,說是 JoyCode 已服務(wù)京東上萬名研發(fā)人員,支撐數(shù)億級用戶產(chǎn)品研發(fā),生成代碼采納率超 50%,開發(fā)周期縮短 40%。
![]()
于是乎,我又開始了一頓測試,來看看 JoyCode 實際能力如何。
既然主打的是企業(yè)級智能編碼工具,那就來幾個企業(yè)級開發(fā)最為關(guān)心的幾大問題。
![]()
快速上手老項目
大部分時間,企業(yè)中并不總是在開發(fā)新項目,而是在原有項目上做些功能的迭代或者業(yè)務(wù)的更新。
特別是對于新人,新加入項目團隊后,要快速掌握整個項目,絕非一件容易的事,稍微規(guī)范點的團隊會有相關(guān)文檔,但很多團隊項目,就真的只有一份代碼。
最讓人痛苦的是,這份代碼,連個注釋都沒有,業(yè)務(wù)邏輯和數(shù)據(jù)結(jié)構(gòu),要人肉去理解,花費時間及其漫長,痛苦面具+1。
我嘗試用 JoyCode 來做這方面的工作,就拿我的真實企業(yè)級開源項目 PmHub 來測試吧。
先讓 JoyCode 基于項目源碼幫我生成項目架構(gòu)圖。
![]()
可以看到 JoyCode 自動切換到架構(gòu)圖設(shè)計模式,然后上來就先分析了項目中的 pom. xml 依賴文件及 Readme 文件,以及對整個項目理解就開始吭哧吭哧自動調(diào)用 draw. io 幫畫項目架構(gòu)圖了。
這里我等了不少時間,中途甚至有些想放棄,罵一句辣雞,然后滾去睡覺。但最后出來的結(jié)果,讓人很驚喜。

除了還原了整個項目的技術(shù)架構(gòu),還把各個層的流轉(zhuǎn)用流動箭頭做了標記。可以說,這是目前為止,我最滿意的一次架構(gòu)圖設(shè)計實驗。
JoyCode 生成. drawio 文件后,通過插件或者 draw.io 就能打開了。
了解了整個項目架構(gòu),還需要根據(jù)數(shù)據(jù)結(jié)構(gòu)來從數(shù)據(jù)層面了解業(yè)務(wù)。可以讓它生成對應(yīng)的 ER 圖,來幫助了解。
prompt:基于該 sql 文件,生成實體-關(guān)系圖,并按照業(yè)務(wù)域?qū)?shù)據(jù)庫表進行分類 這里有個細節(jié),由于 sql 文件非常大,在 Chat 界面可以看到,JoyCode 會對整個上下文進行合理壓縮,然后制定該任務(wù)的 todolist,agent 會執(zhí)行任務(wù)。
![]()
先看下稍微簡單一些的任務(wù),將表按照業(yè)務(wù)域做分類,這個完全沒啥問題。
![]()
到了畫圖這,由于表過多,我本就沒打算它能一次成,在一番處理后,終于生成好了。
![]()
說實話,這和我理想中的 ER 圖有些距離,不過用來做項目輔助理解,多少有些用。
有了清晰的數(shù)據(jù)結(jié)構(gòu),對于有些復(fù)雜的業(yè)務(wù)邏輯,可以借助 AI 來進行代碼脈絡(luò)查看,可以通過流程圖來輔助理解。
比如 PmHub 項目中的這串代碼:
/**
* 任務(wù)待逾期提醒
*/
@Component
@Slf4j
publicclass TaskNotifyJob {
@Autowired
private ProjectTaskMapper projectTaskMapper;
@Autowired
private ProjectTaskNotifyMapper projectTaskNotifyMapper;
@Scheduled(cron = "0 0 9 * * ?")
@Transactional(rollbackFor = Exception.class)
public void taskNotify() {
List tasks = projectTaskMapper.queryTaskNotifyJob();
// 當前時間
LocalDate localDate = LocalDate.now();
tasks.stream().filter(taskNotifyDTO -> StringUtils.isNotBlank(taskNotifyDTO.getUserWxName()) && taskNotifyDTO.getCloseTime() != null)
.forEach(taskNotifyDTO -> {
if (ProjectStatusEnum.PAUSE.getStatus().equals(taskNotifyDTO.getStatus())) {
return;
}
LocalDate closeDate = taskNotifyDTO.getCloseTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
if (ChronoUnit.DAYS.between(localDate, closeDate) == taskNotifyDTO.getNotifyDay()) {
log.info("待逾期任務(wù)提醒開始, 用戶id:{}, 企微id:{}, 任務(wù)id:{}", taskNotifyDTO.getUserId(), taskNotifyDTO.getUserWxName(), taskNotifyDTO.getTaskId());
// 進行待逾期消息提醒
TaskOverdueRemindDTO taskOverdueRemindDTO = new TaskOverdueRemindDTO();
// 設(shè)置任務(wù)名稱
taskOverdueRemindDTO.setTaskName(taskNotifyDTO.getTaskName());
// 設(shè)置通知用戶id
taskOverdueRemindDTO.setUserIds(Collections.singletonList(taskNotifyDTO.getUserWxName()));
// 設(shè)置天數(shù)
taskOverdueRemindDTO.setNum(taskNotifyDTO.getNotifyDay());
// 設(shè)置任務(wù)詳情地址
String url = SsoUrlUtils.ssoCreate(appid, agentid, host + path + ssoPath + URLEncoder.encode(host + "/pmhub-project/my-task/info?taskId=" + taskNotifyDTO.getTaskId()));
taskOverdueRemindDTO.setDetailUrl(url);
taskOverdueRemindDTO.setOaTitle("任務(wù)即將逾期提醒");
taskOverdueRemindDTO.setOaContext("您的任務(wù)【" + taskNotifyDTO.getTaskName() + "】還有【" + taskNotifyDTO.getNotifyDay() + "】天到期,請及時處理!");
taskOverdueRemindDTO.setUserName(taskNotifyDTO.getUserName());
taskOverdueRemindDTO.setLinkUrl(OAUtils.ssoCreate(host + "/pmhub-project/my-task/info?taskId=" + taskNotifyDTO.getTaskId()));
RocketMqUtils.push2Wx(taskOverdueRemindDTO);
// 進行查詢 如果數(shù)據(jù)庫不存在記錄 則就插入記錄
LambdaQueryWrapper qw = Wrappers.lambdaQuery(ProjectTaskNotify .class).eq(ProjectTaskNotify::getTaskId, taskNotifyDTO.getTaskId()).eq(ProjectTaskNotify::getOverdue, 0);
if (projectTaskNotifyMapper.selectOne(qw) == null) {
// 插入記錄
ProjectTaskNotify projectTaskNotify = new ProjectTaskNotify();
projectTaskNotify.setProjectId(taskNotifyDTO.getProjectId());
projectTaskNotify.setTaskId(taskNotifyDTO.getTaskId());
projectTaskNotify.setOverdue(0);
projectTaskNotify.setUserId(taskNotifyDTO.getUserId());
projectTaskNotify.setUserWxName(taskNotifyDTO.getUserWxName());
projectTaskNotify.setCloseTime(taskNotifyDTO.getCloseTime());
projectTaskNotify.setTaskName(taskNotifyDTO.getTaskName());
projectTaskNotifyMapper.insert(projectTaskNotify);
}
log.info("待逾期任務(wù)提醒結(jié)束");
}
});
}}
可以選中這段代碼后,解釋該代碼。
![]()
然后讓 JoyCode 生成流程圖。
![]()
代碼評審
在團隊開發(fā)中,開發(fā)完代碼通常需要進行代碼評審,也簡稱為 CR,這個工作通常會團隊內(nèi)交叉進行,最終上線需要技術(shù) leader 進行最終 CR。
現(xiàn)在就可以把這個工作先交給 AI 來做一輪前置評審,識別出相關(guān)風(fēng)險,保證代碼質(zhì)量。
![]()
JoyCode 會給出一份評審報告,并列出改進建議和優(yōu)先級排序。
![]()
在完成開發(fā)后,做代碼提交,JoyCode 能夠自動添加 git commit 信息。
![]()
接口變生產(chǎn)代碼
在實際企業(yè)級開發(fā)中,前后端會同步開發(fā),往往是先定義好接口,然后前后端都基于該接口進行開發(fā)。
所以如何將定義好的接口(API 文檔)轉(zhuǎn)化為生產(chǎn)級代碼,就顯得很重要。
我嘗試在 JoyCode 中測試該功能,比如照著我們開源的 PmHub 項目的接口文檔,我們嘗試做點有意思的事情。
PmHub 接口文檔地址:https://laigeoffer-pmhub.apifox.cn
給到如下提示詞:
基于該API文檔:https://laigeoffer-pmhub.apifox.cn 中的"我的項目"模塊進行開發(fā),請嚴格遵循開發(fā)規(guī)范和接口定義,前后端分離,保證項目可運行。他會先根據(jù) API 文檔創(chuàng)建需求文檔、設(shè)計文檔和任務(wù)文檔。
![]()
然后就開始吭哧吭哧的由前端到后端的開發(fā)。我這里選的是 JoyCode 的規(guī)約編程模式。
一句話解釋規(guī)約編程:你不用手把手教 AI 怎么做,你只管用規(guī)則(規(guī)約)把“要什么”和“標準是什么”定義清楚,AI 就能自己寫出 100% 滿足你要求的代碼。
在任務(wù)列表中可以分解了 22 個任務(wù),等待執(zhí)行,我們點擊確認全部執(zhí)行。
![]()
在任務(wù)隊列中就可看到所有任務(wù),JoyCode 會按照任務(wù)順序依次執(zhí)行。
![]()
這里我發(fā)現(xiàn)了一處小細節(jié),在 JoyCode 中多個任務(wù)是可以并行的,比如這個命令:
cd pmhub-ui && npm install 它就能在終端自己并行執(zhí)行,在 Chat 中的代碼任務(wù)也在同步執(zhí)行。
在生成前端代碼這個任務(wù)中,可以看到無論是使用的框架還是文件類命名的風(fēng)格都出奇的和規(guī)范保持一致,甚至還學(xué)習(xí)了命名風(fēng)格,環(huán)境配置。
我列了一張對比圖:
![]()
出奇的相似。前端頁面也完全可用。
![]()
登錄進來后就可以看到項目管理功能模塊了。
![]()
這是一個基于 API 文檔利用 JoyCode 生成的項目管理系統(tǒng),全程我唯一要做的是把 API 丟給 JoyCode,然后讓他規(guī)劃任務(wù),按照指定的規(guī)約進行編程。
JoyCode 的表現(xiàn)還不錯,在嚴肅的企業(yè)級場景中,不會瞎搞,像是個憨實的程序員。
一句話需求到 PRD
我從 GitHub 了解到,JoyCode 內(nèi)置了一些工具,能將一句話需求快速轉(zhuǎn)變?yōu)?strong>專業(yè)產(chǎn)研翻譯,生成 PRD 文檔。
來測試下效果。
提示詞:幫我生成專業(yè)的PRD文檔,我需要開發(fā)一個項目管理系統(tǒng),支持新建項目、項目中新建任務(wù)。 ![]()
可以看到將口語的一句話需求轉(zhuǎn)化為了專業(yè)的業(yè)務(wù)語言。
全棧開發(fā)
我也蠻想試試在 JoyCode 中進行全棧開發(fā),
這里我直接利用原先 PmHub 的 PRD 文檔和設(shè)計原型文檔,進行全棧開發(fā)。
ps:這也是規(guī)約編程的執(zhí)行標準,不建議直接上手開發(fā),在開發(fā)前定義好相應(yīng)需求和設(shè)計,才能讓 AI 更好的完成任務(wù)。
我的目的很簡單,幫我一比一復(fù)刻一個 PmHub 出來。
但由于 PmHub 功能很多,完全復(fù)刻需要時間,這里我就以基礎(chǔ)的能力來做了復(fù)刻。下面是我整體的實現(xiàn)流程。
![]()
第一步,PRD 分析。
PmHub 的需求分析長這樣:
![]()
提示詞:你是一名全棧架構(gòu)師,以上是項目管理系統(tǒng)的prd,幫我根據(jù)這個prd,
生成一個關(guān)鍵設(shè)計說明。并生成系統(tǒng)整體交互流程UML時序圖 ![]()
生成的時序圖,經(jīng)過調(diào)整和樣式簡單優(yōu)化得到如下:
![]()
這里的 UML 邏輯需要多次核對,Chat 修改,最終能得到符合的效果,稍微有些花時間。
第二步,設(shè)計原型文檔分析。
這是 PmHub 的原型設(shè)計圖,直接將他丟給 JoyCode。
![]()
以上是項目管理系統(tǒng)的原型設(shè)計文檔「URL鏈接」,請基于此進行技術(shù)方案設(shè)計。 可以看到結(jié)果會更偏向設(shè)計需求:
![]()
第三步、生成 API 接口文檔
接口先行,并行開發(fā),是敏捷開發(fā)的必要點,這里我創(chuàng)新性的讓 JoyCode 先根據(jù)以上信息生成 API 接口文檔,然后根據(jù)上面的步驟再依次生成前后端代碼及數(shù)據(jù)庫代碼。
由于模塊很多,建議區(qū)分單個模塊生成。
基于以上信息及文檔,幫我生成項目管理模塊中的項目列表和添加項目的 api 接口文檔,我要能直接導(dǎo)入到apifox中。 ![]()
然后還生成了 api 文檔說明。
![]()
這里需要導(dǎo)入到 Apifox 中進行 check,確保符合后繼續(xù)接下來的操作。
第四步,生成代碼。
這里我的經(jīng)驗是根據(jù) api 文檔以及原型設(shè)計稿會有很好的效果,AI 不會瞎搞,樣式和接口都是按照預(yù)定的來。
包括技術(shù)設(shè)計、架構(gòu)設(shè)計,這些在規(guī)約中已經(jīng)指定,這就是規(guī)約編程的魅力吧。
和之前一樣,JoyCode 會根據(jù)要求,老老實實寫代碼。
由于時間關(guān)系,我就只讓開發(fā)了登錄頁面、項目列表頁和新建項目,包括整個框架這次我也讓生成好了,這樣下次單模塊開發(fā)就能直接使用。
登錄頁:
![]()
這是項目列表頁:
![]()
這是添加項目頁面:
![]()
可以說,98%以上還原了我 PmHub,包括頁面組件樣式和功能。
雖然,過程中會有一些問題需要調(diào)整,但在 JoyCode 中也能方便的處理。
我體驗下來,JoyCode 對于復(fù)雜任務(wù)的理解和處理效果是很好的,如果給的足夠詳細,比如原型設(shè)計,基于 API 接口開發(fā)等。
更能發(fā)揮出好的效果。
還可以在 JoyCode 中一鍵部署,不過我的功能還沒開發(fā)完全,就先不部署了,到時再多調(diào)調(diào),看下能否完全復(fù)刻出一個 PmHub 出來。
呼,現(xiàn)在真方便了。有了 AI 規(guī)約編程,你不用手把手教 AI 怎么做,你只管用規(guī)則(規(guī)約)把“要什么”和“標準是什么”定義清楚,AI 就能自己寫出滿足你要求的代碼。
以后接手沒有注釋和文檔的屎山項目時,也許我們終于不用再戴上痛苦面具了。
特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺“網(wǎng)易號”用戶上傳并發(fā)布,本平臺僅提供信息存儲服務(wù)。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.