用 Ruby 实现基于大模型的命令行角色扮演脚本

最近想研究一下大模型的使用,为了练手写了一个命令行角色扮演脚本,在此分享。

先看效果:

代码放在文末,这是一个单文件脚本,运行需要安装 Ruby 环境。

使用的时候把代码保存在本地,例如 main.rb

申请一个 OpenAI 兼容的 API(我用的是 DeepSeek),设置环境变量到同目录的 .env 文件,内容为:

OPENAI_BASE_URL=https://api.deepseek.com
OPENAI_API_KEY=sk-xxx

然后执行 ruby main.rb 即可。

脚本代码:

require "bundler/inline"

gemfile do
  source "https://rubygems.org"

  gem "openai", github: "openai/openai-ruby", branch: "main"
  gem "dotenv"
  gem "reline"
end

require "openai"
require "dotenv/load"
require "reline"

trap("INT") do
  exit
end

if ENV["OPENAI_BASE_URL"].nil? || ENV["OPENAI_API_KEY"].nil?
  puts "需要设置环境变量 OPENAI_BASE_URL 和 OPENAI_API_KEY"
  exit
end

class Role
  def initialize(name:, prompt:)
    @name = name
    @prompt = prompt

    @openai = OpenAI::Client.new
    @messages = [
      {
        "role": "system",
        "content": @prompt
      }
    ]
  end

  def play
    request

    loop do
      puts
      user_input = Reline.readline("我> ", true)

      @messages << {
        "role": "user",
        "content": user_input
      }

      request
    end
  end

  def request
    stream = @openai.chat.completions.stream_raw(
      messages: @messages,
      model: "deepseek-chat"
    )

    puts
    print @name + "> "
    content = ""
    stream.each do |completion|
      sub_content = completion[:choices][0][:delta][:content]
      content += sub_content
      print sub_content
      $stdout.flush
    end
    puts

    @messages.push({
      "role": "assistant",
      "content": content
    })
  end
end

# 根据需要修改角色名称和设定
Role.new(
  name: "水无灯里",
  prompt: "你是水星领航员的水无灯里。不回答超出角色设定的问题。首先打个招呼,然后询问客户有什么需要。"
).play
1
所有评论 0
@Rei
Ruby 程序员,Ruby China 管理员,GeekNote 创建者。
准则 博客 联系 反馈 © 2025 Geeknote