前回の記事で下記のPythonコードから、astとtokenizeモジュールを用いてJSONに構造化する方法を記しました。
from dataclasses import dataclass @dataclass class LogA: """Aの情報を表すログ""" __logname__ = "log_a" a1: int # Aの1つ目の情報 a2: str # Aの2つ目の情報 @dataclass class LogB: """Bの情報を表すログ""" __logname__ = "log_b" b1: int # Bの1つ目の情報 b2: str b3: float # Bの3つ目の情報 @dataclass class LogC: """Cの情報を表すログ""" __logname__ = "log_c" c1: int c2: str # Cの2つ目の情報 c3: float # Cの3つ目の情報 c4: bool # Cの4つ目の情報
このPythonコードを次のJSONに変換する問題を考えます。
{ "name": "log_a", "desc": "Aの情報を表すログ", "columns": [ {"name": "a1", "desc": "Aの1つ目の情報"}, {"name": "a2", "desc": "Aの2つ目の情報"}, ] }
{ "name": "log_b", "desc": "Bの情報を表すログ", "columns": [ {"name": "b1", "desc": "Bの1つ目の情報"}, {"name": "b2", "desc": ""}, {"name": "b3", "desc": "Bの3つ目の情報"}, ] }
{ "name": "log_c", "desc": "Cの情報を表すログ", "columns": [ {"name": "c1", "desc": ""}, {"name": "c2", "desc": "Cの2つ目の情報"}, {"name": "c3", "desc": "Cの3つ目の情報"}, {"name": "c4", "desc": "Cの4つ目の情報"}, ] }
本記事では、これを生成AIで構造化する方法を記します。
最初に示したPythonコードの例のようにクラスのみがまとまっていれば構造化しやすそうですが、実際のPythonコードにはimport文や関数など構造化対象の部分以外の余計な記述がたくさんあります。
変換対象ではない余計な入力が多いと、生成AIを惑わせることになり、精度の悪い生成結果をもたらしてしまいます。
from dataclasses import dataclass import xxx import yyy import zzz @dataclass class LogA: """Aの情報を表すログ""" __logname__ = "log_a" a1: int # Aの1つ目の情報 a2: str # Aの2つ目の情報 def hoge(): print(1) def fuga(): print(2) @dataclass class LogB: """Bの情報を表すログ""" __logname__ = "log_b" b1: int # Bの1つ目の情報 b2: str b3: float # Bの3つ目の情報 def poyo(): print(3) @dataclass class LogC: """Cの情報を表すログ""" __logname__ = "log_c" c1: int c2: str # Cの2つ目の情報 c3: float # Cの3つ目の情報 c4: bool # Cの4つ目の情報
上記のようなコードからクラスの部分を切り取るのに再びastモジュールが役に立ちます。
astモジュールを用いることで、クラスごとのノードを取得でき、同時にノードの開始行数、終了行数を取得することができます。
これにより、上記のコードからクラスの先頭行、終了行を取得し、対象行数のスライスを取り、その部分を結合し下記を得ます。
@dataclass class LogA: """Aの情報を表すログ""" __logname__ = "log_a" a1: int # Aの1つ目の情報 a2: str # Aの2つ目の情報
@dataclass class LogB: """Bの情報を表すログ""" __logname__ = "log_b" b1: int # Bの1つ目の情報 b2: str b3: float # Bの3つ目の情報
@dataclass class LogC: """Cの情報を表すログ""" __logname__ = "log_c" c1: int c2: str # Cの2つ目の情報 c3: float # Cの3つ目の情報 c4: bool # Cの4つ目の情報
これを順に生成AIに入力していきます。
トークン作成には下記のような文字列を使います。
token=""" Pythonコードが入力として与えられます。 Pythonコードに書かれているclassの情報を解析して「ログ名」「ログの説明」、各フィールドに対して「フィールド名」「フィールドの説明」の情報を表すJSONを作成してください。 [コード例]が与えられた場合、[出力例]のようなJSONを返して下さい。 [コード例] ```python @dataclass class LogX: \"\"\"Xの情報を表すログ\"\"\" __logname__ = "log_x" x1: int # Xの1つ目の情報 x2: str # Xの2つ目の情報 x3: str # Xの3つ目の情報 ``` [出力例] ``` { "name": "log_x", "desc": "Xの情報を表すログ", "columns": [ {"name": "x1", "desc": "Xの1つ目の情報"}, {"name": "x2", "desc": "Xの2つ目の情報"}, {"name": "x3", "desc": "Xの3つ目の情報"} ] } ``` 下記がJSON化してほしいPythonコードになります。 ```python @dataclass class LogA: \"\"\"Aの情報を表すログ\"\"\" __logname__ = "log_a" a1: int # Aの1つ目の情報 a2: str # Aの2つ目の情報 ``` jsonの部分のみを返してください。 出力結果に```や```jsonは必要ありません。 columnsの最後の要素に,は必要ありません。 """