Ernesto Ponce
Posted on March 5, 2023
In this tutorial we are going to create a simple golang command line program that uses the openAI API to recreate a similar funcionality of the chatgpt web.
https://chat.openai.com/chat
We will see this
- OpenAI apikey setup
- Setup base golang project
- Get input from terminal
- Send question to openAI API
- Show the results
This is the final result of the app
This gif was created using the vhs amazing tool.
https://github.com/charmbracelet/vhs
The funcionality is pretty simple.
- Execute a binary program.
- Ask a question, then press enter.
- The program send a questions to the openAI API and show the response, all on the terminal.
OpenAI apikey
In order to complete this tutorial you must obtain a apikey,
go to openAI and get a new one
https://platform.openai.com/account/api-keys
Be sure that you save the apikey in some place, because they will show you it only once time.
Setup project
Go to your terminal, and run this command in order to create a folder and go inside
mkdir chatgptcli && cd chatgptcli
After that, init a go module
go mod init chatgptcli
Create a main.go file
touch main.go
Get input from on terminal
In the main.go file add this code.
func main() {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Ask to chat gpt: ")
text, err := reader.ReadString('\n')
if err != nil {
panic(err)
}
fmt.Println("User input:", text)
}
We created a reader object passing the os.Stdin as parameter in order to obtain the input from the command line.
After we use the ReadString that reads the input until a break line ( Enter key pressed ) is found, this is defined by the parameter '\n'.
If we have an error we finish the programa using a call to a panic function, this is not the most elegant way to manage this but for the purpose of the tutorial is enough.
After that we only print on console the user input text.
Send question to openAI API
We will use this great library to connect to the openAPI API
https://github.com/sashabaranov/go-openai
That bring us a nice interface to connect to the api without the need to know all the params, configurations, etc, that the openAI required for work.
This is the official documentation if you want to take a look.
https://platform.openai.com/docs/api-reference/chat
Add the library to the project
go get github.com/sashabaranov/go-openai
Add this code to main function on file main.go
func main() {
// previous code
// [...]
c := openai.NewClient("youropenaitoken"))
resp, err := c.CreateChatCompletion(
context.Background(),
openai.ChatCompletionRequest{
Model: openai.GPT3Dot5Turbo,
Messages: []openai.ChatCompletionMessage{
{
Role: "user",
Content: text,
},
},
},
)
if err != nil {
panic(err)
}
fmt.Println(resp.Choices[0].Message.Content)
fmt.Println()
}
This block of code create a newClient using the openAI token, in this project we hardcode this value but if you use this in a project ṕlease consider to use an environment variable instead of this.
We use the method createChatCompletion and the model openai.GPT3Dot5Turbo as our configuration.
The official definition for this model is the following
A set of models that improve on GPT-3 and can understand as well as generate natural language or code
There are more options to choose
- DALL-E
- Whisper
- Codex
- etc
https://platform.openai.com/docs/models/overview
All of them or at least most of them are available to use with the library.
Run program with this command
go run main.go
That works fine but we have a problem, after the response for the API appears in the terminal, the programs finish and if we want to ask another question we have to open the program again.
We can change this behaviour and prevent that, adding a little change.
Add a "for" that wraps all main code.
func main() {
for {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Ask to chat gpt: ")
text, err := reader.ReadString('\n')
if err != nil {
fmt.Println("Error reading input:", err)
return
}
fmt.Println("Input text:", text)
c := openai.NewClient("youropenaitoken")
resp, err := c.CreateChatCompletion(
context.Background(),
openai.ChatCompletionRequest{
Model: openai.GPT3Dot5Turbo,
Messages: []openai.ChatCompletionMessage{
{
Role: "user",
Content: text,
},
},
},
)
if err != nil {
panic(err)
}
fmt.Println(resp.Choices[0].Message.Content)
fmt.Println()
}
}
The for loops run infinitely ( like a "while true" in other languages ) and the promp to enter text will appears after see the results from the API, with than change now we have to close the program using CTRL+C.
So, that is all for now, you can see all the code in this gist.
https://gist.github.com/ernesto27/6aadbb2ed8169294c375505733381f16
This program works fine, but we can make some improvements for future tutorials, for example.
- The conversation starts from scratch always, i am not sure if is possible to mantain a conversation with the API.
- We can improve how the text looks in the terminal.
- We can configure the program to use a env variable instead of hardcode token.
You also can find a more complete version of this program on this repository.
https://github.com/ernesto27/chatgpt-cli
Posted on March 5, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.