教你如何0 代碼手搓一個 Chrome 插件

0 評論 857 瀏覽 5 收藏 24 分鐘

最近這段時間 IDE 特別火,B站和小紅書上刷到了無數(shù)個用 Cursor 和 Windsurf 快速開發(fā)軟件的教程。作為一個一直有開發(fā)夢但不會代碼的產(chǎn)品經(jīng)理,這給了我一個很好的機(jī)會去嘗試自己開發(fā)工具。最終我是是用字節(jié)新上線的工具 Trae 完成全部的開發(fā),并且順利上線 Chrome 插件商店。本文將記錄一下春節(jié)時期開發(fā)時的流程和遇到的一些坑。

01 這款產(chǎn)品是干什么的

開發(fā)的初衷來自于日常生活中。我在上班到公司后,第一件事就是打開知乎、人人都是產(chǎn)品經(jīng)理或者公眾號,把想要讀的內(nèi)容打開放在標(biāo)簽頁中,等有空的時候再讀。但實(shí)際情況往往是因?yàn)閮?nèi)容太長來不及讀、工作太忙忘記或者不小心關(guān)掉標(biāo)簽頁而導(dǎo)致忘記閱讀。這個時候就希望有個工具能夠?qū)⒕W(wǎng)頁上的內(nèi)容轉(zhuǎn)換為精簡過的音頻。于是這款插件就誕生了。

他的主要功能包括:

  1. 內(nèi)容出處(確認(rèn)是不是想要閱讀的文章)
  2. 創(chuàng)建播客(將文章轉(zhuǎn)換為 5 分鐘內(nèi)的訪談式播客)
  3. 播客制作列表(之前制作過的播客任務(wù),點(diǎn)擊后會跳轉(zhuǎn)播放音頻)

02 如何將文章轉(zhuǎn)成播客

之前google 出品的 NotebookLM在國外很火,他最厲害的點(diǎn)就在于能夠上傳文件、鏈接將其轉(zhuǎn)換為播客,兩個 AI 主持人會圍繞素材內(nèi)容進(jìn)行討論、調(diào)侃,使信息獲取更具趣味性。在 github 上找到了開源版的 prompt,于是就用扣子來搭了一個屬于自己的 NotebookLM。

1. 搭建工作流

由于我們的插件只需要考慮網(wǎng)頁內(nèi)容,所以整體的功能分為四步:

  1. 獲取網(wǎng)頁內(nèi)信息
  2. 將其轉(zhuǎn)換為 host 和 guest對話的腳本
  3. 用兩個不同的聲音扮演 host 和 guest,并合成對應(yīng)的音頻
  4. 將音頻依次組合,成為一個完整的音頻文件

因此我最終的工作流形態(tài)如下:

首先先用扣子的官方插件LinkReaderPlugin,他可以將網(wǎng)頁中的內(nèi)容提取出來;之后,用大模型將內(nèi)容轉(zhuǎn)換為腳本,這里我選擇的是豆包 128k,prompt 是

SYSTEM_PROMPT:

你是一位世界級的播客制作人。你的任務(wù)是將提供的輸入文本轉(zhuǎn)化為引人入勝且富有信息量的播客腳本。你將收到一段可能結(jié)構(gòu)不清晰或雜亂無章的文本,這些文本來源于PDF文件或網(wǎng)頁。忽略無關(guān)的信息或格式問題。你的重點(diǎn)是提取出最有趣和最具洞察力的內(nèi)容,以便進(jìn)行播客討論。

USER_INPUT:

context:{{input}}

# Steps to Follow:

  1. **分析輸入:** 仔細(xì)檢查文本,識別關(guān)鍵主題、觀點(diǎn)以及可以推動引人入勝的播客對話的有趣事實(shí)或軼事。忽略不相關(guān)的信息或格式問題。
  2. **集思廣益的想法:** 在“<scratchpad>”中,創(chuàng)造性地集思廣益,以引人入勝的方式呈現(xiàn)要點(diǎn)??紤]: – 類比、講故事的技巧或假設(shè)場景,使內(nèi)容具有相關(guān)性 – 讓普通受眾能夠理解復(fù)雜主題的方法 – 在播客期間探索發(fā)人深省的問題 – 創(chuàng)意填補(bǔ)信息空白的方法

這樣,你就能獲得一個帶分鏡得腳本:

然后,再將這個分鏡腳本作為輸入去請求下一個大模型,將其轉(zhuǎn)換為對話。這里我選擇的還是豆包 128k,prompt 是

SYSTEM_PROMPT:
您是世界級的播客制作人。 您的任務(wù)是將提供的輸入文本轉(zhuǎn)換為引人入勝且信息豐富的播客腳本。 您將收到一個可能是非結(jié)構(gòu)化或混亂的文本作為輸入,這些文本來自以下地方PDF 或網(wǎng)頁。忽略不相關(guān)的信息或格式問題。 您的重點(diǎn)是為播客討論提取最有趣和最有洞察力的內(nèi)容。目標(biāo)是在{{host}} 和{{guest}}之間實(shí)現(xiàn)自然的對話流程
角色與動態(tài):指令定義了主持人和專家的角色,確保他們相輔相成。主持人熱情地強(qiáng)調(diào)有趣的觀點(diǎn),而專家則提供分析、背景和更廣泛的視角
– 深入探討:指令強(qiáng)調(diào)超越表面信息,以揭示關(guān)鍵見解和“知識金 nuggets”,讓聽眾感到自己學(xué)到了新東西
– 目標(biāo)受眾:系統(tǒng)提示概述了理想聽眾的特征,他們重視效率,欣賞難忘細(xì)節(jié),并尋求引人入勝的學(xué)習(xí)體驗(yàn)
– 結(jié)構(gòu)與傳遞:系統(tǒng)提示強(qiáng)調(diào)清晰結(jié)構(gòu)和吸引人的傳遞方式的重要性,使用路標(biāo)來引導(dǎo)聽眾,避免單調(diào)、機(jī)械化的語調(diào)
– 使用最佳想法來自
{{file}}
令人難忘的例子:現(xiàn)實(shí)世界的例子和相關(guān)的軼事對于讓信息深入人心至關(guān)重要。系統(tǒng)提示強(qiáng)調(diào)將信息生動化,促進(jìn)參與,并確保學(xué)習(xí)超越這一集。
– 確保復(fù)雜主題被清晰簡單地解釋。
– 專注于保持引人入勝且 {{tone}}以吸引聽眾。
– 規(guī)則:
> 主持人總是先發(fā)言并采訪嘉賓。嘉賓負(fù)責(zé)解釋主題。
> 主持人應(yīng)向嘉賓提問。
> 主持人的提問話術(shù)需要盡可能的豐富,不要只用一種形式提問,這很重要。
> 主持人需要在適當(dāng)?shù)臅r機(jī)附和嘉賓說的內(nèi)容再開始繼續(xù)提問。
> 主持人在最后應(yīng)總結(jié)關(guān)鍵見解。
> 在主持人與嘉賓的回答中包含常見的口頭填充詞,如“呃”和“嗯”。這樣可以使劇本更真實(shí)。
> 主持人與嘉賓可以互相打斷。
> 嘉賓不得包含營銷或自我宣傳內(nèi)容。
> 嘉賓不得包括任何未在輸入文本中證實(shí)的材料。
> 這將是一場適合所有年齡段的對話。
> 當(dāng)輸出接近結(jié)尾時,主持人和嘉賓應(yīng)該自然地總結(jié)關(guān)鍵見解。這應(yīng)該感覺像是一場隨意的談話,而不是正式的回顧,在簽字之前最后一次強(qiáng)調(diào)主要觀點(diǎn),并進(jìn)行自然過渡。
**總結(jié)關(guān)鍵見解:** 自然地將關(guān)鍵點(diǎn)的總結(jié)融入對話的結(jié)尾部分。這應(yīng)該感覺像是一場隨意的談話,而不是正式的回顧,在簽字之前強(qiáng)化主要收獲。
– 包括簡短的“喘息”時刻,讓聽眾吸收復(fù)雜信息
– 以積極向上的方式結(jié)束,也許可以提出一個發(fā)人深省的問題或呼吁聽眾采取行動

USER_INPUT:
現(xiàn)在,開發(fā)播客對話。 請使用播客指定的語言
– context: {{context}}
– host:{{host}}
– guest:{{guest}}
– tone:{{tone}}
– 主持人和嘉賓的名字不受語言限制。
– 腳本格式和內(nèi)容:
1. 腳本以主持人說話開始。
2. 主持人和嘉賓之間交替對話,一行在a time
3. 在每行開頭省略發(fā)言者姓名。
4. 使用提供的名稱進(jìn)行主人和客人的自我介紹。
5. 以名字稱呼對方,以營造友好的氛圍。
6. 專注于創(chuàng)建引人入勝的、來回的對話
– 輸出要求:
**腳本格式**:腳本應(yīng)以主持人講話開始。對話應(yīng)由主人和客人輪流進(jìn)行,每次說一行。每行開頭請勿包含說話者姓名。
**輸出要求**:最終腳本應(yīng)僅包含對話內(nèi)容。避免在輸出中包含任何 XML 標(biāo)簽或其他格式。 通過遵循這些說明,您將創(chuàng)建一個內(nèi)容豐富且引人入勝的高質(zhì)量播客腳本
**輸出格式**:參考:
host: 歡迎收聽今天的播客!我是主持人vertigo,很高興今天邀請到了AI數(shù)字人領(lǐng)域的專家bey來和我們聊聊這個令人興奮的話題。bey,歡迎你來到節(jié)目!
guest: 謝vertigo,我很高興能來參加今天的節(jié)目。AI數(shù)字人確實(shí)是一個非常熱門和有前景的領(lǐng)域。

最后你就可以拿到一個對話形式的腳本了:

再然后,就需要通過代碼將開頭是 host和開頭是 guest的內(nèi)容拆開,變成兩個數(shù)組,然后再依次用對應(yīng)的聲音合成。

合成完成后再通過代碼將兩組音頻按照對話的形式排序,最后用merge_audios插件將多個音頻組合成一個完整的音頻。

這樣我們的工作流就搭建完成了!

2. 如何在外部調(diào)用工作流

當(dāng)測試成功并發(fā)布工作流后,在【扣子 API】模塊中可以找到對應(yīng)的調(diào)用接口文檔,這個時候只需授權(quán)令牌、找到工作流調(diào)用的接口文檔,后面就可以讓 Trae 根據(jù)接口文檔來調(diào)用工作流了。

03 開始開發(fā)Chrome 插件

第一版:基礎(chǔ)功能

首先現(xiàn)在電腦上新建一個空白文件夾,然后在 Trae 中打開這個文件夾,然后在對話欄中輸入下面的 prompt:

我想做一款 chrome 插件,使得能夠在閱讀新聞和文章時,通過打開這個插件,能夠新建一個播客任務(wù),將這篇新聞或文章制作成一個播客音頻,然后可以通過播放這個音頻來了解文章內(nèi)容。

這個插件點(diǎn)擊后是一個小彈窗,其中包含以下內(nèi)容:
1.原文標(biāo)題和鏈接(這個輸入框自動帶上當(dāng)前網(wǎng)頁的文章內(nèi)容標(biāo)題、鏈接),展示形式問:
a.文案標(biāo)題:<當(dāng)前網(wǎng)頁的文章內(nèi)容標(biāo)題>
b.鏈接:<當(dāng)前網(wǎng)頁的文章標(biāo)簽>
2.創(chuàng)建播客按鈕,點(diǎn)擊后開始新建播客,制作過程中會有個 loading 的狀態(tài),并且調(diào)用扣子的工作流來實(shí)現(xiàn),后面我會介紹具體調(diào)用方式。
3.任務(wù)列表功能:
a.增加一個創(chuàng)建播客的任務(wù)列表,放置在創(chuàng)建播客的按鈕下方,并用橫線分割。在沒有任務(wù)時默認(rèn)為空,并用灰色字體描述“創(chuàng)建的播客任務(wù)將展示在此處”。
b.當(dāng)用戶點(diǎn)擊了創(chuàng)建播客按鈕后,在任務(wù)列表中新建一個任務(wù),任務(wù)名為“<文章標(biāo)題>的播客”,并在任務(wù)右側(cè)增加 loading 轉(zhuǎn)圈的圖標(biāo)。
c.當(dāng)任務(wù)完成后 loading 圖標(biāo)變成綠色的勾圖標(biāo),點(diǎn)擊后在下方出現(xiàn)剛剛設(shè)計的音頻播放器,點(diǎn)擊后可以進(jìn)行播放等炒作。
d.若任務(wù)失敗,則 loading 圖標(biāo)變成紅色的叉圖標(biāo)
4.保持任務(wù)進(jìn)行功能:
a.當(dāng)鼠標(biāo)點(diǎn)擊非插件區(qū)域?qū)е虏寮棿半[藏時,插件中創(chuàng)建播客和播放音頻的任務(wù)會繼續(xù)進(jìn)行。
b.當(dāng)瀏覽器中切換了 tab 頁面時,之前插件中創(chuàng)建播客和播放音頻的任務(wù)會繼續(xù)進(jìn)行。
c.只有在瀏覽器被關(guān)掉重新打開后,插件里的任務(wù)才會消失。
5.待制作完成后會有一個播放器組件,其中:
a.中間是播放/暫停按鈕,點(diǎn)擊后開始/暫停播放,在沒有播放的時候點(diǎn)擊后開始播放,同時按鈕變成暫停樣式;如果播放過程中點(diǎn)擊按鈕則暫停播放,同時按鈕變成播放樣式;如果播放結(jié)束則按鈕自動變成暫停樣式;
b.左側(cè)是向前返回按鈕,點(diǎn)擊后往前回退10秒并開始播放,如果已經(jīng)播放的總長度不足10秒則從播客第0秒開始從同播放;
c.右側(cè)是向后快進(jìn)按鈕,點(diǎn)擊后向后快進(jìn)10秒并開始播放,如果剩余總長度不足10秒則直接播放完畢;
d.組件右側(cè)有一個下載按鈕,點(diǎn)擊后可以下載對應(yīng)音頻。

調(diào)用扣子的工作流方法你需要參考這個文檔:https://www.coze.cn/open/playground/workflow_run
其中所需的 token:{這里輸入你的 token}
workflow_id:7464076330435903522
parameters:{
“Link”:”<當(dāng)前網(wǎng)頁的網(wǎng)址>”
}

這是一個參考樣式:
curl–XPOST‘https://api.coze.cn/v1/workflow/run’ \
–H“Authorization: Bearer {token}”\
–H“Content-Type: application/json”\
–d ‘{
“parameters”:{
“l(fā)ink”:“https://mp.weixin.qq.com/s/ro6imJKBfEHaX1ETg1MF4g”,
“tone”:“”,
“host_name”:“”,
“guest_name”:“”
},
“workflow_id”:“7464076330435903522”
}‘

好了,我是一個不懂代碼的產(chǎn)品經(jīng)理,下面請你先和我討論清楚產(chǎn)品需求,待我確認(rèn)后再一步步開始

細(xì)心的人會發(fā)現(xiàn)我的 prompt 中還增加了插件中直接播放的功能,但最后上線的版本中沒有,這個稍后我會提到。

再輸入完這一段 prompt 后,Trae 會梳理具體需要做哪一些步驟,并和我確認(rèn),當(dāng)我確認(rèn)之后他就會開始正式開工了!

在開發(fā)的過程中,Trae 會要求你去完成一些操作,比如將圖標(biāo)文件放到指定的文件夾中:

在他完成所有的任務(wù)后,他會要求你在 chrome 中進(jìn)行測試。這時你可以通過 Chrome 的開發(fā)者模式把本地插件加載到 Chrome 中測試,第一版的效果如下:

說實(shí)話還是很驚艷的,能夠滿足我基礎(chǔ)的要求,Trae 牛逼!

當(dāng)驗(yàn)證完沒有問題后,記得把當(dāng)前的內(nèi)容更新到 Readme 中,并且使用 Git 存檔。這里參考了黃叔的《AI 編程藍(lán)皮書》通過以下幾個命令將版本存檔(黃叔的文檔地址:https://superhuang.feishu.cn/wiki/CBBPwvgEuicVhFkx0s7cPmhpn4e),方便后續(xù)回退:

第二版:功能調(diào)整

在完成基礎(chǔ)功能后,發(fā)現(xiàn)了一個嚴(yán)重的問題。創(chuàng)建的播客任務(wù)很容易一直處于“l(fā)oading”狀態(tài),只有在 devtool 打開的情況下才能順利拿到成功或者失敗的結(jié)果。這個問題整整困擾了我 4 天(至今都不知道為什么……),我把這個問題來回地復(fù)述給 Trae 無數(shù)次,每次的結(jié)果都是“我發(fā)現(xiàn)了問題,xxxxxxx”,但是根據(jù)他的要求改了之后并沒有任何區(qū)別。每一次改完不管用之后還要回退到之前的版本重來(在此期間我也嘗試使用了 Cursor,但依然沒有解決)。就當(dāng)我都準(zhǔn)備放棄的時候,我發(fā)現(xiàn)目前的消息傳遞機(jī)制是異步的,但是我提供的后端接口不是,這會導(dǎo)致以下問題:

連蒙帶猜,我將之前采用的同步接口改為異步的,打著最后測試一次,完不成就不做的心態(tài),給 Trae 輸入了以下 prompt:

請將調(diào)用 api 采用異步的方案,所以要做一下調(diào)整:
1.api 接口的入?yún)⒁趙orkflow_id后面加上“is_async”:true;
2.發(fā)送請求后會獲取到execute_id;
3.需要通過查詢工作流異步執(zhí)行的接口來獲取返回的結(jié)果,接口為curl–XGET‘https://api.coze.cn/v1/workflows/7464076330435903522/run_histories/{execute_id}‘ \
–H“Authorization: Bearer {token}”\
–H“Content-Type: application/json”,其中{execute_id}輸入剛剛得到的execute_id:
4.你需要一直輪訓(xùn)去查詢結(jié)果,如果查詢工作流異步執(zhí)行結(jié)果如果任務(wù)再進(jìn)行中時,你查詢后他的輸出如下:{“msg”:“”,“data”:[{“update_time”:1738314930,“execute_status”:“Running”,“connector_uid”:“1344067924934523”,“run_mode”:2,“debug_url”:“https://www.coze.cn/work_flow?execute_id=7466005754399883273&space_id=7405114579312934975&workflow_id=7464076330435903522”,“cost”:“0.00000”,“error_code”:“0”,“execute_id”:“7466005754399883273”,“bot_id”:“0”,“connector_id”:“1024”,“create_time”:1738314930,“token”:“0”,“l(fā)ogid”:“202501311715300E951B760C4EC108D9A0”,“output”:“{\”O(jiān)utput\”:\”null\”}”}],“detail”:{“l(fā)ogid”:“20250131171537BAC478447118616C6E6B”},“code”:0}。

如果他已經(jīng)運(yùn)行成功并返回結(jié)果時,你查詢結(jié)果他的輸出如下:{“code”:0,“msg”:“”,“data”:[{“connector_uid”:“1344067924934523”,“cost”:“0.00000”,“execute_id”:“7466005754399883273”,“l(fā)ogid”:“202501311715300E951B760C4EC108D9A0”,“error_code”:“0”,“error_message”:“”,“connector_id”:“1024”,“execute_status”:“Success”,“debug_url”:“https://www.coze.cn/work_flow?execute_id=7466005754399883273&space_id=7405114579312934975&workflow_id=7464076330435903522”,“create_time”:1738314930,“update_time”:1738315071,“token”:“10114”,“run_mode”:2,“output”:“{\”O(jiān)utput\”:\”{\\\”url\\\”:\\\”https://lf-bot-studio-plugin-resource.coze.cn/obj/bot-studio-platform-plugin-tos/c1b0498f-2c33-4467-804f-9f34ccbbdf83.mp3\\\”}\”}”,“bot_id”:“0”}],“detail”:{“l(fā)ogid”:“20250131171815D45651B07BC4261192F8”}}

請你根據(jù)他返回的結(jié)果來檢查目前有沒有問題

修改之后,插件會每隔 2 秒去調(diào)用查詢接口獲取結(jié)果,最后終于能夠準(zhǔn)確獲取返回結(jié)果了。

除了任務(wù)獲取的問題外,原先我想要插件中能夠播放音頻,并且在插件彈窗消失后能夠持續(xù)后臺播放,但是查了一下貌似現(xiàn)在 Chrome還不支持(不確定是否這樣),而且沒有找到有別的插件有類似的功能。所以我把點(diǎn)擊展開播放器組件調(diào)整成了點(diǎn)擊跳轉(zhuǎn)到音頻頁面:

前面做的很好?,F(xiàn)在我們增加以下功能:
1.在任務(wù)列表的分割線上方增加文字和按鈕:左側(cè)向左對齊增加文字“任務(wù)列表”,右側(cè)向右對齊增加按鈕“清空”。字體大小與副標(biāo)題一致。文字和按鈕常駐在分割線上方。
2.對于制作完成的任務(wù),點(diǎn)擊時會打開一個頁面,頁面地址就是任務(wù)完成后的音頻地址。
請你仔細(xì)寫代碼,不要出現(xiàn)代碼語法上的錯誤

這下整體功能算是全部實(shí)現(xiàn)了。

第三版:優(yōu)化 UI

既然功能都已經(jīng)完成,拿最后就是優(yōu)化一下整體的 UI 界面了。因?yàn)樽约簩?shí)在沒有美感,所以這一步我讓 kimi 來幫我做:

拿著 kimi 給的樣式作為輸入去要求 Trae 修改,沒想到效果確實(shí)還不錯。最后再通過免費(fèi)的漸變背景CSS3樣式 | oulu.me找到了自己比較喜歡的漸變作為背景,最終這款插件就完成了。

本文由 @VerTig0 原創(chuàng)發(fā)布于人人都是產(chǎn)品經(jīng)理。未經(jīng)作者許可,禁止轉(zhuǎn)載

題圖來自Unsplash,基于CC0協(xié)議

該文觀點(diǎn)僅代表作者本人,人人都是產(chǎn)品經(jīng)理平臺僅提供信息存儲空間服務(wù)

更多精彩內(nèi)容,請關(guān)注人人都是產(chǎn)品經(jīng)理微信公眾號或下載App
評論
評論請登錄
  1. 目前還沒評論,等你發(fā)揮!