見出し画像

DeepSeek-R1(deepseek-reasoner)についてまとめ、API から試してみる

tl;dr

  • DeepSeek R1 は MIT ライセンスで商用利用可能なオープンモデル

  • DeepSeek API は他の SOTA モデルと比較して一桁程度小さい料金で利用可能

  • API レスポンスは CoT 部分を返す reasoning_content と最終的な回答部分を返す content に分けられる

  • max_tokens を 1 に設定すると、思考過程のみを抽出できるが、CoT 部分も課金対象となる

  • aider のベンチマークでは、DeepSeek R1 と Claude 3.5 Sonnet の組み合わせが o1 を超える性能を発揮したが、R1 の CoT 部分を渡しているわけではない


みなさん、DeepSeek R1 を使われていらっしゃいますか?さすがに 671B とローカル環境で動かすには荷が重いパラメータ数ではありますが、DeepSeek Chat(ウェブ版)からであれば無料で使うことができ、API からも他のモデルと比べて格安で利用することのできるモデルです。

私ごとですが、今がちょうど Claude / ChatGPT のサブスク期間が過ぎたタイミングなので、普段使いでどこまで DeepSeek が使えるかを測る意図も含め、メインのチャット UI を DeepSeek Chat にしています。o1 のような reasoning のできる DeepThink はもちろん、Search も使えます。なんと ChatGPT 上ではできない、それらの同時利用もできるので、しばらくはこれ一本で事足りるのではないかと期待しています。Search も Google Advanced で使える Deep Research 並みの数十件の引用をしてくれるのでかなり満足度が高いです。利用規約によると学習される可能性があるとのことで、その点だけご注意ください。

R1 / R1-Zero のモデルの重み自体も MIT ライセンスで公開されており、商用利用に制限がなく、これからのローカル LLM の性能のひとつの基準点になるのかなと個人的には考えています。

本記事は、今更ながら公式ドキュメントを参照しながら API を叩いてみたよという単なるログではあるのですが、最後に max token を 1 にすることで思考過程のみを取り出すなんてこともしたりします。あまり難易度は高くありませんので、よろしければご自身の環境でも試されてみてください。


DeepSeek の公式ドキュメントは Docusaurus のアイコンがそのままになっていたり、アラは目立つものの必要な機能は十分に書いてあるので、一度通読しておくと良いかと思います。今回は deepseek-reasoner 関連の部分にだけ言及します。

簡単に上記のコード部分以外を手動でまとめると下記のようになるかなと思います。

  • DeepSeek-R1 は OpenAI の o1 モデルと同等性能かつオープンソースなモデル

    • (コメントまでですが、オープンモデルではあるものの、オープンソースとまでは言えないのかなと考えています)

  • GitHub や arXiv にて technical report が公開されている

    • 個人的には arXiv の方が HTML (experimental) のページで日本語翻訳しながら読めるのでオススメ

  • ライセンスが緩く、MIT で公開、商用利用も可

  • DeepSeek R1 は DeepSeek Chat(ウェブ版)からも API からも利用できる

    • モデルの指定は deepseek-reasoner、今回の記事で取り扱います

  • deepseek-reasoner は、最終的な回答をいきなり出力するのではなく、その前に Chain-of-Thought を用いることで最終的な回答の精度をあげている

    • 補足をすると CoT Prompting で用いられるような思考過程を生成し、その思考過程を元にクエリに対する回答を出力すると私は解釈しています

  • DeepSeek は openai ライブラリ互換で使えるが、deepseek-reasoner で用いるパラメータをサポートするために SDK のアップデートが必要

  • max tokens はデフォルトで 4k で、8k まで増やせる(CoT 部分は 32k まで)

  • API レスポンスは、CoT 部分を返す reasoning_content と最終的な回答部分を返す content に分けられる

  • context length は 64k で、reasoning_content はここにカウントされない

  • Function calling / JSON output / Fill in the middle Completion はサポートされない

    • その他、サポートされていないパラメータがいくつかある

  • マルチターンのチャットの場合、前のやり取りの CoT 部分は次のコンテクストに含まれない

少しできる or できないが不明瞭なので、細かい制御をしたいときは適宜対応可否を確認する必要がありますね。

価格は?

https://openai.com/api/pricing/

DeepSeek API はよく使われるモデルに対してどのくらい安いのでしょうか。

「*」のついているものはキャッシュヒット時の料金。他の SOTA のモデルと比べて一桁程度小さいことがわかります。

さっそく動かしてみる

ディレクトリを作成しましょう。

mkdir deepseek-reasoner
cd deepseek-reasoner

DeepSeek API は openai 互換ですので、openai ライブラリを使います。また、API Key を .env で指定するため、python-dotenv を使います。

uv init --python 3.12
uv add openai
uv add python-dotenv

https://platform.deepseek.com/api_keys

API Key を取得しましょう。上記の URL からコンソールページを開いて新しく API Key を発行しましょう。もし過去に発行した不要になった API Key があればこの機会に削除しておきましょう。

コンソールページより Create new API Key を押して、deepseek-reasoner とでもしておきましょうか。お好きな名前を指定してください。

API Key が表示されますので、Copy を押しましょう。

.env に下記のように API Key を入れましょう。

DEEPSEEK_API_KEY=sk-xxx

ストリーミングなし / あり ver のそれぞれを試してみます。

touch nostreaming.py streaming.py

公式ドキュメントに記載の内容を日本語にして、reasoning_content / content のそれぞれを出力します。

nostreaming.py として下記を保存します。

import os
from dotenv import load_dotenv
from openai import OpenAI

load_dotenv()

client = OpenAI(
    api_key=os.getenv("DEEPSEEK_API_KEY"), base_url="https://api.deepseek.com"
)

# Round 1
messages = [{"role": "user", "content": "9.11と9.8はどちらが大きいですか?"}]
response = client.chat.completions.create(model="deepseek-reasoner", messages=messages)

reasoning_content = response.choices[0].message.reasoning_content
content = response.choices[0].message.content

print("Round 1 Reasoning" + "-" * 20)
print(reasoning_content)
print("\nRound 1 Response" + "-" * 20)
print(content)

# Round 2
messages.append({"role": "assistant", "content": content})
messages.append(
    {"role": "user", "content": "「strawberry」という単語には「r」が何個ありますか?"}
)
response = client.chat.completions.create(model="deepseek-reasoner", messages=messages)

reasoning_content = response.choices[0].message.reasoning_content
content = response.choices[0].message.content

print("\nRound 2 Reasoning" + "-" * 20)
print(reasoning_content)
print("\nRound 2 Response" + "-" * 20)
print(content)

実行しましょう。

uv run nostreaming.py

手元の実行結果は下記のようになりました。

❯ uv run nostreaming.py
Round 1 Reasoning--------------------
まず、9.11と9.8を比較するために、小数点以下の桁数を揃えます。9.8は9.80とも表記できます。

次に、整数部分の9は両方とも同じなので、小数点以下を比較します。0.11と0.80では、0.80の方が大きいです。

しかし、これは間違いです。実際には小数点以下第一位の数字を比較する必要があります。9.11の小数点以下第一位は1で、9.8(9.80)のそれは8です。したがって、9.8の方が大きいことがわかります。

Round 1 Response--------------------
**解答:**
9.11 と 9.8 を比較するには、小数点以下の桁数を揃えるとわかりやすくなります。
\[
9.8 = 9.80
\]
次に、各桁を左から順に比較します:
- **整数部分**:どちらも **9** で等しいです。
- **小数点第1位**:**1**(9.11)と **8**(9.80)を比較します。
**8 > 1** なので、**9.80 の方が大きい**ことがわかります。

**結論:**
\[
\boxed{9.8 \text{ の方が大きい}}
\]

Round 2 Reasoning--------------------
まず、「strawberry」という単語を正確に綴りを確認します。よく間違えやすいので注意が必要です。

次に、アルファベットを一つずつ分解して確認します。s, t, r, a, w, b, e, r, r, y となります。ここで、各文字を数えながら「r」が含まれているかチェックします。

分解した結果、rは3番目、8番目、9番目の文字に存在します。つまり、合計3つの「r」が含まれていることがわかります。

ただし、綴りを間違えている可能性もあるため、再度確認する必要があります。正しい綴りは「strawberry」で、実際にrが3つ含まれています。

Round 2 Response--------------------
**解答:**
「strawberry」の綴りを分解して確認します:
\[
s \quad t \quad r \quad a \quad w \quad b \quad e \quad r \quad r \quad y
\]
この中で **r** は **3番目**、**8番目**、**9番目** の文字に存在します。

**結論:**
\[
\boxed{3 \text{ 個}}
\]

LaTeX 記法を交えつつ、正答まで辿り着くことができています。次にストリーミングも試してみましょう。

streaming.py として下記を保存します。差分は client.chat.completions.create に stream=True と指定している点と、reasoning_content / content を空文字で初期化してから response.choices[0] から delta.reasoning_content / delta.content をチャンクごとに取り出し加えている点です。

import os
from dotenv import load_dotenv
from openai import OpenAI

load_dotenv()

client = OpenAI(
    api_key=os.getenv("DEEPSEEK_API_KEY"), base_url="https://api.deepseek.com"
)

# Round 1
messages = [{"role": "user", "content": "9.11と9.8はどちらが大きいですか?"}]
response = client.chat.completions.create(
    model="deepseek-reasoner", messages=messages, stream=True
)

reasoning_content = ""
content = ""

print("Round 1 Reasoning" + "-" * 20)
for chunk in response:
    if chunk.choices[0].delta.reasoning_content:
        reasoning_content += chunk.choices[0].delta.reasoning_content
        print(chunk.choices[0].delta.reasoning_content, end="", flush=True)
    elif chunk.choices[0].delta.content:
        content += chunk.choices[0].delta.content

print("\n\nRound 1 Response" + "-" * 20)
print(content)

# Round 2
messages.append({"role": "assistant", "content": content})
messages.append(
    {"role": "user", "content": "「strawberry」という単語には「r」が何個ありますか?"}
)
response = client.chat.completions.create(
    model="deepseek-reasoner", messages=messages, stream=True
)

reasoning_content = ""
content = ""

print("\nRound 2 Reasoning" + "-" * 20)
for chunk in response:
    if chunk.choices[0].delta.reasoning_content:
        reasoning_content += chunk.choices[0].delta.reasoning_content
        print(chunk.choices[0].delta.reasoning_content, end="", flush=True)
    elif chunk.choices[0].delta.content:
        content += chunk.choices[0].delta.content

print("\n\nRound 2 Response" + "-" * 20)
print(content)

実行してみましょう。

uv run streaming.py

実行結果は下記のようになりました。

❯ uv run streaming.py
Round 1 Reasoning--------------------
まず、比較する二つの数値は9.11と9.8です。どちらが大きいかを判断するために、それぞれの数値を同じ位取りで比べる必要があります。

9.11は小数点以下第二位まであり、9.8は小数点以下第一位までです。比較を容易にするため、9.8を9.80に変換して、両方の数値を小数点以下第二位まで揃えます。

次に、整数部分を確認します。どちらも9なので同じです。次に小数点第一位の数字を見ると、9.11は1、9.80は8です。8の方が1より大きいので、この時点で9.80の方が大きいと判断できます。

したがって、9.8は9.11よりも大きい数値であると言えます。

Round 1 Response--------------------
**解答:**

9.11 と 9.8 を比較します。

1. **小数点以下の桁数を揃える**
9.8 を 9.80 と表記します(値は同じです)。

\[
9.11 \quad \text{と} \quad 9.80
\]

2. **整数部分を比較**
両方の整数部分は **9** で等しいです。

3. **小数点第一位を比較**
- 9.11 の小数点第一位は **1**
- 9.80 の小数点第一位は **8**

**8 > 1** なので、この時点で **9.80 > 9.11** と判断できます。

**結論:**
\(\boxed{9.8 \text{ の方が大きい}}\)

Round 2 Reasoning--------------------
まず、「strawberry」という単語のスペルを正確に確認します。ユーザーが質問しているのは「r」の数ですから、一つずつ文字を分解して確認する必要があります。

単語を分解すると、s-t-r-a-w-b-e-r-r-yとなります。ここで各文字を順番に見ていきます。特に「r」が含まれる箇所に注意します。

分解した文字列を確認すると、3番目の文字が「r」で、その後7番目と8番目にも「r」が続いています。つまり、3文字目に1つ目、7文字目と8文字目にそれぞれ「r」があるように見えます。

ただし、正確に数えるために、再度確認します。正しいスペルは「strawberry」で、s-t-r-a-w-b-e-r-r-yです。この場合、3番目の「r」と、その後ろの部分で「er」の後に再び「r」が来ているので、合計2回「r」が出現していることになります。

しかし、スペルを間違えている可能性もありますので、もう一度確認します。例えば「strawberry」は「straw」と「berry」が合わさった単語です。「berry」の部分には「r」が2つ含まれているため、全体では「straw」の部分に1つ、「berry」に2つで合計3つになる可能性があります。

ここで混乱が生じます。実際の「strawberry」の正しいスペルでは、s-t-r-a-w-b-e-r-r-yであり、分解すると以下のようになります:
1. s
2. t
3. r
4. a
5. w
6. b
7. e
8. r
9. r
10. y

この場合、3番目、8番目、9番目に「r」があります。つまり、合計3つの「r」があるように見えますが、実際には「strawberry」の正しいスペルでは「r」は2つです。なぜなら、「berry」の部分はb-e-r-r-yであり、ここに2つの「r」があるからです。最初の「straw」の部分には「r」が1つあるため、合計3つではなく、2つになるはずです。

しかし、実際にスペルを確認すると、「strawberry」はs-t-r-a-w-b-e-r-r-yで、3番目の「r」、そして8番目と9番目に「r」が続きます。つまり、合計3つの「r」が存在することになります。これは矛盾しています。

この矛盾を解消するために、信頼できる辞書やスペルチェックツールで確認します。実際には、「strawberry」の正しいスペルは「s-t-r-a-w-b-e-r-r-y」であり、この中で「r」は3回出現します。最初の「r」は「straw」の部分にあり、その後「berry」の部分に2つの「r」があります。したがって、正解は3つです。

ただし、ユーザーが「strawberry」と入力した場合、実際には「r」は2つしか含まれていない可能性もあります。これは一般的なスペルミスによるものかもしれません。しかし、正確なスペルを前提とすると、答えは3つになります。

最終的な確認として、公式の辞書や教育資料を参照します。例えば、Oxford English Dictionaryでは「strawberry」のスペルは「s-t-r-a-w-b-e-r-r-y」とされており、3つの「r」が含まれています。したがって、正解は3つです。

Round 2 Response--------------------
**解答:**

「strawberry」のスペルを分解して確認します。

1. **単語を1文字ずつ分解**
\[
s \quad t \quad r \quad a \quad w \quad b \quad e \quad r \quad r \quad y
\]

2. **「r」の位置を特定**
- 3番目: \( r \)
- 8番目: \( r \)
- 9番目: \( r \)

3. **総数をカウント**
合計 **3個** の「r」が含まれています。

**結論:**
\(\boxed{3 \text{ 個}}\)

今回は strawberry の方で正解はしているものの少し混乱していますね!あやしい!o1 / o1-mini の思考過程が見えないので、単に正解したとしてもそれがロバストに正答できているか否かをきちんと検証するようにしたいとこの挙動を見て思いました。

おまけ

数日前に max tokens を 1 にしてみたという下記の X のポストを見かけました。プライシングページを見ると、たとえ max_tokens が 1 だったとしても CoT 部分も課金されるので少し誤解を招く表現にはなっていると思うものの、単に CoT 部分だけを抜き出してみるのもおもしろいと思うので試してみます。

先ほどの nostreaming.py の例のリクエスト部分に max tokens を指定してみます。ほぼ同じですが、下記にコードを記載します。

import os
from dotenv import load_dotenv
from openai import OpenAI

load_dotenv()

client = OpenAI(
    api_key=os.getenv("DEEPSEEK_API_KEY"), base_url="https://api.deepseek.com"
)

# Round 1
messages = [{"role": "user", "content": "9.11と9.8はどちらが大きいですか?"}]
response = client.chat.completions.create(model="deepseek-reasoner", messages=messages, max_tokens=1)

reasoning_content = response.choices[0].message.reasoning_content
content = response.choices[0].message.content

print("Round 1 Reasoning" + "-" * 20)
print(reasoning_content)
print("\nRound 1 Response" + "-" * 20)
print(content)

# Round 2
messages.append({"role": "assistant", "content": content})
messages.append(
    {"role": "user", "content": "「strawberry」という単語には「r」が何個ありますか?"}
)
response = client.chat.completions.create(model="deepseek-reasoner", messages=messages, max_tokens=1)

reasoning_content = response.choices[0].message.reasoning_content
content = response.choices[0].message.content

print("\nRound 2 Reasoning" + "-" * 20)
print(reasoning_content)
print("\nRound 2 Response" + "-" * 20)
print(content)

実行します。

uv run nostreaming.py

❯ uv run nostreaming.py
Round 1 Reasoning--------------------
嗯,用户问的是9.11和9.8哪个更大。这个问题看起来挺简单的,但可能对于刚开始学小数的人来说,容易搞混。首先,我需要确认用户是不是真的在比较这两个数,还是有其他的背景,比如版本号之类的,但通常版本号可能用不同的方式比较,不过这里看起来应该就是数值比较。

首先,我应该先比较整数部分。两个数的整数部分都是9,所以整数部分相同,接下来要看小数部分。9.11的小数部分是0.11,而9.8的小数部分是0.8。这里可能会让一些人困惑,因为0.11看起来像是两位小数,而0.8是一位小数。可能需要统一小数位数来比较。将0.8写成0.80的话,这样就有两位小数了,这时候0.80和0.11比较,显然0.80更大。所以9.8比9.11大。

不过,有时候可能会有误解,比如把9.11当作9年11个月,或者类似的单位,但用户没有提到单位,所以应该当作纯数字来比较。另外,可能有人会误以为更多的小数位数代表更大的值,比如觉得0.11比0.8大,因为11比8大,但实际上小数位的每一位的权重不同,十分位上的8比百分位上的1大很多。所以需要强调十分位和百分位的区别。

总结来说,比较的时候应该逐位比较,先看十分位,9.8的十分位是8,而9.11的十分位是1,所以9.8更大。即使9.11的百分位有1,但十分位的8已经超过了1,所以不需要继续比较下去。因此正确的结论是9.8比9.11大。

Round 1 Response--------------------


Round 2 Reasoning--------------------
嗯,用户现在问的是“strawberry”这个单词里有几个字母“r”。首先,我需要先正确拼写出这个单词,确认每个字母的位置。可能有时候拼写错误会导致答案出错,所以先检查一遍。

“Strawberry”正确的拼写是S-T-R-A-W-B-E-R-R-Y。现在我要一个一个字母数,看看有几个“r”。首先分解一下:

S, T, R, A, W, B, E, R, R, Y。

数到第三个字母是R,然后后面还有两个R吗?不,应该是第8和第9个字母是R吗?让我再仔细看一下。分解后的字母顺序应该是:

1. S
2. T
3. R
4. A
5. W
6. B
7. E
8. R
9. R
10. Y

所以,第三个字母是R,第八和第九个字母各有一个R,对吗?那总共有三个R?或者是不是这样?

或者可能我分解错了。再仔细分解一次:strawberry的正确拼写是s-t-r-a-w-b-e-r-r-y。中间部分可能有双写的r?比如在“berry”部分,通常拼写是b-e-r-r-y,所以这部分有两个r。而前面的straw是s-t-r-a-w,这里有一个r。所以加起来的话,总共有三个r?或者是不是?

不过,可能我哪里数错了。再数一次:

s - 1
t -2
r -3
a -4
w -5
b -6
e -7
r -8
r -9
y -10

所以,在位置3、8、9都是r,对吗?那总共有三个r?不过实际上,通常strawberry的正确拼写是s-t-r-a-w-b-e-r-r-y,所以应该有两个r在最后的部分,即berr中的两个r。而前面的straw中的r是第三个字母,所以总共有三个r吗?

不过这可能不对,因为可能前面的straw中的r只有一个,而后面berry部分有两个r,所以总共是三个r。或者可能用户拼写错误?比如是否应该是两个r?

这个时候可能需要再检查一下正确的拼写。让我确认一下:查一下strawberry的正确拼写。是的,正确的拼写是s-t-r-a-w-b-e-r-r-y,中间有两个r在最后的部分,也就是第8和第9个字母,所以总共有三个r吗?因为第三个字母是r,然后第8和第9各有一个r,所以总共三个?

或者是不是这样,前面的straw中的r是第三个字母,而berry中的两个r是第8和第9,所以总共有三个?

不过可能我之前分解错误。比如,strawberry的正确分解应该是:

s t r a w b e r r y,所以字母顺序是:

1. s
2. t
3. r
4. a
5. w
6. b
7. e
8. r
9. r
10. y

是的,这样的话,r出现在第3、8、9位,所以共有三个r?

但是通常strawberry的拼写是只有两个r?比如,可能用户输入错误,或者我哪里弄错了。这时候可能需要再查证一次。

根据牛津词典或其他可靠来源,strawberry的正确拼写确实是s-t-r-a-w-b-e-r-r-y,也就是有两个r在最后的部分,也就是在berry中的双r。而前面的straw中的r是第三个字母。所以总共有三个r?

或者是不是,前面straw中的r是一个,后面有两个,所以总共有三个?或者可能我数错了?

再数一次字母:

s (1)
t (2)
r (3)
a (4)
w (5)
b (6)
e (7)
r (8)
r (9)
y (10)

所以是的,三个r:位置3、8、9。因此答案是三个?

不过,根据常见的拼写,strawberry应该有两个r吗?或者是不是用户的问题可能有拼写错误?

或者可能用户自己拼错了单词?比如是否应该是strawberry的正确拼写是有一个r在straw部分,两个r在berry部分,所以总共三个r?

或者可能我的记忆有误?这时候可能需要通过分解单词来确认。比如straw + berry = strawberry。straw的拼写是s-t-r-a-w,其中有一个r。而berry的正确拼写是b-e-r-r-y,有两个r。所以组合起来就是三个r?但是当组合成strawberry时,是否合并了某些字母?

实际上,组合成strawberry的时候,是straw + berry,所以拼写为s-t-r-a-w-b-e-r-r-y,确实有三个r:一个来自straw,两个来自berry。所以总共有三个r。

因此,正确答案应该是三个r?

不过,可能我之前一直以为strawberry有两个r,这需要再次确认。比如,查一下在线词典。比如,Merriam-Webster的网站上,strawberry的拼写确实是s-t-r-a-w-b-e-r-r-y,也就是三个r吗?

不,等一下,可能我犯了一个错误。让我仔细看看:strawberry的拼写是s-t-r-a-w-b-e-r-r-y,对吗?分解的话,s, t, r, a, w, b, e, r, r, y。所以确实是三个r吗?因为第三个字母是r,第八和第九是r,所以三个?

或者是不是,可能strawberry的正确拼写只有两个r?比如,可能我记错了?

这时候可能需要实际查看拼写。例如,在Google搜索中,输入strawberry,结果会显示正确拼写。实际检查发现,正确的拼写是s-t-r-a-w-b-e-r-r-y,也就是三个r:位置3, 8, 9。因此,答案应该是三个?

不过,可能用户的问题中存在拼写错误,比如用户输入的是“strawberry”而不是正确的拼写,但用户的问题里是正确的,所以需要按照正确拼写来回答。

因此,正确的答案是两个r?或者三个?

这时候可能我的数数有误,或者分解错误。再分解一次:

s (1)
t (2)
r (3)
a (4)
w (5)
b (6)
e (7)
r (8)
r (9)
y (10)

所以有三个r:位置3、8、9。所以答案是三个?

但通常,人们可能认为strawberry有两个r,因为最后的berry有两个r,加上前面的straw的一个r,所以总共有三个?

或者可能,我哪里混淆了?比如,可能strawberry的正确拼写是s-t-r-a-w-b-e-r-r-y,是的,三个r。因此正确答案是三个?

或者可能我的分解有误,实际上只有两个r?

这时候,可能需要再次检查。比如,输入strawberry到文本中,然后逐个字母检查:

s t r a w b e r r y

是的,中间有三个r:第三个字母,以及第八、第九个字母。因此,总共有三个r?

但可能用户的问题中存在不同的拼写方式,或者用户自己存在拼写错误,但根据问题中的正确拼写,答案应该是三个?

不过,我之前可能一直认为strawberry有两个r,这让我感到困惑。这需要进一步确认。

根据剑桥词典,strawberry的拼写是S-T-R-A-W-B-E-R-R-Y,也就是三个r。是的,正确的拼写有三个r。因此,正确答案是三个?

不过,用户的问题可能是在测试我的细心程度,或者可能存在其他陷阱?

比如,是否考虑大小写?但用户的问题中没有提到大小写,所以应该按小写处理。

因此,结论是“strawberry”这个单词中有三个字母“r”。

Round 2 Response--------------------

レスポンスがなかなか返ってこないと思ったら、4 回も strawberry の分解をしていました。簡単なクエリに対しては無駄なトークンを消費しがちなのかもしれません。今回は中国語で CoT 部分を生成してくれました。日本語でプロンプトを書いても CoT 部分は日英中とブレる印象です。制御をしようかと思ったのですが、なかなか通常の Jailbreak では難しいようで、力不足を感じました。

また、この CoT 部分を他のモデルに適用するとどうなの?という議論を直近数日見かけることがありましたが、タスクによるでしょうと思っていたところで、ちょうど aider がブログ記事にまとめていました。

あくまで aider の polyglot benchmark & architect / editor model の役割分離に限っての話ですが、DeepSeek R1 + Claude 3.5 Sonnet の組み合わせが o1 を超える性能を発揮したとのこと。ただし、R1 の CoT 部分を渡しているわけではなく、最終回答のみを渡している点に注意。また、CoT 部分だけを渡した場合は性能の向上が見られなかったよう。

architect / editor については aider のプロンプト指定を見てみるとわかりやすいかと思います。

aider の記事は、単にコーディングの性能が DeepSeek R1 + Claude 3.5 Sonnet を組み合わせると性能があがるという話ではないことにだけご注意ください。あくまで aider 独自のベンチマーク評価における最高性能であって、汎用的なコーディングタスクにおいて R1 + Sonnet が上回るとまでは言っていないこと、CoT 部分の誤解がちらほら見かけたのでそれとは違うよという点に要注意です。

それでも DeepSeek R1 が安いことには変わりないので、もし aider 使いの方や自前の Agentic ツールなどで多段リクエストをする際はこの構成で試してみると面白いかもしれません。

以上となります。

宣伝(著書)

いいなと思ったら応援しよう!