26
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

お題は不問!Qiita Engineer Festa 2023で記事投稿!

ChatGPTめっちゃ痩せたいです

Last updated at Posted at 2023-07-02

初めまして。HRBrainでソフトウェアエンジニアをしているビクトルと申します。

最近ChatGPTが人気になって、私はChatGPTのAPIを試して遊びたいと思っていました。私を知ってる人は筋トレマニアという印象を持っているのでChatGPTに栄養指導をしてもらおうと思っています。

最初にどんなことを考えましょ

Screenshot 2023-06-16 at 14.04.18.png

:cry:

今回の目標はシンプルなサービスを作ることだけではなく、爆速で開発をすることです(一週間以内に全部終わりたいです)

早速行きましょ!

ChatGPTのリクエストとリスポンス

最初からChatGPTのリスポンスは気にせずにしたいので2つの方法を考えました。

  • WebSocketを使う
  • ASYNCリクエストを使う

ASYNCでしてみれば実装が複雑になりそう気がしたのと、今回は速さが大事なのでWebSocketを選択しました。

Show me the code!

ChatGPTをinputに1日の摂取カロリーと体重と持ってる材料で3日以内の栄養指導を説明してくれるというアプリを作りたいと思っています。

FrontEnd側

スピードに対してnextを選択しました。

メインページでWebSocketクライアントを使いましょ

const ws = new WebSocket("ws://<server>:<port>/<endpoint>")

これで四つのイベントをハンドリングしましょう

ws.onopen = () => {
  // サーバーと繋がるとき
}

ws.onerror = () => {
  // エラーが起こるとき
}

ws.onmessage = (event) => {
  // メッセージが返すとき
  // eventでデータと他のプロパティを持っている
}

ws.onclose = () => {
  // WebSocketのconnectionを閉まるとき
}

BackEnd側

ここでChatGPTと連携をする。

使っているライブラリは

  • chi ルーター
  • melody WebSocketサーバー
    このライブラリはgorillaのwebsocketのラッパーです
  • go-openai

コードはこんな感じになっている

m := melody.New()
r := chi.NewRouter()

// CORSを設定しないといけない
r.Use(cors.Handler(cors.Options{
    AllowedOrigins: []string{"http://*", "ws://*"},
    AllowedMethods: []string{http.MethodPost, http.MethodGet, http.MethodOptions},
    AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token"},
    MaxAge:         300,
}))

// このルーターには最初`/`をつけてWebSocketのルーターを書いている
r.Route("/", func(ws chi.Router) {
    ws.Get("/<endpoint>", func(w http.ResponseWriter, r *http.Request) {
        if err := m.HandleRequest(w, r); err != nil {
            // エラーをハンドリング

            return
        }
    })
})

MelodyライブラリはJavascriptWebSocketと似てるメソッドを実装して。。。


// HandleMessageはクライアントからのイベントを受けるハンドラー
m.HandleMessage(func(s *melody.Session, msg []byte) {
    
    // ここにユースケースでChatGPTライブラリを叩いている
    d, err := advisory.Question(ctx, domain.Advisory{Message: question.Question})
    if err != nil {
        fmt.Println(err)
        _ = m.Broadcast([]byte(`err: ` + err.Error()))
    }

    b, err := json.Marshal(reqDomain.Response{Advise: d.Message})

    // クライアントにリスポンスを返す
    _ = m.Broadcast(b)
})

// WebSocketと連携を切られるとき
m.HandleDisconnect(func(session *melody.Session) {
    _ = session.Write([]byte(`diss`))
})

ユースケースでCreateChatCompletionのメソッドを使う、このメソッドにはChatGPTのWebでやりとりをするときと一緒です。

resp, err := a.client.CreateChatCompletion(
    ctx,
    openai.ChatCompletionRequest{
        Model: openai.GPT3Dot5Turbo0301,
        Messages: []openai.ChatCompletionMessage{
            {
                Role:    openai.ChatMessageRoleUser,
                Content: adv.Message,
            },
        },
    },
)

ModelChatGPTのAIモーデルです。

これでサーバーとクライアントを実行して試していきましょーー

ezgif.com-video-to-gif (2).gif

コード管理はこちらです。

26
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?