您好,登錄后才能下訂單哦!
今天小編給大家分享一下與ChatGPT結對編程怎么實現的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
我們以dsl_translator這個節點為例,一開始,我只是這么提問(并沒有,我只是演示一個錯誤示范):
我想用nodeJS用下面的yaml描繪的數據結構得到一個新的數組:
base: steps: 10 batch_size: 1 poly: - template_prompt: template: > a cat, ${ chara } ${ facial_expressions } meta: view_angle: - side_view, - front_view, faal_expressions: - (smile:1.5), - (smile:1.2), - smile,
果然,ChatGPT也不慣著我,給出了我下面的代碼:
//...... const newArray = []; data.poly.forEach(item => { const obj = { template: item.template_prompt.template, meta: item.template_prompt.meta }; newArray.push(obj); }); console.log(newArray);
我仿佛聽到AI在說:“你就說是不是數組吧,你要數組,我給你數組,沒毛病~”
遇到這種問題,只能反思是自己沒說清楚,那么該怎么說清楚呢?
我們這個程序是服務于AI畫圖的,其實我們也可以從AI畫圖中借鑒不少經驗,比如說在AI畫圖中,有一個control net里的open pose技術,我可以畫個骨架,就像下面這樣:
我就可以用這個骨架圖去畫個穿靴子的貓,拿著個刺劍什么的。這個技術告訴我們什么呢?我們可以通過描述一個骨架來控制AI生成的內容。那么圖片可以,編程是不是也可以?
于是經過一段時間的摸索,最后我寫出了下面的描述:
我想用nodeJS用下面的yaml描繪的數據結構得到一個新的數組:
base: steps: 10 batch_size: 1 poly: - template_prompt: template: > a cat, ${ chara } ${ facial_expressions } meta: chara: - Abyssinian, - cat_in_boots, facial_expressions: - (smile:1.5), - (smile:1.2), - smile,
要求:
假設上面的yaml轉成json的轉換代碼我已經寫完了
我需要遍歷poly下的所有的頂層元素
遍歷過程中,要處理template_prompt元素的子元素:
從template中讀取作為模版。
讀取meta中的屬性,因為屬性可能每次都不一樣,是不確定的,所以不能硬編碼。
然后基于meta中的屬性,把template作為 string literal 解析,這個解析代碼我已經有了,假設名為render_string_template,可以不實現,留一個函數接口即可。
要遍歷組合meta中的屬性形成一個數組,比如chara 有兩個值,facial_expressions 有三個值,那么應該生成2*3也就是六組屬性放入這個數組中,這個數組和template會被傳入render_string_template函數,最后會獲得兩個prompt字符串
將生成的prompt字符串數組和template_prompt元素之外的其他元素合并成一個對象,要求在同一級別。prompt字符串數組有幾個元素,就會合并成幾個對象,并放入一個新數組中,我們稱之為ploys。
繼續遍歷,直到遍歷完所有頂層元素,所有元素都放入了polys中。polys是一個一維數組。
將ploys中的每一個元素與base中的屬性合成一個新的對象,base的屬性展開與prompt屬性同級,當ploys中的每一個元素的屬性名與base中的屬性名相同時,覆蓋base中的屬性。這些新對象組合出的數組就是我要的數組
可以看到,我在之前的prompt的后面加了很多的描述,其中的2-6就是用自然語言講了我期望這個函數實現整個過程的大概邏輯。這個手法就很像Open Pose。通過這個操作,我得到了我想要的代碼,畢竟這個邏輯不復雜。
上面prompt的要求里除了表達了主干邏輯,其實也用了一些其他的技巧。比如“1. 假設上面的yaml轉成json的轉換代碼我已經寫完了”,“把template作為 string literal 解析,這個解析代碼我已經有了,假設名為render_string_template,可以不實現,留一個函數接口即可。”
這個呢有點像control net里的seg技術,他就是把圖片上的東西都分區域,就像下面這樣:
然后再生成的就靠譜很多,甚至你還可以對其中特定部分進行針對性的描述。這個技術就很適合用來控制AI生成的注意力焦點。
那么在我們這個例子,上面提到的那些描述就起到了seg的作用。他可以讓我們不用在一個prompt描述里編寫所有的細節,這對于復雜的邏輯很有幫助。因為即便是一個小節點,其實邏輯也可能有點復雜的,就像這里面,我們可以把meta數據與tempalte合并的功能延遲實現,只描述與他的交互,使生成的程序先把參數扔給它。有的時候,我們想要使用特定的庫,也可以用這個方式,比如我在另外一個場景下是這么實現的這個效果:
1. 讀取文件的fs,要使用const fs = require('fs/promise')引入。
2. 用js-yaml庫解析yaml。
通過這樣的技巧,我們就可以把代碼進行進一步的分解,讓我們更容易描述清楚我們想要部分的業務邏輯,而且也可以給我們節省點算力,畢竟ChatGPT生成的時候如果太長也會中斷,你讓他繼續的話,有時候也續不上。這個技巧就可以讓他專注于你希望他專注的地方,從而提高表現力。
上面的寫完之后呢,我發現一個問題,這個DSL還不是我想要的最終形態,對于同一套模板,我可能需要多種meta,因為有些屬性的組合是沒有意義的,我也不想浪費我寶貴的GPU。那么我們就不能太暴力的讓它窮舉所有的組合,我要針對同一個tempalte給他不同的屬性組合,所以meta的值就必須是個列表,大概如下所示:
base: steps: 10 batch_size: 1 poly: - template_prompt: template: > a cat, ${ chara } ${ facial_expressions } meta: - chara: # 這里改成了數組 - Abyssinian, - cat_in_boots, facial_expressions: - (smile:1.5), - (smile:1.2), - smile,
于是現在我們就面臨一個問題:改代碼。而這個時候就體現出我們之前拆任務的價值了,因為各個模塊都是隔離的,那就沒有什么改代碼,重新生成一份就好了,所以我改了改要求:
要求:
假設上面的yaml轉成json的轉換代碼我已經寫完了
我需要遍歷poly下的所有的頂層元素
遍歷過程中,要處理template_prompt元素的子元素:
從template中讀取作為模版。
讀取meta中的屬性,因為屬性可能每次都不一樣,是不確定的,所以不能硬編碼。
然后基于meta中的屬性,把template作為 string literal 解析,這個解析代碼我已經有了,假設名為render_string_template,可以不實現,留一個函數接口即可。
要遍歷組合meta中的每一個屬性組形成一個數組,
每一個屬性組可能只需要看做一個對象,當且僅當每一個屬性值都為單值
每一個屬性組可能也需要展開,當且僅當任何一個屬性值有多值,比如 chara 有兩個值,facial_expressions 有三個值,那么應該生成2*3也就是六組屬性放入這個數組中,這個數組和template會被傳入render_string_template函數,最后會獲得兩個prompt字符串
將生成的prompt字符串數組和template_prompt元素之外的其他元素合并成一個對象,要求在同一級別。prompt字符串數組有幾個元素,就會合并成幾個對象,并放入一個新數組中,我們稱之為ploys。
繼續遍歷,直到遍歷完所有頂層元素,所有元素都放入了polys中。polys是一個一維數組。
將ploys中的每一個元素與base中的屬性合成一個新的對象,base的屬性展開與prompt屬性同級,當ploys中的每一個元素的屬性名與base中的屬性名相同時,覆蓋base中的屬性。這些新對象組合出的數組就是我要的數組
改完要求,配上上面的DSL直接扔給了它,得到了我們想要的代碼。
所以在今天這個時刻,有些重構工作突然變得沒有那么大價值了,因為在劃定好的邊界里,重寫比重構更快,盡管兩次輸出的代碼并不一樣,但是他們的功能是一樣的。
以上就是“與ChatGPT結對編程怎么實現”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。