compile()関数を使うとPythonスクリプトのSyntax Errorを検出できる。スクリプトとその情報を与えてQwen3でバグフィクスをさせてみた。
from langchain_ollama import OllamaLLM from langchain_ollama import OllamaEmbeddings from langchain_community.vectorstores import FAISS from langchain_community.document_loaders import TextLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain.chains import RetrievalQA import re base_question="""あなたはPythonのコード修正アシスタントです。 あなたの仕事は、PythonコードのSyntax Errorを修正することです。 ・Syntax Errorの内容はPythonのcompile()関数により取得したものが与えられる。 ・Syntax Errorの修正以外は、オリジナルのコードを維持すること。 ・修正したスクリプトを出力せよ。 ・出力するスクリプトは ```python と ``` で囲うこと。 //////////////////////////////////////// Syntax Errorの内容: {SyntaxError} //////////////////////////////////////// 修正すべきスクリプト: {MyScript} """ ############################################################################################ ############################################################################################ ############################################################################################ ############################################################################################ ############################################################################################ ############################################################################################ def extract_python_code_blocks(text): """ 与えられた文字列から、 ```python ~ ``` で囲まれた範囲のコードをリストで返す。 """ pattern = r"```python\s*(.*?)```" match = re.search(pattern, text, re.DOTALL) return match.group(1) if match else None def check_syntax(code_str): try: compile(code_str, "<string>", "exec") print("構文エラーはありません。") return None except SyntaxError as e: print(f"構文エラーが発生しました: {e}") error_message = ( f"構文エラー: {e.msg}\n" f"ファイル名: {e.filename}\n" f"行番号: {e.lineno}\n" f"エラー発生位置: {e.offset}\n" f"エラー箇所: {e.text.strip() if e.text else '不明'}" ) return error_message ############################################################################################ ############################################################################################ ############################################################################################ ############################################################################################ ############################################################################################ ############################################################################################ def trycode(source): llm = OllamaLLM(model="qwen3:4b") code = source Loop = True while Loop: print("trycode===============================") print(code) print("=========================================") # 構文が間違っていたらもう一度生成し直し err = check_syntax(code) if err == None: break else: print("Syntax Error ============================") print(err) print("=========================================") # 問い合わせ作成 q1 = base_question.format(SyntaxError=err, MyScript=code) # 問い合わせ実行 response = llm.invoke(q1) code = re.sub(r"<think>.*?</think>", "", response, flags=re.DOTALL) # ```pythonを外す code = extract_python_code_blocks(code) return code ############################################################################################ ############################################################################################ ############################################################################################ ############################################################################################ ############################################################################################ ############################################################################################ # スクリプトファイル読み込み # myscript_path = "test.py" # パスを引数から取得 import sys if len(sys.argv) < 2: print("Usage: python auto_debugger.py <script_path>") sys.exit(1) myscript_path = sys.argv[1] if not myscript_path.endswith(".py"): print("Error: The script path must end with '.py'") sys.exit(1) myscript = "" with open(myscript_path, "r",encoding="utf-8") as f: myscript = f.read() myscript = trycode(myscript)# 自動Syntax Error修復 print(myscript) # スクリプトファイル書き込み with open(myscript_path + "_fix.py", "w",encoding="utf-8") as f: f.write(myscript)
import numpy as np import cv2 def generate_white_noise(width, height): # 0〜255のランダムな値を持つ画像を生成 noise = np.random.randint(0, 256, (height, width, 3), dtype=np.uint8) return noise def save_image(image, filename): cv2.imwrite(filename, image) if __name__ == "__main__": width = 640* height = 480 noise_image = generate_white_noise(width, height save_image(noise_image, "white_noise.png")
修正前
import numpy as np import cv2 def generate_white_noise(width, height): # 0〜255のランダムな値を持つ画像を生成 noise = np.random.randint(0, 256, (height, width, 3), dtype=np.uint8) return noise def save_image(image, filename): cv2.imwrite(filename, image) if __name__ == "__main__": width = 640 height = 480 noise_image = generate_white_noise(width, height) save_image(noise_image, "white_noise.png")
修正後