はじめに
こんにちは。突然ですが、先日Xを閲覧していると以下のポストが流れてきました。
生成AIで書かれたコードかどうかを95%の精度で検知するサービスが始まったらしいです。その名も、AI Code Detector by Span。
対応する言語としては、TypeScriptとpythonに対応しているようです。
では実際に自分で書いたpythonのコードと生成AIに書かせたコードの2つを試してみたいと思います。
自分で書いたpythonコードを渡す
pythonで適当なコードを渡してみます。
渡すコード
def dollar_to_yen(dollar,rate):
return dollar * rate
# 引数にリテラルを指定して呼び出す
yen = dollar_to_yen(100,105)
print("為替レート:105")
print(f"100ドルは{yen}円")
rate = 100
dollar = 150
# 引数に変数を指定して呼び出す
yen = dollar_to_yen(dollar,rate)
print(f"為替レート:{rate}")
print(f"{dollar}ドルは{yen}円")
では検知してもらいましょう。確認っと。
おっと、
チェックするためには最低1000文字を張り付ける必要があるそうです。
ということで、改めてコードを作成します。
class Customer:
bmi = 22
def __init__ (self, number, name, height=0):
self.__number = number
self.__name = name
self.__height = height
# nameのゲッターメソッド
def get_name(self):
return self.__name
# numberのゲッターメソッド
def get_number(self):
return self.__number
# numberのセッターメソッド
def set_number(self, number):
self.__number = number
# heightのゲッターメソッド
def get_height(self):
return self.__height
def std_weight(self):
return Customer.bmi * (self.__height / 100) ** 2
# インスタンスを生成
taro = Customer(101, "ヤマダタロウ", 180)
name = taro.get_name()
taro.set_number(99)
number = taro.get_number()
height = taro.get_height()
print(f"{number}:{name} {height}cm")
# 以下、同じ処理を繰り返す
hanako = Customer(102, "ヤマダハナコ", 160)
print(f"{hanako.get_number()}:{hanako.get_name()} {hanako.get_height()}cm")
ichiro = Customer(103, "スズキイチロウ", 170)
print(f"{ichiro.get_number()}:{ichiro.get_name()} {ichiro.get_height()}cm")
jiro = Customer(104, "タナカジロウ", 165)
print(f"{jiro.get_number()}:{jiro.get_name()} {jiro.get_height()}cm")
for i in range(5, 300):
c = Customer(100+i, f"カスタマー{i}", 150 + (i % 50))
print(f"{c.get_number()}:{c.get_name()} {c.get_height()}cm 標準体重={c.std_weight():.1f}kg")
すると、
Your code is 0% written by AI.となりました。自分で書いたコードですからね。うれしい。
では次に、生成AIに書かせたコードで試してみたいと思います。
生成AIに書かせたpythonコードを渡す
今回はchatgptに書かせたコードを渡してみます。
生成AIに投げたプロンプト
以下の内容を生成AIに投げてみます。
コーディングをお願いします。
使用する言語:python
生成してほしいコード:お会計システム
条件:1000文字以上になるまで
渡すコード
import sys
class Item:
def __init__(self, code: int, name: str, price: float):
self.code = code
self.name = name
self.price = price
def __str__(self):
return f"[{self.code}] {self.name} - {self.price:.2f}円"
class Cart:
def __init__(self):
self.items = []
def add_item(self, item: Item, quantity: int = 1):
for _ in range(quantity):
self.items.append(item)
print(f"{item.name} を {quantity} 個追加しました。")
def remove_item(self, code: int, quantity: int = 1):
removed_count = 0
for i in range(quantity):
for cart_item in self.items:
if cart_item.code == code:
self.items.remove(cart_item)
removed_count += 1
break
if removed_count > 0:
print(f"商品コード {code} を {removed_count} 個削除しました。")
else:
print("指定の商品はカートに存在しません。")
def calculate_total(self):
return sum(item.price for item in self.items)
def show_cart(self):
if not self.items:
print("カートは空です。")
else:
print("=== カートの中身 ===")
summary = {}
for item in self.items:
if item.code not in summary:
summary[item.code] = {"name": item.name, "price": item.price, "count": 0}
summary[item.code]["count"] += 1
for code, info in summary.items():
print(f"{info['name']} x {info['count']} = {info['price']*info['count']}円")
print(f"合計金額: {self.calculate_total()}円")
class Payment:
def __init__(self, total_amount: float):
self.total_amount = total_amount
def pay_by_cash(self, cash_amount: float):
if cash_amount < self.total_amount:
print("支払い金額が不足しています。")
return False
change = cash_amount - self.total_amount
print(f"現金 {cash_amount} 円を受け取りました。お釣りは {change} 円です。")
return True
def pay_by_card(self, card_number: str):
if len(card_number) != 16 or not card_number.isdigit():
print("カード番号が不正です。16桁の数字を入力してください。")
return False
print(f"カード番号 {card_number[-4:]}**** にて {self.total_amount} 円を支払いました。")
return True
class BillingSystem:
def __init__(self):
self.catalog = []
self.cart = Cart()
def add_item_to_catalog(self, code: int, name: str, price: float):
item = Item(code, name, price)
self.catalog.append(item)
def show_catalog(self):
print("=== 商品一覧 ===")
for item in self.catalog:
print(item)
def find_item_by_code(self, code: int):
for item in self.catalog:
if item.code == code:
return item
return None
def run(self):
while True:
print("\n=== お会計システム ===")
print("1. 商品一覧表示")
print("2. カートに商品追加")
print("3. カートから商品削除")
print("4. カートの中身確認")
print("5. 支払い")
print("6. 終了")
choice = input("番号を入力してください: ")
if choice == "1":
self.show_catalog()
elif choice == "2":
self.show_catalog()
try:
code = int(input("商品コードを入力してください: "))
quantity = int(input("数量を入力してください: "))
except ValueError:
print("入力が不正です。")
continue
item = self.find_item_by_code(code)
if item:
self.cart.add_item(item, quantity)
else:
print("商品が見つかりません。")
elif choice == "3":
try:
code = int(input("削除する商品コードを入力してください: "))
quantity = int(input("削除する数量を入力してください: "))
except ValueError:
print("入力が不正です。")
continue
self.cart.remove_item(code, quantity)
elif choice == "4":
self.cart.show_cart()
elif choice == "5":
total = self.cart.calculate_total()
if total == 0:
print("カートが空です。支払いできません。")
continue
print(f"お支払い金額は {total} 円です。")
pay_method = input("支払い方法を選んでください (cash/card): ")
payment = Payment(total)
if pay_method == "cash":
try:
cash_amount = float(input("現金の金額を入力してください: "))
except ValueError:
print("入力が不正です。")
continue
if payment.pay_by_cash(cash_amount):
self.cart = Cart() # 支払い成功後、カートをリセット
elif pay_method == "card":
card_number = input("カード番号を入力してください(16桁): ")
if payment.pay_by_card(card_number):
self.cart = Cart()
else:
print("支払い方法が不正です。")
elif choice == "6":
print("システムを終了します。")
sys.exit()
else:
print("無効な選択です。")
if __name__ == "__main__":
system = BillingSystem()
# 商品を登録
system.add_item_to_catalog(101, "りんご", 120)
system.add_item_to_catalog(102, "みかん", 80)
system.add_item_to_catalog(103, "バナナ", 100)
system.add_item_to_catalog(104, "牛乳", 150)
system.add_item_to_catalog(105, "パン", 200)
system.add_item_to_catalog(106, "卵", 300)
system.add_item_to_catalog(107, "お米", 2500)
system.add_item_to_catalog(108, "肉", 1200)
system.add_item_to_catalog(109, "魚", 1000)
system.add_item_to_catalog(110, "野菜", 500)
# 実行
system.run()
さあ、どうなるのか見ものですね。
"Your code in 100% written by AI" 生成AIが100%で書かれたコードと検知しました。
その通りです。お見事。

なぜ検知することが可能なの?
どうして検知することが可能なのか、公式サイトに使用している技術が掲載されているのでまとめておきます。
どのように機能しますか?
AIコード検出機能は、数百万ものAI生成および人間が記述したコードサンプルでトレーニングされた機械学習分類器span-detect-1を搭載しています。意味的に生成されたコードの「チャンク」を解析し、スタイル、構文、構造のパターンに基づいて、AI生成か人間が記述したものかを分類します。
要するに、検知に使用されている技術は以下の通り。
- 機械学習分類器「span-detect-1」
- コードのチャンク解析
- 特徴分析
- 分類機能
大量のコードサンプルを学習した機械学習モデルが、書き方の癖や構造的特徴を見抜くことで検知が可能になっています。
触ってみた感想
触ってみた感想として95%の精度があると公式情報に記述がありますが、実際のところどうなのでしょうか。こればかりは検証してみないことにはわかりません。
AI対AIチェッカーの戦いになるのかなー。今後も注目して見ていきたいと思います。

