Saját szoftverügynök építése Pythonban

Az egyszerű chatbotok kora lejárt. A jövő az autonóm ügynökök világa, ahol a szoftver nemcsak válaszol, hanem cselekszik is. Ezek a rendszerek képesek adatbázisokban keresni, számolni vagy akár API-kat hívni. Sokan azt hiszik, ez bonyolult mágia. Valójában logikus tervezés kérdése. Ebben a cikkben egy ügyfélszolgálati asszisztens példáján keresztül, lépésről lépésre, valós Python kódokkal mutatjuk be a működést.

1. A működési ciklus (The Core Loop)

Minden ügynök lelke egy végtelen ciklus. A rendszer megfigyeli a környezetet, döntést hoz, végrehajtja azt, majd értékeli az eredményt. Ezt addig ismétli, amíg a feladat kész nincs.

Gyakorlati megvalósítás Pythonban:

def agent_loop(user_input, max_steps=5):
    step = 0
    while step < max_steps:
        # 1. Megfigyelés és döntés (LLM hívás)
        action = get_next_action(history)
        
        # Ha a modell szerint végeztünk:
        if action == "STOP":
            return "Feladat kész."
            
        # 2. Cselekvés végrehajtása
        result = execute_tool(action)
        
        # 3. Eredmény visszacsatolása a memóriába
        history.append(f"Eszköz eredménye: {result}")
        step += 1
        
    return "Túl sok lépés, leálltam."

2. Célok és határok definiálása

A homályos utasítás a kudarc receptje. A gépnek pontosan tudnia kell, mi a sikeres állapot. A példánkban az ügynök célja: rendelési státuszok lekérdezése.

A rendszerprompt (System Prompt) kódja:

system_instruction = """
Te egy ügyfélszolgálati asszisztens vagy.
Fő célod: Segíteni a felhasználóknak a rendeléseik nyomon követésében.
Szabályok:
1. Csak a megadott eszközöket használd.
2. Ha nem találod a rendelést, kérj pontosítást.
3. SOHA ne találj ki rendelési számokat.
4. Ha végeztél, válaszolj a felhasználónak és állj le.
"""

3. Eszközök készítése (Tools)

Az ügynök ettől lesz több, mint egy szöveggenerátor. Függvényeket adunk a kezébe, amelyeket meghívhat. Készítsünk egy egyszerű „adatbázis-kereső” függvényt.

Python eszköz definíció:

# Ez a "szimulált" adatbázisunk
orders_db = {
    "ORD-123": "Szállítás alatt",
    "ORD-456": "Kézbesítve",
    "ORD-789": "Feldolgozás alatt"
}

def check_order_status(order_id):
    """Lekérdezi egy rendelés státuszát az ID alapján."""
    status = orders_db.get(order_id)
    if status:
        return f"A(z) {order_id} rendelés státusza: {status}."
    else:
        return "Hiba: A rendelés nem található."

Ezt a függvényt a nyelvi modellnek JSON formátumban kell leírnunk, hogy tudja, hogyan használja.

4. Hatékony promptok tervezése

A modellnek tudnia kell, milyen eszközök érhetők el. A promptba dinamikusan beillesztjük az eszközök leírását és a gondolkodásmódot (pl. ReAct minta).

Prompt sablon:

def create_prompt(user_query, tools_description):
    prompt = f"""
    {system_instruction}
    
    Elérhető eszközök:
    {tools_description}
    
    Használd a következő formátumot:
    Gondolat: Mit kell tennem?
    Eszköz: Az eszköz neve (pl. check_order_status)
    Paraméter: Az eszköz bemenete (pl. ORD-123)
    
    Felhasználó kérdése: {user_query}
    """
    return prompt

5. Memória és állapotkezelés

Az ügynöknek emlékeznie kell az előző lépésekre. Ha lekérdezte a státuszt, a következő lépésben már tudnia kell az eredményt, hogy megválaszolhassa a kérdést.

Állapotkezelés listával:

history = []

# Felhasználó indít
history.append({"role": "user", "content": "Hol jár az ORD-123 rendelésem?"})

# ... a ciklus belsejében ...
# A modell válaszának mentése
history.append({"role": "assistant", "content": "Gondolat: Meg kell néznem az adatbázist..."})

# Az eszköz eredményének mentése (fontos lépés!)
tool_output = check_order_status("ORD-123")
history.append({"role": "system", "content": f"Eszköz válasza: {tool_output}"})

6. Biztonsági korlátok (Guardrails)

Nem engedhetjük szabadjára a rendszert. Mi van, ha végtelen ciklusba kerül, vagy törölni akar adatokat? Kellenek a védvonalak.

Kódba épített védelem:

def execute_tool_safe(tool_name, param):
    # Engedélyezett eszközök listája
    allowed_tools = ["check_order_status"]
    
    if tool_name not in allowed_tools:
        return "HIBA: Ez az eszköz nem engedélyezett vagy nem létezik."
    
    # Érzékeny művelet ellenőrzése (Human-in-the-loop)
    if tool_name == "refund_order" and float(param) > 10000:
        return "HIBA: 10.000 Ft feletti visszatérítéshez emberi jóváhagyás kell."
        
    # Futtatás
    if tool_name == "check_order_status":
        return check_order_status(param)

7. Tesztelés és fejlesztés

Az autonóm ügynökök viselkedése nem determinisztikus. Tesztelni kell őket váratlan helyzetekben is. Írjunk egy tesztesetet, ahol a felhasználó rossz adatot ad meg.

Teszteset Pythonban:

def test_agent_missing_order():
    print("--- Teszt: Hiányzó rendelés ---")
    response = agent_loop("Mi van az ORD-999 rendeléssel?")
    
    # Ellenőrizzük, hogy a válasz tartalmazza-e a hibát
    if "nem található" in response or "ellenőrizze" in response:
        print("SIKER: Az ügynök megfelelően kezelte a hibás ID-t.")
    else:
        print("HIBA: Az ügynök hallucinált vagy rossz választ adott.")

test_agent_missing_order()

A váz adott, a többi rajtad áll

A fenti hét lépés és a kódok alkotják az alapot. Ezt a vázat tetszőlegesen bővítheted új eszközökkel (pl. e-mail küldés, keresés a neten). A titok nem a modell méretében, hanem a gondos tervezésben és a robusztus kódban rejlik. Ha tetszett a cikk, iratkozz fel hírlevelünkre, hogy még több hasonló tartalmat olvashass!

Kérjük, ellenőrizd a mező formátumát, és próbáld újra.
Köszönjük, hogy feliratkoztál.

vagyunk.hu hírlevél

Hozzászólás

Az e-mail címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük