英文:
ruby-openai api gem in Ruby on Rails: how to implement a streaming conversation?
问题
OpenAI提供了一个API,允许您实现像ChaGPT或DAL-E这样的AI服务。
对于Ruby on Rails应用程序,有几个可用的宝石,其中之一是ruby-openai
。
它运行得很好,但唯一的问题是它不具备流式对话功能,这意味着您只能一次发送一个问题请求,而无法跟踪对话的历史记录。换句话说,API在发送回复后会忘记您提出的每个问题。
那么我们如何解决这个问题?
英文:
Openai provides an api which allows you to implement AI services such as ChaGPT or DAL-E.
For Ruby on Rails application, and there are couple of gems available, obe of them being ruby-openai
.
It works very well, but the only problem is that it doesn't come with the stream conversation feature, meaning that you can only send one question request at a time without any history tracking of the conversation. In other words, the api forgets every question you asked after having sent the reply.
So how can we fix this?
答案1
得分: 0
基本上,您需要自己实现整个行为。以下是所有的实现步骤,包括使用dal-e
ai来生成多张图片的响应。
您还可以在此处找到我的整个存储库,并克隆该应用程序!
实施流式对话功能
基本实施
查看Doug Berkley的Notion页面以了解API的基本实施。
实施流式对话
默认情况下,openai
gem不包含此功能,因此需要自己实现。
- 创建具有以下结构的3个表的数据库(conversations、questions、answers):
# schema.rb
ActiveRecord::Schema[7.0].define(version: 2023_05_29_194913) do
create_table "answers", force: :cascade do |t|
t.text "content"
t.integer "question_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["question_id"], name: "index_answers_on_question_id"
end
create_table "conversations", force: :cascade do |t|
t.text "initial_question"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.text "historic"
end
create_table "questions", force: :cascade do |t|
t.text "content"
t.integer "conversation_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["conversation_id"], name: "index_questions_on_conversation_id"
end
add_foreign_key "answers", "questions"
add_foreign_key "questions", "conversations"
end
- 路由
Rails.application.routes.draw do
root "pages#home" # 假设您有一个包含home操作的pages控制器
resources :conversations, only: [:create, :show]
post "question", to: "conversations#ask_question"
end
- 主页视图(只有一个按钮,重定向到创建对话操作 - 请参阅下面)
<h1>让我们聊天</h1>
<%= button_to "创建新对话", conversations_path, method: :post, class: "btn btn-primary my-3" %>
- 控制器
app/controllers/conversations_controller.rb
class ConversationsController < ApplicationController
def create
@convo = Conversation.create
redirect_to conversation_path(@convo)
end
def show
@convo = Conversation.find(params[:id])
end
def ask_question
@question = Question.new(content: params[:entry])
conversation = Conversation.find(params[:conversation])
@question.conversation = conversation
@question.save
if conversation.historic.nil?
response = OpenaiService.new(params[:entry]).call
conversation.historic = "#{@question.content}\n#{response}"
else
response = OpenaiService.new("#{conversation.historic}\n#{params[:entry]}").call
conversation.historic += "\n#{@question.content}\n#{response}"
end
conversation.save
@answer = Answer.create(content: response, question: @question)
redirect_to conversation_path(conversation)
end
end
- 显示页面
app/views/conversations/show.html.erb
<h1>这是您的对话</h1>
<p>提出您的问题</p>
<form action="<%= question_path %>", method="post">
<input type="hidden" name="conversation" value="<%= @convo.id %>">
<textarea rows="5" cols="33" name="entry"></textarea>
<input type="submit" class="btn btn-primary">
</form>
<br>
<ul>
<% @convo.questions.each do |question| %>
<li>
Q: <%= question.content.capitalize %> <%= "?" if question.content.strip.last != "?" %>
</li>
<li>
A: <%= question.answers.first.content %>
</li>
<% end %>
</ul>
<%= link_to "返回", root_path %>
- 运行
rails s
并进行测试
资源:
- https://github.com/OGsoundFX/ruby-open-ai
- https://doug-berkley.notion.site/doug-berkley/Rails-ChatGPT-Service-Object-Setup-21748fc969514b978bf6345f897b6d3e
- https://github.com/alexrudall/ruby-openai
更多信息:
英文:
Basically you need to implement the whole behaviour yourself. Here are all the implementation step, including the implementation of the dal-e
ai with a response with several pictures rather then just one.
You can also find my whole repository HERE and clone the app!!!
IMPLEMENTING A STREAM CONVERSATION FEATURE
Basic implementation
Check out Doug Berkley's Notion Page for basic implementation of the API
Implement a streaming conversation
By default the openai
gem does not come with that feature, hence having to implement it yourself
- Create your database with 3 tables (conversations, questions, answers) with thw following sctructure:
# schema.rb
ActiveRecord::Schema[7.0].define(version: 2023_05_29_194913) do
create_table "answers", force: :cascade do |t|
t.text "content"
t.integer "question_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["question_id"], name: "index_answers_on_question_id"
end
create_table "conversations", force: :cascade do |t|
t.text "initial_question"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.text "historic"
end
create_table "questions", force: :cascade do |t|
t.text "content"
t.integer "conversation_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["conversation_id"], name: "index_questions_on_conversation_id"
end
add_foreign_key "answers", "questions"
add_foreign_key "questions", "conversations"
end
- Routes
Rails.application.routes.draw do
root "pages#home" # supposes that you have a pages controller with a home action
resources :conversations, only: [:create, :show]
post "question", to: "conversations#ask_question"
end
- Home page view (with just a button that redirects to the create conversation action -- see bellow)
<h1>Let's talk</h1>
<%= button_to "Create New Conversation", conversations_path, method: :post, class: "btn btn-primary my-3" %>
- Controller
app/controllers/conversations_controller.rb
class ConversationsController < ApplicationController
def create
@convo = Conversation.create
redirect_to conversation_path(@convo)
end
def show
@convo = Conversation.find(params[:id])
end
def ask_question
@question = Question.new(content: params[:entry])
conversation = Conversation.find(params[:conversation])
@question.conversation = conversation
@question.save
if conversation.historic.nil?
response = OpenaiService.new(params[:entry]).call
conversation.historic = "#{@question.content}\n#{response}"
else
response = OpenaiService.new("#{conversation.historic}\n#{params[:entry]}").call
conversation.historic += "\n#{@question.content}\n#{response}"
end
conversation.save
@answer = Answer.create(content: response, question: @question)
redirect_to conversation_path(conversation)
end
end
- Show page
app/views/conversations/show.html.erb
<h1>This is your conversation</h1>
<p>Ask your question</p>
<form action="<%= question_path %>", method="post">
<input type="hidden" name="conversation" value="<%= @convo.id %>">
<textarea rows="5" cols="33" name="entry"></textarea>
<input type="submit" class="btn btn-primary">
</form>
<br>
<ul>
<% @convo.questions.each do |question| %>
<li>
Q: <%= question.content.capitalize %> <%= "?" if question.content.strip.last != "?" %>
</li>
<li>
A: <%= question.answers.first.content %>
</li>
<% end %>
</ul>
<%= link_to "Back", root_path %>
rails s
and test
Resources:
- https://github.com/OGsoundFX/ruby-open-ai
- https://doug-berkley.notion.site/doug-berkley/Rails-ChatGPT-Service-Object-Setup-21748fc969514b978bf6345f897b6d3e
- https://github.com/alexrudall/ruby-openai
Going Further:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论