Trong thời đại hiện nay, AI đã và đang len lỏi vào hầu hết các lĩnh vực công nghệ, từ các ứng dụng web, hệ thống khuyến nghị, đến những công cụ hỗ trợ cá nhân hóa công việc. Một trong những hướng đi ngày càng phổ biến đó là việc xây dựng các CLI có khả năng tương tác với AI để hỗ trợ công việc hàng ngày như viết tài liệu, tra cứu kiến thức, dịch ngôn ngữ, hoặc thậm chí là viết code mẫu.
Trong bài viết này, chúng ta sẽ cùng tìm hiểu cách xây dựng một ứng dụng CLI đơn giản sử dụng ngôn ngữ lập trình Golang, kết hợp với Google Gemini – một trong những nền tảng AI tiên tiến do Google phát triển. Ứng dụng mà chúng ta sẽ tạo ra có thể giúp bạn gửi câu hỏi trực tiếp đến AI từ dòng lệnh và nhận lại phản hồi một cách nhanh chóng, hiệu quả.
Giới thiệu Google Gemini

Google Gemini là tên thương hiệu của dòng mô hình trí tuệ nhân tạo mới nhất của Google DeepMind, kế thừa từ PaLM. Với khả năng xử lý ngôn ngữ tự nhiên mạnh mẽ, Gemini cho phép lập trình viên tương tác dễ dàng với AI thông qua API, phục vụ nhiều mục đích như:
- Viết nội dung tự động (blog, bài thơ, bài viết…).
- Dịch thuật và diễn giải văn bản.
- Hỏi – đáp kiến thức.
- Sinh code mẫu, trợ giúp kỹ thuật.
- Tóm tắt văn bản.
Google cung cấp API dựa trên HTTP hoặc SDK chính thức, trong đó có thư viện Go giúp việc tích hợp vào ứng dụng Golang dễ dàng hơn.
Giới thiệu Cobra – thư viện xây dựng CLI

Cobra là một thư viện mạnh mẽ và phổ biến dùng để xây dựng các công cụ dòng lệnh trong Golang. Nó hỗ trợ cấu trúc phân chia lệnh (command
), cờ (flags
), sinh help text tự động và rất dễ mở rộng. Các công cụ nổi tiếng như kubectl
, hugo
đều được viết bằng Cobra.
Cobra cho phép bạn:
- Xây dựng nhiều lệnh con như:
ask
,translate
,summarize
. - Thêm flags như
--model
,--temp
để điều chỉnh hành vi AI. - Tích hợp dễ dàng với cấu trúc
main.go
.
Coding
Tạo thư mục dự án
mkdir ai-cli
cd ai-cli
go mod init github.com/yourname/ai-cli
Cài đặt Cobra CLI và khởi tạo
go install github.com/spf13/cobra-cli@latest
cobra-cli init --pkg-name github.com/yourname/ai-cli
Sau lệnh trên, dự án sẽ có cấu trúc cơ bản:
ai-cli/
├── cmd/
│ └── root.go // lệnh gốc
└── main.go // entry point
Cài thư viện Google Gemini
Để sử dụng Gemini API trong Go, ta cần cài SDK chính thức:
go get cloud.google.com/go/palm/apiv1
Và tạo biến môi trường chứa API Key của bạn:
export GOOGLE_API_KEY=your_api_key_here
API key này lấy từ Google Cloud Console, sau khi bật API “Generative Language API”.
Thêm lệnh ask – gửi câu hỏi tới AI
Ta sẽ thêm một lệnh tên là ask
, mục đích là nhận input từ người dùng (ví dụ: “Tóm tắt bài học về Golang”), gửi tới Google Gemini, nhận phản hồi và in ra màn hình.
Tạo file cmd/ask.go
package cmd
import (
"context"
"fmt"
"os"
"strings"
palm "cloud.google.com/go/palm/apiv1"
palmpb "cloud.google.com/go/palm/apiv1/palmpb"
"github.com/spf13/cobra"
)
var model string
var temperature float32
var askCmd = &cobra.Command{
Use: "ask [câu hỏi]",
Short: "Gửi câu hỏi đến Google Gemini và nhận phản hồi",
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
question := strings.Join(args, " ")
apiKey := os.Getenv("GOOGLE_API_KEY")
if apiKey == "" {
fmt.Println("Lỗi: Chưa đặt biến môi trường GOOGLE_API_KEY")
return
}
ctx := context.Background()
client, err := palm.NewClient(ctx)
if err != nil {
fmt.Println("Không thể tạo client:", err)
return
}
defer client.Close()
req := &palmpb.GenerateMessageRequest{
Model: model,
Prompt: &palmpb.MessagePrompt{
Context: "Bạn là một trợ lý AI thông minh.",
Messages: []*palmpb.Message{
{Content: question},
},
},
Temperature: float32(temperature),
}
resp, err := client.GenerateMessage(ctx, req)
if err != nil {
fmt.Println("Lỗi khi gọi API:", err)
return
}
if len(resp.Candidates) > 0 {
fmt.Println(resp.Candidates[0].Content)
} else {
fmt.Println("Không có phản hồi từ AI.")
}
},
}
askCmd
là một lệnh con trong CLI. Khi gọi ./ai-cli ask "..."
, hàm Run
sẽ được thực thi.
question := strings.Join(args, " ")
: nối toàn bộ các argument thành một câu hỏi đầy đủ.
apiKey := os.Getenv(...)
: lấy khóa API từ biến môi trường.
palm.NewClient(...)
: khởi tạo client để kết nối với Google Gemini.
GenerateMessageRequest
: yêu cầu AI sinh phản hồi dựa trên prompt đã định.
Temperature
: độ sáng tạo của AI (0.0 đến 1.0). Càng cao càng “ngẫu nhiên”.
Thêm flags – điều chỉnh hành vi AI
Để CLI linh hoạt hơn, ta sẽ cho phép người dùng tùy chọn model và temperature.
Thêm vào init()
:
func init() {
rootCmd.AddCommand(askCmd)
askCmd.Flags().StringVarP(&model, "model", "m", "models/chat-bison-001", "Model AI muốn sử dụng")
askCmd.Flags().Float32VarP(&temperature, "temperature", "t", 0.7, "Độ sáng tạo của AI (0.0 đến 1.0)")
}
Ý nghĩa:
--model
(hoặc -m
) dùng để chọn model Gemini.
--temperature
(hoặc -t
) dùng để điều chỉnh tính sáng tạo của AI.
Nếu không truyền, giá trị mặc định sẽ là "models/chat-bison-001"
và 0.7
.
Ví dụ chạy:
./ai-cli ask "Giới thiệu về Golang" -m models/text-bison-001 -t 0.5
Chạy thử: Ví dụ thực tế
Câu hỏi:
./ai-cli ask "Tóm tắt lịch sử Việt Nam trong 5 câu"
Kết quả:
Việt Nam có lịch sử lâu đời, bắt đầu từ các nền văn hóa Đông Sơn. Trải qua hơn 1000 năm Bắc thuộc, đất nước dần giành được độc lập. Các triều đại như Lý, Trần, Lê đã phát triển văn hóa, giáo dục. Pháp đô hộ vào cuối thế kỷ 19, dẫn đến kháng chiến giành độc lập. Năm 1975, đất nước thống nhất, mở ra thời kỳ phát triển mới.
Mở rộng: Xây dựng chatbot
Ứng dụng có vẻ hơi đơn giản nên chúng ta sẽ mở rộng công cụ CLI tích hợp AI bằng cách:
Thêm chế độ chatbot: bạn có thể trò chuyện nhiều lượt với Google Gemini, giống như ChatGPT.
Lưu lại lịch sử hội thoại để bạn có thể xem lại sau.
Trong phần này, chúng ta sẽ xây dựng một lệnh mới chat
, cho phép người dùng trò chuyện với AI trong nhiều lượt, thay vì chỉ hỏi 1 câu như ask
. Bên cạnh đó, mỗi cuộc hội thoại sẽ được lưu lại dưới dạng file văn bản (hoặc JSON) để có thể xem lại khi cần.
Mục tiêu của chat command
Người dùng có thể nhập nhiều câu hỏi.
AI sẽ phản hồi từng lượt dựa trên ngữ cảnh hội thoại.
Khi người dùng gõ exit
hoặc quit
, kết thúc phiên trò chuyện.
Toàn bộ cuộc hội thoại được lưu vào chat_history_<timestamp>.txt
.
implement chat.go
Tạo file mới cmd/chat.go
:
package cmd
import (
"bufio"
"context"
"fmt"
"os"
"strings"
"time"
palm "cloud.google.com/go/palm/apiv1"
palmpb "cloud.google.com/go/palm/apiv1/palmpb"
"github.com/spf13/cobra"
)
var chatCmd = &cobra.Command{
Use: "chat",
Short: "Trò chuyện nhiều lượt với Google Gemini",
Run: func(cmd *cobra.Command, args []string) {
apiKey := os.Getenv("GOOGLE_API_KEY")
if apiKey == "" {
fmt.Println("Lỗi: chưa thiết lập GOOGLE_API_KEY.")
return
}
ctx := context.Background()
client, err := palm.NewClient(ctx)
if err != nil {
fmt.Println("Không thể khởi tạo client:", err)
return
}
defer client.Close()
reader := bufio.NewReader(os.Stdin)
var messages []*palmpb.Message
filename := fmt.Sprintf("chat_history_%s.txt", time.Now().Format("20060102_150405"))
file, err := os.Create(filename)
if err != nil {
fmt.Println("Không thể tạo file lưu lịch sử:", err)
return
}
defer file.Close()
fmt.Println("Bắt đầu trò chuyện với Gemini (gõ `exit` để thoát)\n")
for {
fmt.Print("👤 Bạn: ")
userInput, _ := reader.ReadString('\n')
userInput = strings.TrimSpace(userInput)
if userInput == "exit" || userInput == "quit" {
fmt.Println("⏹️ Kết thúc trò chuyện.")
break
}
// Thêm câu hỏi của người dùng vào context
messages = append(messages, &palmpb.Message{
Author: "user",
Content: userInput,
})
req := &palmpb.GenerateMessageRequest{
Model: "models/chat-bison-001",
Prompt: &palmpb.MessagePrompt{
Context: "Bạn là trợ lý AI thông minh và thân thiện.",
Messages: messages,
},
Temperature: 0.7,
}
resp, err := client.GenerateMessage(ctx, req)
if err != nil {
fmt.Println("❌ Lỗi gọi API:", err)
continue
}
if len(resp.Candidates) > 0 {
reply := resp.Candidates[0].Content
fmt.Println("🤖 Gemini:", reply)
// Ghi vào file lịch sử
file.WriteString("👤 " + userInput + "\n")
file.WriteString("🤖 " + reply + "\n\n")
// Thêm phản hồi vào context để giữ mạch hội thoại
messages = append(messages, &palmpb.Message{
Author: "model",
Content: reply,
})
} else {
fmt.Println("⚠️ Không có phản hồi từ AI.")
}
}
fmt.Printf("\n📁 Lịch sử hội thoại đã lưu tại: %s\n", filename)
},
}
Cập nhật root.go để thêm lệnh chat
Trong cmd/root.go
, thêm dòng sau vào init()
:
rootCmd.AddCommand(chatCmd)
Chạy thử thôi
Chạy lệnh:
./ai-cli chat
Kết quả:
👤 Bạn: Xin chào, bạn là ai?
🤖 Gemini: Chào bạn! Tôi là trợ lý AI sử dụng mô hình Gemini của Google. Tôi có thể giúp gì cho bạn?
👤 Bạn: Hãy giải thích ngắn gọn về biến trong Golang.
🤖 Gemini: Trong Golang, biến được khai báo bằng từ khóa `var` và có kiểu dữ liệu tường minh. Ví dụ: `var x int = 10`.
Sau khi kết thúc trò chuyện, bạn sẽ thấy file:
chat_history_20250618_223214.txt
Trong đó chứa đầy đủ nội dung hội thoại.
Đánh giá hiện tại
Đã làm được
- Giữ được ngữ cảnh trong nhiều lượt hội thoại.
- Trải nghiệm như một AI chatbot ngay trong terminal.
- Có thể tích hợp cho nhiều use-case thực tế (hỏi đáp, học tập, code).
- Lưu được lịch sử phục vụ phân tích hoặc training sau này.
Chưa làm được
- Chưa hỗ trợ lưu hội thoại theo user profile.
- Giao diện terminal còn đơn giản, chưa hỗ trợ màu sắc hoặc UI đẹp.
- Với lịch sử dài, chi phí gọi API tăng do context dài hơn.
Hướng phát triển tiếp theo
Thêm chế độ streaming để hiện câu trả lời theo từng dòng:
Hiển thị câu trả lời từng ký tự hoặc từng dòng một sẽ tạo cảm giác như AI đang "gõ" phản hồi trực tiếp, giúp trải nghiệm tương tác trở nên sống động hơn. Tính năng này rất hữu ích khi câu trả lời dài, đồng thời giúp người dùng không phải chờ đợi toàn bộ kết quả mới hiển thị.
Dùng định dạng JSON để lưu lịch sử:
Việc lưu lịch sử hội thoại dưới dạng JSON thay vì thuần văn bản sẽ giúp việc phân tích, lọc hoặc tái sử dụng dữ liệu trở nên dễ dàng hơn trong tương lai. Định dạng này cũng dễ dàng tích hợp với các hệ thống hoặc API khác nếu cần mở rộng.
Tích hợp command alias, ví dụ: ai chat
, ai ask
, ai translate
:
Việc cung cấp các bí danh (alias) cho lệnh giúp người dùng nhớ và sử dụng nhanh hơn, đặc biệt khi CLI có nhiều tính năng. Chẳng hạn, thay vì phải nhớ từng lệnh riêng biệt, người dùng chỉ cần gõ ai chat
để bắt đầu hội thoại, ai translate
để dịch nhanh văn bản, v.v.
Kết nối tới Telegram / Discord / Slack để chạy bot tự động:
Mở rộng CLI thành một chatbot có thể hoạt động trên các nền tảng nhắn tin phổ biến sẽ giúp ứng dụng tiếp cận người dùng dễ dàng hơn. Đây cũng là bước đệm quan trọng nếu bạn muốn biến trợ lý AI này thành một công cụ cộng tác cho nhóm hoặc doanh nghiệp.
Tích hợp SQLite để lưu user history theo phiên đăng nhập:
Khi ứng dụng phục vụ nhiều người dùng hoặc cần ghi nhớ lịch sử theo phiên, SQLite là lựa chọn phù hợp để lưu trữ cục bộ. Bạn có thể tổ chức dữ liệu theo người dùng, thời gian hoặc mục đích sử dụng, từ đó giúp việc truy xuất, phân tích và tùy biến trải nghiệm trở nên hiệu quả hơn.
Kết luận
Từ một ý tưởng nhỏ về "hỏi nhanh AI từ terminal", bạn hoàn toàn có thể mở rộng ra thành một trợ lý mạnh mẽ tích hợp vào mọi công việc. Với Golang và thư viện Cobra, bạn có thể phát triển một CLI thân thiện, dễ bảo trì. Kết hợp với sức mạnh từ mô hình Google Gemini, bạn có trong tay một công cụ giúp tăng hiệu suất học tập, làm việc và sáng tạo nội dung.
Hy vọng bài viết mang lại kiến thức thực tế và có thể truyền cảm hứng cho bạn bắt đầu xây dựng các công cụ AI của riêng mình!
Nếu bạn thấy hữu ích, đừng ngần ngại chia sẻ bài viết này đến bạn bè hoặc đồng nghiệp đang tìm cách tích hợp AI vào quy trình làm việc của mình nhé!