+4

Người lười viết báo cáo hàng ngày dùng Ruby và Google Gemini

Mở bài

Chào các bạn. Mình đã đặt chuông báo thức là Wake me up when September ends rồi mà chả ai gọi mình dạy cả... Hơi dỗi nha.

Mình giới thiệu qua. Mình đã sắp được 5 năm ở Nhật và với mình, thứ phiền toái nhất vẫn là... báo cáo hàng ngày =)) Tất nhiên giờ có 1 đống kiến thức quản lý cũng như kinh nghiệm làm việc thì mình hiểu tầm quan trọng của báo cáo. Tuy nhiên, viết 1 cái báo cáo bằng tiếng nước ngoài, lại thuộc hàng ngôn ngữ khó, xong lại còn dính tới chữ tượng hình(Hán tự) khiến mình thường phải mất 1-2 tiếng để ngồi viết báo cáo, mà hồi đó viết xong thì sếp nào cũng claim... Thế nên theo bài hát gây sát thương nhất từ ban nhạc Nhật mình yêu thích nhất thì:

漢字も苦手 見たこともない単語が

ぐるぐるぐる 目が回りそうだ

Dịch:

Kanji thì rõ là khó, lại còn chỗ từ vựng tôi chưa từng thấy bao giờ

Làm mắt tôi cứ đảo tròn đảo tròn đảo tròn hết cả lên

Vì vậy, để tối ưu được sự lười, tập trung vào việc luyện tập code Ruby, chơi bời, đu idol,... thì mình tìm 1 cách để làm sao mình chỉ cần lấy ghi dự án, các task trong dự án, tiến độ, công việc dự kiến làm ngày mai,... là sẽ có 1 cái báo cáo để mình gửi đi. Và với việc có GenAI là trend thì mình cũng phải đu trend thôi 🤣

(nhân tiện thì câu kia là bài Hon wo Yomu của ban nhạc SCANDAL. Các bạn hãy đón nghe)

Tiến hành làm project

Chuẩn bị Google Gemini key

Bạn đã biết đến ChatGPT? Bạn đã biết đến OpenAI? Thế thì bạn cũng sẽ biết 1 số các AI Ngẫu Sinh khác.

Google Gemini ra mắt vào tháng 12 năm 2023 (trước đây là Google Bard), được mệnh danh là “mô hình AI mạnh mẽ và tổng quát nhất” của Google. Gemini được đánh giá là một bước đột phá trong lĩnh vực trí tuệ nhân tạo, sở hữu nhiều khả năng vượt trội so với các mô hình LLM (ngôn ngữ lớn) khác như GPT-4 của OpenAI. Ngoài ra, Gemini được tích hợp với hệ sinh thái Google, nhờ vậy mà có thể cung cấp cho người dùng những kiến thức chuyên sâu và nguồn tài nguyên dồi dào.

Đấy là dựa theo bài báo ở Việt Nam mà mình thấy giới thiệu đầy đủ về Google Gemini. Còn dân dã thì ngày trc mình ko có đk đăng ký account OpenAI để dùng ChatGPT cũng như chính sách hồi đó khác. Giờ đây khác rồi nhưng dùng Google Bard quen quá nên nghiện roài, không cai được 🤣 Nên mình là fan của Google Gemini.

(Lời thì thầm của người dùng ngôn ngữ Đá ... đỏ: các bạn đừng tiếp xúc tech stack của mình. Nghiện đấy 🤣 )

OK, lời giới thiệu cho Google Gemini thế là đã đủ. Cách thức để lấy key dùng Google Gemini rất đơn giản. Bạn chỉ cần có Gmail hoặc account Google là hoàn toàn có thể đăng ký được.

Vào Google AI Studio, click "Create API key in new project" là bạn sẽ có 1 key.

image.png

Khi key hiện ra, bạn hãy copy và lưu lại key vào file .env

image.png

Dùng Ruby để viết

Thôi nào, mình thích hard game 1 tí và viết bằng Python, JS/TS hay Shell script nó có hơi dễ quá. Ngoài ra thì mình cũng đang muốn luyện lại skill Ruby, chứ không phải để lót chuột Ruby Gold treo lên cho vui.

Sử dụng gem gemini-ai

gemini-ai là một Ruby gem để tương tác với Gemini thông qua Vertex AI, Generative Language API hoặc AI Studio và các dịch vụ AI ngẫu sinh khác của Google. Đây là Github của gem: https://github.com/gbaptista/gemini-ai

Các bạn có thể thấy có rất nhiều cách để gọi tới service của Google, nhưng vì mình vừa dùng cách nhanh như trên nên mình sẽ gọi theo cách đầu:

client = Gemini.new(
  credentials: {
    service: 'generative-language-api',
    api_key: ENV['GOOGLE_GEMINI_TOKEN']
  },
  options: { model: 'gemini-pro', server_sent_events: true }
)

Phần code

Trước tiên thì mình phải tạo cái folder, cho vào trong đó Gemfile, Gemfile.lock, .gitignore. Đây là hình ảnh cấu trúc thư mục của mình:

Với .gitignore, mình sử dụng luôn template từ Github: https://github.com/github/gitignore/blob/main/Ruby.gitignore

Tuy nhiên để ổn với cấu trúc file trên thì mình có thêm:

/result/*
!/result/.keep
/input/*
!/input/.keep

Ở trong Gemfile:

# frozen_string_literal: true

source 'https://rubygems.org'

gem 'gemini-ai', '~> 4.2.0'
gem 'dotenv'

Gemfile.lock thì cứ tạo ra để trống, xong chạy bundle install là coi như đã setup môi trường.

Tại lib/main.rb, bước đầu là gọi các thư viện cần thiết:

# frozen_string_literal: true

require 'dotenv/load'
require 'gemini-ai'

Mình sẽ tạo 1 cái input text gồm 2 phần: phần email template và phần đọc file.

Phần email template sẽ như sau:

text_request = <<-TEXT
この日報フォーマットに情報を追加てください。

"A様

お疲れ様です。ホアンクアンです。

本日の業務内容を報告していたします。

業務内容:
  1. プロジェクト1
    - タスク1:
      進捗状況: %

課題

明日の予定
  1. プロジェクト1
    プロジェクト1の予定

以上、本日の報告とさせていただきます。"
TEXT

Vì đây là multiline nên mình đã dùng heredoc ở đây. Rất hữu hiệu. Đặc biệt nếu phải viết SQL nhiều dòng để chạy trong Ruby thì heredoc xịn xò.

À, nhưng nếu không có template sẵn thì bạn để chuỗi rỗng cũng không sao hết nhé.

Phần đọc file thì như dưới đây

Dir.glob('./input/*.txt').each do |file_name|
  text_request += File.read(file_name)
end

Tiếp theo là đưa input trên cho Gemini

result = client.stream_generate_content({
  contents: { role: 'user', parts: { text: text_request } }
})

Kết quả trả ra là 1 định dạng dữ liệu. Mình muốn lấy mỗi phần text nên mình sẽ phải thêm:

mail_template = result
              .map { |response| response.dig('candidates', 0, 'content', 'parts') }
              .map { |parts| parts.map { |part| part['text'] }.join }
              .join

puts mail_template

Ở đây mình cũng viết thêm shell để chạy cho tiện:

echo "Job starts"
sleep .5
echo "Processing..."
ruby lib/main.rb > result/out.txt
echo "Done"

Vậy là khi chạy project, chỉ cần chạy sh run.sh là xong.

Viết README cho Project

À, và tất nhiên mình cũng lười viết README nốt nên mình cũng dùng AI gen ra luôn cho nhanh

image.png

Thành quả

Và đây là repo thành quả của mình: https://github.com/BlazingRockStorm/genai-daily-report-generator

Tuy nhiên, ở version đầu tiên này, tính ngẫu sinh vấn rất cao. Và mình có nhận thấy format là format của markdown nên mình đã cải tiến

Cải tiến

Mình thêm phần temperature vào vì thực sự có form sẵn rồi, mình chỉ muốn dùng đúng. Nếu các bạn chưa có form thì không cần đặt đâu nhé.

result = client.stream_generate_content({
  contents: { role: 'user', parts: { text: text_request } },
  generationConfig: { temperature: 0 }
})

Ở shell, mình xuất ra format markdown:

echo "Job starts"
sleep .5
echo "Processing..."
ruby lib/main.rb > result/out.md
echo "Done"

Chạy:

Đây là 3 file mẫu của mình:

  • file 1
プロジェクト1:
タスク1: 
進捗状況: 40%

タスク2:
   進捗状況: 30%。
   
課題/問題ない

タスク2の優先度が高いので、明日このタスク続きます
  • file 2
プロジェクト2:
タスク1: 
進捗状況: 100%
   
課題/問題ない

プロジェクト完了
  • file 3
プロジェクト3:
  進捗状況:0%

課題/問題:まだ設計中

明日設計続く

Kết quả chạy:

Screenshot 2024-10-18 at 13.39.26.png

Nó rất sát format mình đặt ra bên trên. Và coi như là xong.

Dự kiến cải tiến

Mình dự định làm sao để convert file doc, tạo test hoặc rspec hay thậm chí là dùng thử 1 gem khác(bật mí sau nếu thành công)

Kết

Như vậy nhờ công cụ trên, mình chỉ mất có 5 phút để tổng hợp các dự án vào các file, 1 phút để tạo báo cáo và 5 phút ngồi review lại. Cuộc sống kỹ sư lười chưa bao giờ dễ đến thế 🤣

Các bạn đọc bài xong nếu có lòng thì cho mình xin Donate nhoé: https://buymeacoffee.com/gryqhon


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí