Rumah >pembangunan bahagian belakang >Golang >Membina CLI Dikuasakan AI dengan Golang dan Google Gemini

Membina CLI Dikuasakan AI dengan Golang dan Google Gemini

王林
王林asal
2024-08-27 13:30:32560semak imbas

Baru-baru ini saya membina CLI berkuasa AI dengan Golang bernama GenCLI, yang mana anda boleh bertanya soalan dalam format teks atau memberikan imej dan meminta butiran mengenainya daripada terminal. Jika itu sesuatu yang menarik untuk anda, blog ini adalah untuk anda. Dalam hal ini, kami membina CLI sepenuhnya dari awal dan memberikannya kuasa AI menggunakan API Gemini Google. Sekiranya anda ingin melihat GenCLI saya di sini adalah pautan Ya, ia adalah sumber terbuka.

Prasyarat

  • Keakraban dengan Golang
  • Pakej Cobra yang telah dicuba

Bermula

Mari kita pergi langkah demi langkah dan fahami setiap proses.

Buat folder dan buka dalam IDE/Editor kegemaran anda. Saya menggunakan Kod VS dan menamakan folder go-ai. Sekarang mulakan projek dengan menjalankan arahan go mod init perintah. Laluan di sini ialah laluan modul. Jika kami menerbitkan modul (projek), ini mestilah laluan dari mana modul kami boleh dimuat turun oleh alat Go. Ini akan menjadi pautan repo GitHub kami. Kita boleh membuat repo GitHub kemudian tetapi kita boleh memberikan pautan sekarang. Bagi saya, ia akan kelihatan seperti ini:

  go mod init github.com/Pradumnasaraf/go-ai 

Setelah anda selesai melakukannya, go.mod akan dibuat.

Building an AI-Powered CLI with Golang and Google Gemini

Walaupun kami boleh mencipta dan melakukan segala-galanya secara manual untuk membina CLI. Tetapi perkara yang menarik tentang Pakej Cobra ialah ia mempunyai CLI yang menjana struktur, menjana fail dan memasang pakej untuk CLI. Ini akan membantu kami mempercepatkan proses dan mengurangkan ralat. Untuk memasang alat Cobra CLI gunakan arahan di bawah:

 go install github.com/spf13/cobra-cli@latest

Sebaik sahaja anda melakukannya, anda boleh menyemak sama ada alat itu dipasang dengan mengikat cobra-cli di terminal dan anda akan mendapat senarai yang tersedia. Sekarang jalankan cobra-cli init untuk menyediakan projek. Selepas menjalankan ia secara automatik akan mencipta folder cmd, go.sum, dan fail main.go. Untuk menguji sama ada ia berfungsi atau tidak jalankan, jalankan main.go. Anda akan melihat output dalam terminal tentang CLI (seperti tangkapan skrin di bawah)

Building an AI-Powered CLI with Golang and Google Gemini

Untuk berkomunikasi dan menggunakan API Gemini Google terlebih dahulu, kita perlu memasang pakej Gemini Golang SKD, untuk melakukannya laksanakan arahan di bawah.

go get github.com/google/generative-ai-go

Kini seperti API lain, kami memerlukan Kunci API. Untuk mendapatkan kepala itu di sini https://aistudio.google.com/app/apikey dan dapatkannya. Ia PERCUMA dan anda mendapatnya dalam 30 Saat. Sebaik sahaja anda mendapat set kunci API ialah pembolehubah persekitaran dengan melaksanakan arahan berikut:

export GEMINI_API_KEY=<YOUR_API_KEY>

Isu dengan kaedah ini ialah pembolehubah persekitaran hanya akan wujud untuk sesi semasa apabila anda menutup terminal ia hilang. Untuk mengelakkan isu ini tambahkan perintah eksport pada fail konfigurasi shell, seperti .bashrc, .bash_profile atau .zshrc (bergantung pada shell anda). Dengan cara ini, anda boleh mengakses CLI dari mana-mana sahaja dalam sistem.

Kini, tiba masanya untuk mencipta sub-perintah untuk CLI dan bukannya menulis logik terus ke root.go. Sebab untuk berbuat demikian ialah jika pada masa hadapan kita ingin memasukkan lebih banyak fungsi dan lebih banyak sub-perintah, kita hanya boleh menambah dengan menambahkan lebih banyak sub-perintah dan tidak menyekat arahan root. Jika anda tidak faham perkara ini, jangan risau ikuti, semuanya akan menjadi jelas.

Untuk mencipta sub-perintah Cobra CLI menyediakan arahan tambah untuk menciptanya. Untuk melakukan itu, laksanakan arahan di bawah. Di sini carian akan menjadi sub-perintah. Anda boleh memilih apa sahaja yang anda suka.

cobra-cli add search

Setelah anda melaksanakannya, fail baharu akan dibuat di bawah direktori cmd dengan semua kod pra-isi ini. Dalam kod tersebut, kami memulakan searchCmd pembolehubah kepada penuding kepada struct cobra.Command dan menyediakan nilai untuk medan seperti, nama sub-perintah, penggunaan, dll. Fungsi dalam Run: akan dicetuskan apabila kami melaksanakan sub- perintah. Juga jika anda melihat kami menambah arahan (sub-perintah) untuk arahan akar dalam fungsi init. Beginilah kod lengkap sepatutnya.

package cmd

import (
    "fmt"

    "github.com/spf13/cobra"
)

// searchCmd represents the search command
var searchCmd = &cobra.Command{
    Use:   "search",
    Short: "A brief description of your command",
    Long: `A longer description that spans multiple lines and likely contains examples`,
    Run: func(cmd *cobra.Command, args []string) {
        fmt.Println("search called")
    },
}

func init() {
    rootCmd.AddCommand(searchCmd)
}

Untuk menyemak sama ada sub-perintah "carian berfungsi seperti yang diharapkan, kini jalankan CLI dengan arahan "carian", dan anda akan melihat "carian dipanggil" dicetak dalam terminal anda.

go run main.go search 

Sekarang, mari kita bekerja di bahagian API. Mari Import pakej untuk API Google Gemini serta lain-lain yang diperlukan untuk tugasan pengelogan dan tahap os. Berikut ialah senarai lengkap.

import (
    "context"
    "log"
    "os"

    "github.com/google/generative-ai-go/genai"
    "github.com/spf13/cobra"
    "google.golang.org/api/option"
)

Kemudian mari tambah fungsi yang dipanggil getResponse. Fungsi ini akan membantu kami berkomunikasi dengan API Gemini, mendapatkan respons dan mencetaknya. Selain itu, jika anda melihat kami telah mengekodkan teks Prompt - "Tulis cerita tentang AI dan sihir", jangan risau, kami akan mengubahnya tetapi mari kita mulakan ia berfungsi :). Ini ialah kod fungsi lengkap tambahkannya di bawah fungsi init anda. Anda akan menemui kod permulaan yang sama di tapak web Gemini.

func getResponse() {

    ctx := context.Background()
    client, err := genai.NewClient(ctx, option.WithAPIKey(os.Getenv("GEMINI_API_KEY")))
    if err != nil {
        log.Fatal(err)
    }
    defer client.Close()

    model := client.GenerativeModel("gemini-1.5-flash")
    resp, err := model.GenerateContent(ctx, genai.Text("Write a story about a AI and magic"))
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(resp.Candidates[0].Content.Parts[0])
}

Now let's add getResponse function to the in the field Run: function. So that when we run the sun command it will call getResponse function. Now the code will look like this.

package cmd

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/google/generative-ai-go/genai"
    "github.com/spf13/cobra"
    "google.golang.org/api/option"
)

// searchCmd represents the search command
var searchCmd = &cobra.Command{
    Use:   "search",
    Short: "A brief description of your command",
// Added the getResponse() function
    Run: func(cmd *cobra.Command, args []string) {
        getResponse()
    },
}

func init() {
    rootCmd.AddCommand(searchCmd)
}

func getResponse() {

    ctx := context.Background()
    client, err := genai.NewClient(ctx, option.WithAPIKey(os.Getenv("GEMINI_API_KEY")))
    if err != nil {
        log.Fatal(err)
    }
    defer client.Close()

    model := client.GenerativeModel("gemini-1.5-flash")
    resp, err := model.GenerateContent(ctx, genai.Text("Write a story about a AI and magic"))
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(resp.Candidates[0].Content.Parts[0])
}

If you getting a red squiggly line under the imported package names run go mod tidy. It will install the missing package and do a cleanup. Now, again execute the go run main.go search. This time you will get a response from the API for the Prompt we hardcoded, i.e, "Write a story about a AI and magic"

Building an AI-Powered CLI with Golang and Google Gemini

In case you are encountering the below error check if your environment variable is set properly with the right name. You can check by executing the printenv command in your terminal and see if it's present there or not.

Building an AI-Powered CLI with Golang and Google Gemini

Once everything is working, let’s make the prompt dynamic so that we don’t have to hardcode the prompt directly into the code and we provide it via the terminal.

To do that, add an ARG: field to the searchCmd struct so that the user at least needs to enter an argument after the sub-command. Also, we will modify the getResponse function to accept a slice of data because args will be in the slice format, and we will use the strings package to convert it into a sentence.

Lastly, replace the hardcoded text in genai.Text() with the userArgs variable we created to convert the slice into a sentence. This is how the complete code will look like; I have commented above on the changes we have to make for better understanding.

package cmd

import (
    "context"
    "fmt"
    "log"
    "os"
    "strings" // import strings package

    "github.com/google/generative-ai-go/genai"
    "github.com/spf13/cobra"
    "google.golang.org/api/option"
)

var searchCmd = &cobra.Command{
    Use:   "search",
    Short: "A brief description of your command",
    Args:  cobra.MinimumNArgs(1), // Minimum 1 arg required
    Run: func(cmd *cobra.Command, args []string) {
        getResponse(args)
    },
}

func init() {
    rootCmd.AddCommand(searchCmd)
}

// Function can now accept slice parameter 
func getResponse(args []string) {
        // Creating a sentence out of a slice
    userArgs := strings.Join(args[0:], " ") 

    ctx := context.Background()
    client, err := genai.NewClient(ctx, option.WithAPIKey(os.Getenv("GEMINI_API_KEY")))
    if err != nil {
        log.Fatal(err)
    }
    defer client.Close()

    model := client.GenerativeModel("gemini-1.5-flash")
        // change the hardcoded text to userArgs variable
    resp, err := model.GenerateContent(ctx, genai.Text(userArgs))
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(resp.Candidates[0].Content.Parts[0])
}

If you execute the go run main search now, it will give you an error message in the terminal saying at least one arg is required. This means our code is working perfectly.

Building an AI-Powered CLI with Golang and Google Gemini

Now let's execute the command the right way giving it an argument - a prompt/question.

Building an AI-Powered CLI with Golang and Google Gemini

As you can see, it provided us with the answer. We pass the prompt in quotes so that we can add special characters like "?", ".", etc. So here it is, a fully functional AI-powered CLI.

Now, if you want to publish the package so that your CLI can directly execute commands and be used from anywhere in the system, it’s very simple to do that. First, push your changes to GitHub and then head over to the URL https://pkg.go.dev/github.com/. In my case, it would be https://pkg.go.dev/github.com/Pradumnasaraf/go-ai. When you visit, you will see a request button; click on that to request adding the package to pkg.go.dev. Once you’re done, after a few hours, it will be on the website.

Building an AI-Powered CLI with Golang and Google Gemini

Once it’s live, you can simply download the CLI by using the go install command:

go install <repo-url>
go install github.com/Pradumnasaraf/go-ai@latest

And directly use the CLI with commands like go-ai, go-ai search, etc. If you encounter the error saying command not found: go-ai after running it, you need to add $GOPATH/bin to your $PATH environment variable. Refer to this guide for that.

That's it for this blog. This was a little longer than the blogs I usually write. I'm glad you're still reading and made it to the end—thank you so much for your support. I sometimes share tips on Twitter. You can connect with me there.

Atas ialah kandungan terperinci Membina CLI Dikuasakan AI dengan Golang dan Google Gemini. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn