在Ruby on Rails中使用ruby-openai API gem:如何实现流式对话?

huangapple go评论65阅读模式
英文:

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不包含此功能,因此需要自己实现。

  1. 创建具有以下结构的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
  1. 路由
Rails.application.routes.draw do
  root "pages#home" # 假设您有一个包含home操作的pages控制器
  resources :conversations, only: [:create, :show]
  post "question", to: "conversations#ask_question"
end
  1. 主页视图(只有一个按钮,重定向到创建对话操作 - 请参阅下面)
<h1>让我们聊天</h1>
<%= button_to "创建新对话", conversations_path, method: :post, class: "btn btn-primary my-3" %>
  1. 控制器 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
  1. 显示页面 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 %>

  1. 运行 rails s 并进行测试 在Ruby on Rails中使用ruby-openai API gem:如何实现流式对话?

资源:

更多信息:

英文:

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

  1. 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 &quot;answers&quot;, force: :cascade do |t|
    t.text &quot;content&quot;
    t.integer &quot;question_id&quot;, null: false
    t.datetime &quot;created_at&quot;, null: false
    t.datetime &quot;updated_at&quot;, null: false
    t.index [&quot;question_id&quot;], name: &quot;index_answers_on_question_id&quot;
  end

  create_table &quot;conversations&quot;, force: :cascade do |t|
    t.text &quot;initial_question&quot;
    t.datetime &quot;created_at&quot;, null: false
    t.datetime &quot;updated_at&quot;, null: false
    t.text &quot;historic&quot;
  end

  create_table &quot;questions&quot;, force: :cascade do |t|
    t.text &quot;content&quot;
    t.integer &quot;conversation_id&quot;, null: false
    t.datetime &quot;created_at&quot;, null: false
    t.datetime &quot;updated_at&quot;, null: false
    t.index [&quot;conversation_id&quot;], name: &quot;index_questions_on_conversation_id&quot;
  end

  add_foreign_key &quot;answers&quot;, &quot;questions&quot;
  add_foreign_key &quot;questions&quot;, &quot;conversations&quot;
end
  1. Routes
Rails.application.routes.draw do
  root &quot;pages#home&quot; # supposes that you have a pages controller with a home action
  resources :conversations, only: [:create, :show]
  post &quot;question&quot;, to: &quot;conversations#ask_question&quot;
end
  1. Home page view (with just a button that redirects to the create conversation action -- see bellow)
&lt;h1&gt;Let&#39;s talk&lt;/h1&gt;
&lt;%= button_to &quot;Create New Conversation&quot;, conversations_path, method: :post, class: &quot;btn btn-primary my-3&quot; %&gt;
  1. Controller app/controllers/conversations_controller.rb
class ConversationsController &lt; 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 = &quot;#{@question.content}\n#{response}&quot;
    else
      response = OpenaiService.new(&quot;#{conversation.historic}\n#{params[:entry]}&quot;).call
      conversation.historic += &quot;\n#{@question.content}\n#{response}&quot;
    end
    conversation.save
    @answer = Answer.create(content: response, question: @question)
    redirect_to conversation_path(conversation)
  end
end
  1. Show page app/views/conversations/show.html.erb
&lt;h1&gt;This is your conversation&lt;/h1&gt;
&lt;p&gt;Ask your question&lt;/p&gt;
&lt;form action=&quot;&lt;%= question_path %&gt;&quot;, method=&quot;post&quot;&gt;
  &lt;input type=&quot;hidden&quot; name=&quot;conversation&quot; value=&quot;&lt;%= @convo.id %&gt;&quot;&gt;
  &lt;textarea rows=&quot;5&quot; cols=&quot;33&quot; name=&quot;entry&quot;&gt;&lt;/textarea&gt;
  &lt;input type=&quot;submit&quot; class=&quot;btn btn-primary&quot;&gt;
&lt;/form&gt;

&lt;br&gt;

&lt;ul&gt;
  &lt;% @convo.questions.each do |question| %&gt;
    &lt;li&gt;
      Q: &lt;%= question.content.capitalize %&gt; &lt;%= &quot;?&quot; if question.content.strip.last != &quot;?&quot; %&gt;
    &lt;/li&gt;
    &lt;li&gt;
      A: &lt;%= question.answers.first.content %&gt;
    &lt;/li&gt;
  &lt;% end %&gt;
&lt;/ul&gt;

&lt;%= link_to &quot;Back&quot;, root_path %&gt;

  1. rails s and test 在Ruby on Rails中使用ruby-openai API gem:如何实现流式对话?

Resources:

Going Further:

huangapple
  • 本文由 发表于 2023年6月1日 23:05:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76383308.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定