使用Ruby on Rails和OpenAI的代码评论生成器

示范

GitHub GitHub是一个基于Web的Git仓库托管服务,它是开发者们共享代码和协作的理想平台。GitHub上有数百万个项目,涵盖了各种编程语言和技术领域。无论你是想要学习编程、参与开源项目,还是与同行交流,GitHub都是一个非常有用的工具。

在不断发展的软件开发领域中,人工智能正在改变开发人员编写和理解代码的方式。像GitHub Copilot和其他人工智能驱动的扩展工具正在变得必不可少,帮助开发人员更高效地编写代码并减少错误。

在最近的一个项目中,我开始探索将GPTs集成到开发工具中,通过创建一个代码注释生成器。

该项目包括两个关键组成部分:

  1. 使用Ruby on Rails构建的API,利用OpenAI的GPT-4o模型生成评论。
  2. 一个独立的Ruby应用程序,作为客户端,调用API为用户提供代码片段的AI生成评论。

下面由Luigi Rojas和EarthCtzn提供的文章对这个项目是有帮助的指南!

1. 构建API.

创建 Rails API

rails new code_comment_generator_api --api

--api 标志告诉 Rails 生成一个专注于 API 的应用程序,并且省略了视图等不必要的组件。

更新 Gemfile

这个 API 将利用 OpenAI 的 GPT-4o 模型生成代码注释。我们将使用ruby-openai gem来完成这个集成。

首先,在项目的Gemfile中添加ruby-openai,并通过运行bundle install来安装它。

和 GPT-4o 对话

让我们专注于一个负责连接到GPT-4o并生成代码注释的服务,在 app/services/comment_generator.rb 文件中。

以下代码展示了我的服务最初如何与ChatGPT进行通信:

#app/services/comment_generator.rb

class CommentGenerator
def self.generate(code)
openai_response = OpenAI::Client.new(access_token: ENV['OPENAI_API_KEY'], log_errors: true).chat(
parameters: {
model: "gpt-4o",
messages: [
{
role: "user",
content: "Write a comment for the following code:\n`\n#{code}\n`"
}
],
max_tokens: 500,
n: 1,
stop: nil,
temperature: 0.5
}
)

puts openai_response.inspect

openai_response['choices'][0]['message']['content'].strip
end
end

这种实现在处理之前等待来自ChatGPT的整个响应。不幸的是,这种方法会让服务感觉慢和无响应。

使用流式传输与GPT-4o进行交流。

为了让服务感觉快速和互动,让我们利用ruby-openai提供的流媒体支持。

#app/services/comment_generator.rb

class CommentGenerator
def self.generate(code)
puts "starting CommentGenerator model"

client = OpenAI::Client.new(access_token: ENV['OPENAI_API_KEY'], log_errors: true)

client.chat(
parameters: {
model: "gpt-4o",
messages: [{ role: "user", content: "Write a comment for the following code:\n`\n#{code}\n`"}],
temperature: 0.7,
stream: proc do |chunk|
puts "Received chunk in CommentGenerator: #{chunk}"
comment_part = chunk.dig("choices", 0, "delta", "content")
puts "In CommentGenerator, comment_part: #{comment_part}"
yield comment_part if block_given?
end
}
)
end
end

这种流式处理方式通过提供实时反馈,使用户体验更加流畅,并与用户期望与类似ChatGPT的基于文本的AI模型进行交互的方式相一致。

实现控制器

下面的代码定义了一个用于生成评论的控制器:

#app/controllers/comments_controller.rb

class CommentsController < ApplicationController
include ActionController::Live

def generate
puts "Starting generate method"
response.headers['Content-Type'] = 'text/event-stream'
response.headers['Cache-Control'] = 'no-cache'

begin
code = params[:code]
puts "Received code: #{code}"

CommentGenerator.generate(code) do |comment_part|
puts "Received comment part: #{comment_part}"
response.stream.write comment_part
end
rescue => e
puts "Error ocurred: #{e.message}"
response.stream.write "data: Error occurred: #{e.message}\n\n"
ensure
puts "Closing response stream"
response.stream.close
end
end
end

ActionController::Live使得可以流式传送响应。generate方法接收一个代码作为输入,然后使用CommentGenerator.generate(在comment_generator.rb中实现的服务)对其进行分块处理。然后将每个分块作为数据事件流式传送回客户端。如果在处理过程中发生任何错误,将流式传送回一个错误消息。

更新routes.rb

这段代码在config/routes.rb中定义了一个路由,它将Rails应用中的POST请求映射到CommentsController中的generate操作。

# config/routes.rb

Rails.application.routes.draw do
post '/comment', to: 'comments#generate'
end

API部分就介绍到这里!运行rails s将启动一个本地web服务器。这意味着我们可以在http://localhost:3000/comment测试API(或者您的应用程序配置为监听的任何端口)。我通过使用Postman向终端发送POST请求来测试API,并将流式响应打印到控制台。

2. 构建 Web 应用程序

随着强大的客户端框架的出现,越来越多的开发者选择使用Rails构建强大的后端,可以在Web应用程序和其他本地平台之间共享。这种方法不仅简化了开发,还允许无缝集成AI驱动工具,比如我们刚开发的API,到现代软件工作流程中。

为了展示我们刚创建的API的互操作性,让我们用Ruby开发一个独立的客户端应用程序。这个客户端应用程序将向API服务器发送请求,并向用户显示服务器的响应。

实施视图

网络应用程序将看起来像这样(使用Bootstrap进行样式设置)

#app/views/home/index.html.erb

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset=UTF-8 <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
<title>Comment Generator</title>
</head>

<body>
<br>
<h1 class="title">Code Comments Generator</h1>
<br>
<section id="events"></section>

<% if @error %>
<p style="color: red;"><%= @error %></p>
<% end %>

<div class="container">

<div class="form-container">
<form id="commentForm">
<label for="code_snippet">Enter your code:</label><br>
<textarea class="form-control" id="code_snippet" name="code_snippet" rows="10" cols="50"></textarea><br>
<button type="submit" class="btn btn-dark">Generate</button>
</form>
</div>
<div class="result-container">
<pre id="commentedCode"></pre>
</div>
</div>

<script>
document.getElementById('commentForm').onsubmit = function(event) {
event.preventDefault();

const codeSnippet = document.getElementById('code_snippet').value;
const eventSource = new EventSource(`/comments?code_snippet=${encodeURIComponent(codeSnippet)}`);

const commentedCodeElement = document.getElementById('commentedCode');
commentedCodeElement.textContent = ""
commentedCodeElement.textContent += "[INFO] Streaming started...\n";


eventSource.addEventListener("message", (event) => {
console.log(event)
const events = document.getElementById("events")
commentedCodeElement.textContent += event.data;
})

eventSource.addEventListener("error", (event) => {
console.log(event)

if (event.eventPhase === EventSource.CLOSED) {
eventSource.close()
console.log("Event Source Closed")
}
})
}
</script>
</body>
</html>

这里需要注意的主要事情是页面允许用户通过表单输入代码片段并提交。页面使用JavaScript和服务器发送事件来实时流式传输和显示来自API服务器的生成注释代码,在页面上的特定区域。

实现客户端控制器

我们需要一个控制器,作为我们开发的代码注释生成API的客户端。

#app/controllers/comments_controller.rb

require 'net/http'
class CommentsController < ApplicationController
include ActionController::Live

def index
response.headers['Content-Type'] = 'text/event-stream'
response.headers['Cache-Control'] = 'no-cache'
response.headers['Last-Modified'] = Time.now.httpdate

code_snippet = params[:code_snippet]
uri = URI('http://localhost:3000/comments')
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.path, { 'Content-Type' => 'application/json' })
request.body = { code: code_snippet }.to_json

sse = SSE.new(response.stream, event: "message")

http.request(request) do |http_response|
http_response.read_body do |chunk|
sse.write(chunk)
end
end
ensure
sse.close if sse
end
end

简而言之,控制器检索通过表单提交的代码片段并将其通过POST请求发送到API服务器http://localhost:3000/comment,然后使用服务器发送事件(SSE)将响应流回客户端。

结束思考

即使作为一个极简可行产品,这个项目也是一个很好的练习,可以更熟悉将GPTs集成到应用程序中、构建APIs,并用Ruby on Rails进行开发。

该应用程序有很大的改进空间。例如,通过尝试不同的格式并添加更多上下文来改进提示工程,可以提升评论的相关性和准确性。此外,对GPT-4o模型在高质量、有评论的代码数据集上进行微调,可以使生成器产生更具上下文特定的评论,并遵循格式规则,使其更适合满足开发人员特定的需求。

2024-09-01 04:13:05 AI中文站翻译自原文