自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

與AI結(jié)對(duì):一位高級(jí)開(kāi)發(fā)人員構(gòu)建插件的歷程

人工智能
James 使用 ChatGPT 來(lái)啟動(dòng)訪問(wèn)者模式在 Go 中的慣用實(shí)現(xiàn)。這包括學(xué)習(xí)如何為訪問(wèn)者函數(shù)定義一個(gè)類(lèi)型,然后聲明一個(gè)函數(shù)來(lái)滿足類(lèi)型。

作者分享了他使用 ChatGPT 學(xué)習(xí) Go、瀏覽 Kolide API 以及構(gòu)建一個(gè)復(fù)雜的 Steampipe 插件的經(jīng)驗(yàn)。

譯自Pairing With AI: A Senior Developer's Journey Building a Plugin,作者 Jon Udell。

雖然改進(jìn)開(kāi)發(fā)人員文檔始終有幫助,但許多人(包括我自己)更喜歡在實(shí)踐中學(xué)習(xí)。這是我在七項(xiàng)指導(dǎo)原則中提出的第七項(xiàng),也是最重要的一項(xiàng):因?yàn)槟阍诿嫦蛉蝿?wù)的可教授時(shí)刻獲取知識(shí),所以學(xué)習(xí)不是前瞻性的,而是直接且切實(shí)的。

當(dāng)經(jīng)驗(yàn)豐富的開(kāi)發(fā)人員與 LLM 合作時(shí),其機(jī)器智能會(huì)支持并增強(qiáng)你的智力。

好處對(duì)我來(lái)說(shuō)很明顯。在 LLM 時(shí)代編寫(xiě)Steampipe 的 ODBC 插件比我在沒(méi)有此類(lèi)幫助的情況下編寫(xiě)插件的體驗(yàn)容易得多。但那公認(rèn)是一個(gè)主觀評(píng)估,所以我一直在尋找一個(gè)機(jī)會(huì)與另一位插件開(kāi)發(fā)人員比較筆記,當(dāng)James Ramirez在我們的社區(qū) Slack 中出現(xiàn)并宣布一個(gè)新插件用于Kolide API時(shí)。我邀請(qǐng)他告訴我他構(gòu)建它的經(jīng)歷,他親切地帶我進(jìn)行了一次與 ChatGPT 的長(zhǎng)時(shí)間對(duì)話,在此對(duì)話中,他熟悉了三個(gè)對(duì)他來(lái)說(shuō)都是新知識(shí)的技術(shù)領(lǐng)域:Kolide API、Go 語(yǔ)言和 Steampipe 插件架構(gòu)。

作為一個(gè)額外的挑戰(zhàn):雖然插件開(kāi)發(fā)人員通常為其插件針對(duì)的 API 找到合適的 Go SDK,但這里并非如此。因此,有必要為 Kolide API 創(chuàng)建一個(gè) Go 封裝,然后將其集成到插件中。

測(cè)試 ChatGPT 的 Go 能力

James 從一些熱身練習(xí)開(kāi)始。首先,為了測(cè)試 ChatGPT 的 Go 能力,他提供了一對(duì) Go 函數(shù),他編寫(xiě)了這些函數(shù)來(lái)調(diào)用相關(guān)的 API/devices/和/devices/ID,并要求對(duì)它們之間的共享邏輯進(jìn)行慣用重構(gòu)。

接下來(lái),他使用簡(jiǎn)單的可變參數(shù)而不是更復(fù)雜的函數(shù)選項(xiàng)模式探索了函數(shù)的可選參數(shù),并確定了簡(jiǎn)單的方法——使用Search結(jié)構(gòu)的切片來(lái)封裝 Kolide 的查詢參數(shù)的字段/運(yùn)算符/值樣式——就足夠了。他要求一個(gè)函數(shù)將Search結(jié)構(gòu)的切片序列化為一個(gè) REST URL,然后優(yōu)化 ChatGPT 提出的版本以創(chuàng)建最終的serializeSearches,該版本增加了對(duì)將友好名稱映射到參數(shù)的支持并使用字符串構(gòu)建器。

AI 處理吹毛求疵,并經(jīng)常提供可提交的建議。

其中一些優(yōu)化,包括使用字符串構(gòu)建器,是由 AI 驅(qū)動(dòng)的機(jī)器人CodeRabbit提出的,它提供了有用的代碼審查。他說(shuō),這是幫助你和你的團(tuán)隊(duì)專注于全局的反饋,因?yàn)樗幚泶得蟠茫⒔?jīng)常(但并非總是)提供可提交的建議。它還采取更廣泛的視角來(lái)總結(jié)拉取請(qǐng)求并評(píng)估已關(guān)閉的 PR 是否解決了其關(guān)聯(lián)問(wèn)題中陳述的目標(biāo)。

映射運(yùn)算符

他繼續(xù)探索將 Steampipe 運(yùn)算符(如QualOperatorEqual)映射到 Kolide 運(yùn)算符(如Equals)的方法。同樣,ChatGPT 提出的方法也變成了一個(gè)一次性方案,朝著一個(gè)干凈簡(jiǎn)單的方案前進(jìn)。但正如 James 在我們的采訪中證實(shí)的那樣,由于你無(wú)論如何都會(huì)迭代一次性版本,所以能夠生成合理的迭代而不是通過(guò)手工更繁瑣地對(duì)它們進(jìn)行編碼是有幫助的。在此過(guò)程中,他正在學(xué)習(xí)基本的 Go 慣用語(yǔ)。

James:

Go 中有 do-while 循環(huán)嗎?

ChatGPT

沒(méi)有,但是……

James:

Go 中有三元運(yùn)算符嗎?

ChatGPT

沒(méi)有,但是……

James:

我如何追加到map[string]string?

ChatGPT

像這樣……

使用反射增強(qiáng)的訪問(wèn)者模式

在理解了基礎(chǔ)知識(shí)并為 Kolide API 開(kāi)發(fā)了一個(gè) Go 客戶端后,James 準(zhǔn)備解決插件開(kāi)發(fā)的實(shí)際工作:定義從 API 封裝返回的 Go 類(lèi)型映射到控制針對(duì)這些表的 SQL 查詢的 Steampipe 架構(gòu)的表。

與所有插件開(kāi)發(fā)者一樣,他從一個(gè)可以列出資源集的表開(kāi)始,然后通過(guò)過(guò)濾和分頁(yè)對(duì)其進(jìn)行增強(qiáng)。在添加第二個(gè)表后,是時(shí)候考慮如何抽象出公共模式和行為。最終結(jié)果是訪問(wèn)者模式的優(yōu)雅實(shí)現(xiàn)。以下是與表kolide_device和kolide_issue相對(duì)應(yīng)的 SteampipeList函數(shù)。

func listDevices(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {
  var visitor ListPredicate = func(client *kolide.Client, cursor string, limit int32, searches ...kolide.Search) (interface{}, error) {
    return client.GetDevices(cursor, limit, searches...)
  }


  return listAnything(ctx, d, h, "kolide_device.listDevices", visitor, "Devices")
}




func listAdminUsers(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {
  var visitor ListPredicate = func(client *kolide.Client, cursor string, limit int32, searches ...kolide.Search) (interface{}, error) {
    return client.GetAdminUsers(cursor, limit, searches...)
  }


  return listAnything(ctx, d, h, "kolide_admin_user.listAdminUsers", visitor, "AdminUsers")
}

以下是所有插件表通用的列表清單函數(shù)。

func listAnything(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData, callee string, visitor ListPredicate, target string) (interface{}, error) {
  // Create a slice to hold search queries
  searches, err := query(ctx, d)
  if err != nil {
    plugin.Logger(ctx).Error(callee, "qualifier_operator_error", err)
    return nil, err
  }


  // Establish connection to Kolide client
  client, err := connect(ctx, d)
  if err != nil {
    plugin.Logger(ctx).Error(callee, "connection_error", err)
    return nil, err
  }


  // Iterate through pagination cursors, with smallest number of pages
  var maxLimit int32 = kolide.MaxPaging
  if d.QueryContext.Limit != nil {
    limit := int32(*d.QueryContext.Limit)
    if limit < maxLimit {
      maxLimit = limit
    }
  }


  cursor := ""


  for {
    // Respect rate limiting
    d.WaitForListRateLimit(ctx)


    res, err := visitor(client, cursor, maxLimit, searches...)
    if err != nil {
      plugin.Logger(ctx).Error(callee, err)
      return nil, err
    }


    // Stream retrieved results
    collection := reflect.ValueOf(res).Elem().FieldByName(target)
    if collection.IsValid() {
      for i := 0; i < collection.Len(); i++ {
        d.StreamListItem(ctx, collection.Index(i).Interface())


        // Context can be cancelled due to manual cancellation or the limit has been hit
        if d.RowsRemaining(ctx) == 0 {
          return nil, nil
        }
      }
    }


    next := reflect.ValueOf(res).Elem().FieldByName("Pagination").FieldByName("NextCursor")
    if next.IsValid() {
      cursor = next.Interface().(string)
    }


    if cursor == "" {
      break
    }
  }


  return nil, nil
}

有了此設(shè)置,向插件添加新表幾乎完全是聲明式的:你僅需定義架構(gòu)及 KeyColumns,以及在 SQL 查詢中的 where(或 join)子句與 API 級(jí)過(guò)濾器之間形成橋梁的相關(guān)運(yùn)算符。然后編寫(xiě)一個(gè)微小的 List 函數(shù),該函數(shù)定義一個(gè)訪問(wèn)器,并將該函數(shù)傳遞到 common listAnything 函數(shù)中,該函數(shù)封裝查詢參數(shù)編組、連接至 API 客戶端、調(diào)用 API、將響應(yīng)解壓縮到一個(gè)集合中以及迭代集合以將數(shù)據(jù)項(xiàng)傳輸?shù)?Steampipe 的外部數(shù)據(jù)包裝器的功能。

James 使用 ChatGPT 來(lái)啟動(dòng)訪問(wèn)者模式在 Go 中的慣用實(shí)現(xiàn)。這包括學(xué)習(xí)如何為訪問(wèn)者函數(shù)定義一個(gè)類(lèi)型,然后聲明一個(gè)函數(shù)來(lái)滿足類(lèi)型。每個(gè)表的訪問(wèn)者都封裝對(duì) API 客戶端的調(diào)用,并返回一個(gè)接口。所有這些都相當(dāng)通用,但訪問(wèn)者的響應(yīng)特定于包裝的 API 響應(yīng)的 Go 類(lèi)型,這意味著需要為每個(gè)表編寫(xiě)一個(gè)不同的 List 函數(shù)。如何避免這種情況?James 問(wèn)道:“res 變量上的字段引用需要是可變類(lèi)型,在執(zhí)行時(shí)指定。你能建議一種方法嗎?”

ChatGPT 的建議(他采納了)是使用反射,以便調(diào)用 listAnything(如 listAnything(ctx, d, h, “kolide_device.listDevices”, visitor, “Devices”))可以傳遞一個(gè)名稱("Devices"),使 listAnything 能夠以與類(lèi)型無(wú)關(guān)的方式訪問(wèn)響應(yīng)結(jié)構(gòu)的字段,例如,此處的 Devices 字段。

type DeviceListResponse struct {
      Devices    []Device   `json:"data"`
      Pagination Pagination `json:"pagination"`
    }

正因如此,listAnything 終于如其名,成為一個(gè)通用的 Steampipe List 函數(shù)。該解決方案很少使用反射,并在 API 層和 Steampipe 層中都保留了 Go 的強(qiáng)類(lèi)型檢查。

LLM 協(xié)助真正意味著什么?

它肯定不意味著 LLM 根據(jù)以下提示編寫(xiě)了一個(gè)體現(xiàn)復(fù)雜設(shè)計(jì)模式的插件:“我需要一個(gè)用于 Kolide API 的 Steampipe 插件,請(qǐng)創(chuàng)建它。”對(duì)我來(lái)說(shuō),以及對(duì) James 來(lái)說(shuō),它的含義更有趣:“讓我們討論為 Kolide API 編寫(xiě)插件的過(guò)程?!边@就像與一只橡皮鴨交談,以便大聲思考需求和策略。但 LLM 是一只會(huì)說(shuō)話的橡皮鴨。有時(shí)響應(yīng)直接適用,有時(shí)不適用,但無(wú)論哪種方式,它們通常可以幫助你獲得清晰度。

作為一名經(jīng)驗(yàn)豐富的軟件工程師,James 本可以想出辦法——但這需要更長(zhǎng)的時(shí)間。

James 說(shuō):“對(duì)話要求我對(duì)所問(wèn)的問(wèn)題非常具體?!彪m然他從頭開(kāi)始使用 Go,但他帶來(lái)了豐富的經(jīng)驗(yàn),使他能夠快速定位并找出哪些是需要問(wèn)的正確問(wèn)題。作為一名經(jīng)驗(yàn)豐富的軟件工程師,James 本可以自己想出所有這些。但這需要更長(zhǎng)的時(shí)間,而且他將花費(fèi)大量時(shí)間預(yù)先閱讀文章和文檔,而不是通過(guò)實(shí)踐學(xué)習(xí)。而且可能沒(méi)有時(shí)間!正如我現(xiàn)在從許多其他人那里聽(tīng)到的那樣,LLM 提供的加速通常決定了擁有一個(gè)想法和能夠執(zhí)行它之間的區(qū)別。

James 還提到了我未考慮過(guò)的開(kāi)源角度。在 LLM 之前,他不會(huì)以完全公開(kāi)的方式完成這項(xiàng)工作?!拔視?huì)一直保密,直到我更有信心,”他說(shuō),“但這從一開(kāi)始就在那里,我很高興它在那里?!边@使得與 Turbot 團(tuán)隊(duì)的接觸盡早成為可能。

這不是一個(gè)自動(dòng)化故事,而是一個(gè)增強(qiáng)故事。當(dāng)像 James Ramirez 這樣的經(jīng)驗(yàn)豐富的開(kāi)發(fā)人員與 LLM 合作時(shí),其機(jī)器智能支持并放大了他的智力。兩者協(xié)同工作——不僅編寫(xiě)代碼,更重要的是,思考架構(gòu)和設(shè)計(jì)。

     

責(zé)任編輯:武曉燕 來(lái)源: 云云眾生s
相關(guān)推薦

2024-01-04 10:02:55

開(kāi)發(fā)插件

2019-08-07 11:00:07

程序員技能開(kāi)發(fā)者

2013-09-25 09:20:39

iOS開(kāi)發(fā)iOS7iPhone5s

2010-08-09 16:09:25

2025-04-09 08:10:00

AI代碼生成器網(wǎng)絡(luò)安全人工智能

2012-05-30 15:15:42

ibmdw

2023-03-15 07:12:53

企業(yè)開(kāi)發(fā)人員提供商

2009-12-11 14:50:14

Visual Basi

2009-11-23 20:07:51

ibmdw開(kāi)發(fā)

2021-02-19 09:33:01

kubernetesJAVA服務(wù)

2020-01-27 16:28:57

開(kāi)發(fā)命令遠(yuǎn)程服務(wù)器

2021-01-30 10:51:07

Python編程語(yǔ)言開(kāi)發(fā)

2022-02-17 16:05:58

SQL開(kāi)發(fā)招聘

2024-09-27 17:06:13

2012-12-14 08:55:45

開(kāi)發(fā)人員產(chǎn)品經(jīng)理

2010-08-16 09:21:35

Windows Pho

2009-07-20 16:11:41

JRuby Swing

2021-12-10 23:48:19

Java開(kāi)發(fā)技術(shù)

2023-02-17 15:01:15

2021-02-16 16:44:40

RustJavaScript開(kāi)發(fā)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)