プログラムはネットワークで話す
HTTPは、2つのプログラムがネットワークで会話する方法です。一方がリクエストを送り、もう一方がレスポンスを返します。データには、たいていJSONというテキスト形式を使います。
どのモデルAPIも、この方法で動きます。リクエストとレスポンスが読めれば、どのAPIでも使えます。
このレッスンのゴール
メモ
HTTPリクエストとJSONボディを読み書きできる。
キーワード
| ことば | いみ | れい |
|---|---|---|
| リクエスト | プログラムが何かを頼むために送るもの | |
| レスポンス | リクエストへの返事として戻ってくるもの | |
| ヘッダー | リクエストやレスポンスについての名前付きの情報 | content-type |
| ステータスコード | リクエストがどうなったかを表す番号 | 200 |
| JSON | キーと値でできたデータのテキスト形式 |
学生が入力するセルは、このプレビューでは空白です。
リクエストは4つの部分でできている
メソッドは、何をするかを表します。GET は読み取り、POST はデータの送信です。URLは、送り先です。ヘッダーは、データの種類などの情報を足します。ボディは、データそのものです。
モデルAPIは、メッセージを入れたJSONボディ付きの POST を受け取ります。
例:リクエストを部分ごとに見る
| 部分 | 入っているもの | この呼び出しでは |
|---|---|---|
| メソッド | すること | POST |
| URL | 送り先 | http://ai:4000/v1/chat/completions |
| ヘッダー | ボディの種類 | content-type: application/json |
| ボディ | JSON形式のデータ | model, messages, max_tokens |
学生が入力するセルは、このプレビューでは空白です。
スクリプトが送るリクエストを表示
docker exec -w /home/node/project agent node -e "const body={model:'lab',messages:[{role:'user',content:'こんにちはと言ってください'}],max_tokens:20};console.log('POST /v1/chat/completions');console.log('content-type: application/json');console.log(JSON.stringify(body,null,2))"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
JSONはキーと値のテキスト
JSONは、データをテキストで書きます。オブジェクトは、"キー": 値 の組を波かっこで囲んだものです。リストは角かっこで囲みます。キーは必ずダブルクォートで囲みます。
プログラムは、送るときにデータをJSONテキストに変え(JSON.stringify)、読むときにJSONテキストをデータに戻します(JSON.parse)。
レスポンスにはステータスとボディがある
レスポンスで最初にあるのはステータスコードです。200から299の番号は、成功を表します。400から499は、リクエスト側の誤りです。500以上は、サービス側の問題です。
ボディを読む前に、ステータスを読みましょう。
例:よく見るステータスコード
| ステータス | 意味 | すること |
|---|---|---|
| 200 | 成功した | ボディを読む |
| 400 | リクエストが間違っている | ボディを直す |
| 401 | キーがないか、間違っている | キーを確かめる |
| 403 | 許可されていない | メッセージを読む |
| 429 | リクエストが多すぎる | 待ってから再試行する |
| 503 | まだ準備ができていない | 後でもう一度試す |
学生が入力するセルは、このプレビューでは空白です。
モデルを呼んでステータスを読む
docker exec -w /home/node/project agent node -e "const u=(process.env.AI_URL||'http://ai:4000')+'/v1/chat/completions';const show=(s,t,k,m)=>{console.log('ステータス:'+s);console.log('コンテンツタイプ:'+t);console.log('トップレベルのキー:'+k);console.log('応答:'+m)};(async()=>{try{const r=await fetch(u,{method:'POST',headers:{'content-type':'application/json',authorization:'Bearer lab'},body:JSON.stringify({model:'lab',messages:[{role:'user',content:'あいさつを3語で言ってください。'}],max_tokens:20})});const j=await r.json();if(r.ok===false)throw new Error(r.status+' '+j.error.message);show(r.status,r.headers.get('content-type'),Object.keys(j).join(', '),j.choices[0].message.content)}catch(e){console.log('応答なし('+e.message+')。記録済みサンプル:');show(200,'application/json','id, object, model, choices, usage','こんにちは、みなさん。')}})()"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
よくある間違い
注意
ステータス200は、答えが正しいという意味だと考える人が多くいます。実際には、リクエストが成功したというだけです。モデルは、間違った答えや変な答えにも200を返すことがあります。まずステータス、次に中身を確かめましょう。
さらに:リクエストを変えてみる
リクエストを表示する実行を書き換えます。ボディに temperature: 0 を足して、もう一度実行します。次に max_tokens を 5 に変えます。
変えるたびに、どの部分を変えたかを書き留めましょう。メソッド、URL、ヘッダー、ボディのどれかです。