Structured Outputsを使うとかしこい文章校正ツールを手軽につくることができる

Structured Outputsは、Chat Completions APIから得られる返答のデータの構造と型を強制するための機能で、最近OpenAIのSDKにも追加されました。

https://platform.openai.com/docs/guides/structured-outputs/ui-generation

この機能を利用することで、簡単な文章校正ツールを作ることができます。

仕組み

  1. 文章データをOpenAIのAPIに送信する際に、各行に番号を付与します。これにより、GPTは各文がどの行にあるかを特定できるようになります。

  2. 文章に対する指示をプロンプトに添えます。例えば、「前提情報が足りない部分を指摘して」といった指示を加えます。

  3. 返答をStructured Outputsで制限することで、「何行目に対するコメント」という形式の結果を得ることができます。

この方法は「LLM にコードを「差分」で書き換えさせるためのアイデア」から着想をえています。

以下は、この文章校正ツールのサンプルコードです:

#!/usr/bin/env python
import sys
from pydantic import BaseModel
from openai import OpenAI


class LintResultItem(BaseModel):
    num: int
    line: str
    comment: str

class LintResult(BaseModel):
    items: list[LintResultItem]


if __name__ == "__main__":
    input_file = sys.argv[1]
    rule = sys.argv[2]
    with open(input_file, "r", encoding="utf-8") as infile:
        text = infile.readlines()
        text_with_line_numbers = "\n".join(
            [f"{i+1}: {line}" for i, line in enumerate(text)]
        )
        
        client = OpenAI()
        completion = client.beta.chat.completions.parse(
            model="gpt-4o-2024-08-06",
            messages=[
                {"role": "system", "content": f"下記は行番号付きのテキストです。ユーザーの指示に従い、必要な箇所にコメントをしてください。\n指示: {rule}"},
                {"role": "user", "content": text_with_line_numbers},
            ],
            response_format=LintResult,
        )

        result = completion.choices[0].message.parsed
        result_items = result.items
        for item in result_items:
            print(f"{item.comment}")
            print(f"  {item.num}: {item.line}")
            print("")

すべての処理を手動でChatGPTに入力することも可能ですが、行番号をすべて入力するなどの作業は煩雑です。このような定型的なタスクは自動化する方が効率的で現実的です。

出力をStructured Outputsにすることで、メタ情報が付与されるので以下のような利点があります:

  1. リントツールとしてエディタに組み込みやすくなる
  2. ウェブアプリ化など、他のプログラムと連携しやすくなる
  3. 書き換えの自動化など、結果の解析や処理が容易になる

使用例

以下は、本記事の執筆中の文章に対して校正をお願いした例です:

❯ python main.py sizu.md 前提情報が足りない部分を指摘して      
この行の主張を具体的に示すため、Structured Outputsがどのように文章校正に役立つのか、またその利点や応用例を説明する必要があります。
  1: # Structured Outputsを使うとかしこい文章校正ツールを手軽に作ることができる

プロンプトに添える指示の具体例を示し、Structured Outputsがどのように機能するのか、プロンプトと出力の間のメカニズムを具体的に説明すると読者にとって分かりやすくなります。
  5: 文章に対する指示をプロンプトに添える。返答をStructured Outputsで制限することで「何行目に対するコメント」という結果を得ることができる

自動化する利点をより具体的に示すことで、手動の方法に対する自動化の優位性を明確に説明する必要があります。また、具体的な例やシナリオを挙げると理解が深まります。
  7: これによって簡単な文章校正ツールを書ける。その気になれば全ての処理は手動でChatGPTに向かって打ち込むことで代用はできるが、しかし、この程度のタスクなら自動化する方が現実的です。
❯ python main.py sizu.md "漢字とかなの使い分けの方針は一貫しているか"
漢字とかなの使い分けに関して、一貫性が欠けている可能性があります。"作る"は漢字にしており、他の動詞(例:"できる"など)は平仮名が使われています。
  1: # Structured Outputsを使うとかしこい文章校正ツールを手軽に作ることができる

漢字とかなの使い分けに関して、一貫性が欠けています。"得て"は漢字にしているが、他の動詞(例:"込む"など)は平仮名です。
  15: この方法は「LLM にコードを「差分」で書き換えさせるためのアイデア」から着想を得ています。

"全て"は漢字で、"すべて"は平仮名が混在しています。記述が一貫していないようです。
  23: 全ての処理を手動でChatGPTに入力することも可能ですが、行番号をすべて入力するなどの作業は煩雑です。このような定型的なタスクは自動化する方が効率的で現実的です。

"しやすく"は平仮名ですが、他の動詞(例:"使う"など)は漢字になっています。記述が一貫していない可能性があります。
  46: 他のプログラムと連携しやすくなる