Ismerős az érzés? Péntek délután van, kapkodsz, beírod a promptot a ChatGPT-nek: „Írj egy Python szkriptet, ami ár-adatokat gyűjt ki, és elmenti őket egy CSV fájlba”. Tíz másodperc múlva ott a kód. Lefuttatod. Működik. Hazamész. Aztán hétfőn, amikor integrálni kellene a főrendszerbe, rájössz, hogy amit kaptál, az nem szoftver, hanem egy időzített bomba.
Az MI-alapú kódgenerálás, legyen az ChatGPT, Claude vagy GitHub Copilot, elképesztő sebességet ad. De van egy hatalmas ára, amit sokan nem vesznek észre. A technikai adósság. Az MI ugyanis „egyszer futtatható”, run-once szkriptekben gondolkodik. Nem érdekli a karbantarthatóság, a modularitás vagy a típusbiztonság. Neki a cél a gyors válasz, nem a clean code.
Ebben a cikkben megmutatom a különbséget a „működő” MI-kód és a „fenntartható” mérnöki munka között. Veszünk egy tipikus generált kódrészletet, és lépésről lépésre átalakítjuk vállalati szintű megoldássá.
A probléma
Kértem a modelltől egy egyszerű szkriptet: elemezzen egy értékesítési CSV-t, és szűrje ki a hibás tranzakciókat. Ezt adta és ez az, amit a fejlesztők 80%-a gondolkodás nélkül bemásol:
A „rossz” generált kód:
import pandas as pd
# Hardcoded útvonal - ha áthelyezed a fájlt, összeomlik
data = pd.read_csv('sales_data.csv')
# Nincs hibakezelés. Mi van, ha hiányzik az 'amount' oszlop?
# Nincs függvény, minden a globális térben fut
results = []
for index, row in data.iterrows():
if row['amount'] > 1000:
discount = row['amount'] * 0.9
results.append(discount)
else:
results.append(row['amount'])
data['final_price'] = results
data.to_csv('processed_sales.csv')
print("Kész!")
Mi a baj ezzel?
- Soronkénti iteráció használata: Pandasban ciklust írni bűn, lassú!
- Globális változók: Ha ezt be akarod hívni egy másik modulba, nem tudod.
- Szöveg érték: Mi az, hogy
1000? Mi az, hogy0.9? Később senki nem fogja tudni, mik ezek a számok. - Típusok hiánya: Milyen adatot vár? DataFrame-et? Listát?
1. lépés: Modularizálás és vektorizáció
Az első dolgunk, hogy a logikát kiszervezzük függvényekbe, és kihasználjuk a Pandas erejét a lassú Python ciklusok helyett.
import pandas as pd
def calculate_discounted_price(df):
# Vektorizált művelet: 100x gyorsabb, mint a for ciklus
# A logikát olvashatóan elkülönítjük
df.loc[df['amount'] > 1000, 'final_price'] = df['amount'] * 0.9
df.loc[df['amount'] <= 1000, 'final_price'] = df['amount']
return df
def main():
df = pd.read_csv('sales_data.csv')
processed_df = calculate_discounted_price(df)
processed_df.to_csv('processed_sales.csv')
if __name__ == "__main__":
main()
Már jobb. De még mindig nem „production-ready”.
2. lépés: Típusmegjelölés, a jövőbeli énednek
Az MI gyakran elhagyja a típusmegjelöléseket (type hints), pedig ezek nélkül egy nagy projektben a kollégáid és az IDE-d, vakon repülnek. Mondjuk meg a kódnak, mi micsoda!
import pandas as pd
from pathlib import Path
# Konstansok kiszervezése - így egy helyen módosítható az üzleti logika
DISCOUNT_THRESHOLD = 1000
DISCOUNT_RATE = 0.9
def apply_business_logic(df: pd.DataFrame) -> pd.DataFrame:
"""
Kiszámítja a végső árat a kedvezmény szabályok alapján.
Args:
df (pd.DataFrame): A nyers értékesítési adatokat tartalmazó DataFrame.
Returns:
pd.DataFrame: A módosított DataFrame a 'final_price' oszloppal.
"""
# Defensive programming: másolatot készítünk, hogy ne módosítsuk az eredetit véletlenül
processed_df = df.copy()
mask = processed_df['amount'] > DISCOUNT_THRESHOLD
processed_df['final_price'] = processed_df['amount']
processed_df.loc[mask, 'final_price'] = processed_df['amount'] * DISCOUNT_RATE
return processed_df
3. lépés: Validáció és pydantic, a profi szint
Mi történik, ha a CSV-ben szöveg van a számok helyett? Az MI kódja összeomlik. A miénk nem fog, mert bevezetjük a pydantic könyvtárat az adatvalidációra. Ez ma az ipari sztenderd Pythonban.
from pydantic import BaseModel, ValidationError, PositiveFloat
from typing import List
import pandas as pd
# Adatmodell definiálása: Ez a szerződés (contract) az adatokkal
class SaleTransaction(BaseModel):
transaction_id: int
amount: PositiveFloat # Automatikusan ellenőrzi, hogy pozitív szám-e
def validate_data(df: pd.DataFrame) -> List[SaleTransaction]:
"""Validálja a bejövő sorokat a Pydantic modellel."""
valid_transactions = []
errors = []
for record in df.to_dict(orient='records'):
try:
# Itt történik a validáció
transaction = SaleTransaction(**record)
valid_transactions.append(transaction)
except ValidationError as e:
errors.append(f"Hiba a {record.get('transaction_id')} tranzakciónál: {e}")
if errors:
print(f"Figyelem: {len(errors)} hibás sort találtunk!")
# Itt logolhatnánk a hibákat fájlba
return valid_transactions
# Így a kódunk nemcsak számol, de védi is a rendszert a szemét adatoktól.
4. lépés: Tesztelés, amit az MI mindig kihagy
Az MI megírja a kódot, de honnan tudod, hogy jól számol? Kérj tőle teszteket! A pytest a legjobb barátod. Íme egy trükk. Másold be a refaktorált függvényedet az MI-nek, és ezt a promptot add neki:
„Írj átfogó unit teszteket ehhez a függvényhez a pytest használatával. Vedd bele a határeseteket is (pl. pontosan 1000, 0, negatív számok).”
import pytest
import pandas as pd
# Feltételezve, hogy a fenti 'apply_business_logic' importálva van
def test_discount_application():
# Setup - Tesztadat létrehozása
input_data = pd.DataFrame({
'amount': [500, 1000, 2000]
})
# Action - Futtatás
result = apply_business_logic(input_data)
# Assert - Ellenőrzés
# 500 -> marad 500
assert result.iloc[0]['final_price'] == 500
# 1000 -> marad 1000 (határérték teszt)
assert result.iloc[1]['final_price'] == 1000
# 2000 -> 1800 (kedvezményes)
assert result.iloc[2]['final_price'] == 1800
Ne légy „copy-paste” fejlesztő!
Az MI egy kiváló junior asszisztens. Megírja az általad megadott prompt alapján, a sablont. De a te feladatod, hogy senior mérnökként viselkedj.
A mivagyunk.hu szabálya:
- Generáltass – Gyorsaság.
- Olvass és érts – Ellenőrzés.
- Refaktorálj – Minőség.
- Tesztelj – Biztonság.
A kód karbantartása a te felelősséged. Ha a generált kód miatt áll le a szerver hajnali 2-kor, a ChatGPT nem fogja felvenni a telefont. Te viszont igen.




