Tự động hóa việc tạo tài liệu bằng AI trong Ruby on Rails
Trong các dự án phần mềm hiện đại, việc tự động hóa các tác vụ lặp đi lặp lại là rất quan trọng để tăng tốc độ phát triển và giảm thiểu sai sót do con người. Một ví dụ tuyệt vời là tạo tài liệu — dù đó là tài liệu yêu cầu sản phẩm (PRD), đề xuất dự án hay bài thuyết trình.
Gần đây, tôi đã làm việc trên một hệ thống sử dụng AI để tạo ra nội dung có cấu trúc từ các cuộc hội thoại, sau đó xuất tài liệu dưới nhiều định dạng như Word (.odt), PowerPoint (.pptx), Markdown (.md) và nhiều định dạng khác. Kiến trúc hệ thống tận dụng AI hội thoại để tạo nội dung có cấu trúc, và hoàn toàn có thể tích hợp với Ruby on Rails. Dưới đây là cách bạn có thể xây dựng hệ thống như vậy.
Cách hoạt động: Kiến trúc hệ thống
User Input (Q&A + files)
↓
Conversational AI (OpenAI)
↓
Structured JSON PRD (document sections)
↓
Output Generators:
├─ DOCX (Word templates)
├─ PPTX (PowerPoint templates)
├─ Markdown (MD templates)
├─ YAML (configuration/data serialization)
├─ ODT (OpenDocument Text)
├─ PDF (final polished document)
└─ TXT (plain text export)
↓
Export & Delivery (files to users)
Luồng này đảm bảo việc tách biệt rõ ràng giữa quá trình tạo nội dung và hiển thị định dạng, giúp hệ thống có thể mở rộng và dễ bảo trì.
Ruby on Rails: Ví dụ triển khai
1. AI hội thoại
Sử dụng gem ruby-openai
để tương tác với API của OpenAI:
require 'openai'
class AiPrdService
def initialize(user_prompt)
@client = OpenAI::Client.new(access_token: ENV['OPENAI_API_KEY'])
@user_prompt = user_prompt
end
def generate_prd_json
response = @client.chat(
parameters: {
model: "gpt-4o-mini",
messages: [
{ role: "system", content: "You are an AI assistant that generates structured PRDs." },
{ role: "user", content: @user_prompt }
],
temperature: 0.7
}
)
# Extract JSON from response (assuming AI outputs JSON)
prd_content = JSON.parse(response.dig("choices", 0, "message", "content"))
prd_content
rescue JSON::ParserError => e
Rails.logger.error "Failed to parse AI response: #{e.message}"
nil
end
end
2. Tạo DOCX bằng template
Sử dụng gem caracal
để tạo tài liệu Word:
require 'caracal'
class DocxGenerator
def initialize(prd_json)
@prd_json = prd_json
end
def generate_docx(output_path)
Caracal::Document.save(output_path) do |docx|
docx.h1 @prd_json['title']
@prd_json['sections'].each do |section|
docx.h2 section['heading']
docx.p section['content']
end
end
end
end
3. Tạo Markdown (MD)
Sử dụng ERB để render mẫu:
class MarkdownGenerator
TEMPLATE = <<~MD
# <%= @prd_json['title'] %>
<% @prd_json['sections'].each do |section| %>
## <%= section['heading'] %>
<%= section['content'] %>
<% end %>
MD
def initialize(prd_json)
@prd_json = prd_json
end
def generate_markdown
ERB.new(TEMPLATE).result(binding)
end
end
4. Xuất YAML cho cấu hình hoặc chia sẻ dữ liệu
require 'yaml'
class YamlGenerator
def initialize(prd_json)
@prd_json = prd_json
end
def generate_yaml(output_path)
File.write(output_path, @prd_json.to_yaml)
end
end
5. Tạo ODT (OpenDocument Text)
Sử dụng gem odf-report
:
require 'odf-report'
class OdtGenerator
def initialize(prd_json)
@prd_json = prd_json
end
def generate_odt(output_path)
report = ODFReport::Report.new("template.odt") do |r|
r.add_field("TITLE", @prd_json['title'])
@prd_json['sections'].each_with_index do |section, index|
r.add_field("HEADING#{index+1}", section['heading'])
r.add_field("CONTENT#{index+1}", section['content'])
end
end
report.generate(output_path)
end
end
6. Tạo PDF
Sử dụng gem prawn
(hoặc wicked_pdf
cho HTML sang PDF):
require 'prawn'
class PdfGenerator
def initialize(prd_json)
@prd_json = prd_json
end
def generate_pdf(output_path)
Prawn::Document.generate(output_path) do |pdf|
pdf.text @prd_json['title'], size: 24, style: :bold
@prd_json['sections'].each do |section|
pdf.move_down 10
pdf.text section['heading'], size: 18, style: :bold
pdf.text section['content'], size: 12
end
end
end
end
7. Xuất văn bản thuần túy (TXT)
class TxtGenerator
def initialize(prd_json)
@prd_json = prd_json
end
def generate_txt(output_path)
content = []
content << @prd_json['title']
@prd_json['sections'].each do |section|
content << "\n#{section['heading']}\n"
content << "#{section['content']}\n"
end
File.write(output_path, content.join("\n"))
end
end
Tại sao xây dựng hệ thống này bằng Rails?
- Dễ bảo trì: Kiến trúc MVC và pattern service object của Rails giúp tách biệt rõ trách nhiệm.
- Dễ mở rộng: Thêm định dạng mới như PDF, ODT chỉ cần vài bước.
- Tích hợp tốt: Có thể sử dụng ActiveJob và xử lý nền để tạo tài liệu không đồng bộ.
- Hệ sinh thái phong phú: Có nhiều gem hỗ trợ tạo mẫu tài liệu và HTTP client.
Tổng kết
Bằng cách kết hợp các mô hình hội thoại mạnh mẽ của OpenAI với kiến trúc linh hoạt của Ruby on Rails, bạn có thể xây dựng các pipeline mạnh mẽ để tự động chuyển đổi hội thoại của người dùng thành tài liệu có cấu trúc rõ ràng — tiết kiệm thời gian và giảm thiểu công việc thủ công.
All Rights Reserved