Tekoälyagentit · Oppitunti

Agentin vaiheiden jälkilokitus

Kunkin päättelyvaiheen, työkalukutsun ja tuloksen kirjaaminen jälkianalyysiä varten

Oppitunti 2/413 vaihetta

Agentin vaiheiden jälkilokitus on ilmainen Tekoälyagentit-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Tekoälyagentit-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Tekoälyagentit-kurssilla on yhteensä 4 oppituntia.

Miksi jäljityslokitus on agenteille välttämätöntä

Vakiomuotoiset sovelluslokit tallentavat virheet ja tapahtumat. Agenttien jäljityslokit tallentavat päättelyn: mitä agentti ajatteli kussakin vaiheessa, minkä työkalun se valitsi, mitä argumentteja se käytti ja mitä työkalu palautti?

Ilman jäljityslokitusta agentin virheen korjaaminen on kuin yrittäisi diagnosoida auton vikaa ilman kojelautaa — voitte vain arvailla.

Pythonin logging-moduulin määrittäminen

Pythonin sisäänrakennettu logging-moduuli on vakiotyökalu. Määrittäkää se agentin alussa käyttämällä muotoa, joka sisältää aikaleiman, tason ja viestin. Käyttäkää jäljitystietoja varten DEBUG-tasoa — sen voi poistaa käytöstä tuotannossa.

import logging
import sys

logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s [%(levelname)s] %(name)s: %(message)s',
    datefmt='%H:%M:%S',
    stream=sys.stdout
)

logger = logging.getLogger('myagent')

# Usage:
logger.debug('Step 1: reasoning started')
logger.info('Agent task completed in 5 steps')
logger.warning('Tool returned empty result')
logger.error('Failed to parse tool arguments')

# Output:
# 14:32:01 [DEBUG] myagent: Step 1: reasoning started
# 14:32:03 [INFO] myagent: Agent task completed in 5 steps

Kunkin päättelyvaiheen kirjaaminen lokiin

Kirjatkaa kunkin vaiheen alussa lokiin keskeiset tiedot: mikä vaihe on kyseessä, mitä päättelyä LLM tuotti, minkä työkalun se valitsi ja mitä argumentteja se välitti. Näin syntyy täydellinen tallenne agentin päätöksentekoprosessista.

import logging
import json

logger = logging.getLogger('myagent')

def log_step(step: int, thought: str, tool_name: str, tool_args: dict):
    logger.debug(
        f'Step {step}: '
        f'reasoning="{thought[:100]}" '
        f'tool={tool_name} '
        f'args={json.dumps(tool_args, ensure_ascii=False)[:200]}'
    )

# Example usage in the agent loop:
# log_step(
#     step=1,
#     thought='I need to find the current weather in Tokyo',
#     tool_name='get_weather',
#     tool_args={'city': 'Tokyo', 'unit': 'celsius'}
# )

if __name__ == '__main__':
    import sys
    logging.basicConfig(level=logging.DEBUG, format='%(message)s', stream=sys.stdout)
    log_step(
        step=1,
        thought='I need to find the current weather in Tokyo',
        tool_name='get_weather',
        tool_args={'city': 'Tokyo', 'unit': 'celsius'}
    )

Työkalujen tulosten kirjaaminen lokiin

Kirjatkaa jokaisen työkalukutsun jälkeen lokiin, onnistuiko kutsu, sekä tuloksen esikatselu. Koko tuloksen kirjaaminen voi tuottaa liikaa tekstiä — lyhentäkää se luettavuuden vuoksi 200 ensimmäiseen merkkiin.

import logging

logger = logging.getLogger('myagent')

def log_tool_result(step: int, tool_name: str, result: str, success: bool):
    status = 'OK' if success else 'ERROR'
    preview = str(result)[:200].replace('\n', ' ')
    logger.debug(
        f'Step {step} result [{status}]: tool={tool_name} '
        f'result_preview="{preview}"'
    )

    if not success:
        logger.warning(f'Tool {tool_name} failed at step {step}')

# Log at the start of the step:
# log_step(step, thought, tool_name, tool_args)
# result = execute_tool(tool_name, tool_args)
# log_tool_result(step, tool_name, result, success=True)

if __name__ == '__main__':
    import sys
    logging.basicConfig(level=logging.DEBUG, format='%(message)s', stream=sys.stdout)
    log_tool_result(1, 'get_weather', '{"temp_c": 18, "condition": "cloudy"}', success=True)
    log_tool_result(2, 'get_weather', 'Connection timed out', success=False)

Rakenteinen lokitus JSON-muodossa

Pelkkä tekstimuotoinen loki on helppo lukea mutta vaikea hakea. Rakenteiset JSON-lokit voidaan viedä lokien koontijärjestelmiin (Datadog, Splunk, CloudWatch) suodatusta, koontinäyttöjä ja hälytyksiä varten.

import logging
import json
import sys

class JSONFormatter(logging.Formatter):
    def format(self, record: logging.LogRecord) -> str:
        log_obj = {
            'timestamp': self.formatTime(record),
            'level': record.levelname,
            'logger': record.name,
            'message': record.getMessage()
        }
        # Add any extra fields attached to the log record
        if hasattr(record, 'step'):
            log_obj['step'] = record.step
        if hasattr(record, 'tool'):
            log_obj['tool'] = record.tool
        return json.dumps(log_obj)

handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(JSONFormatter())
logger = logging.getLogger('agent_trace')
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)

logger.setLevel(logging.DEBUG)
logger.debug('Step 3: tool=search_web', extra={'step': 3, 'tool': 'search_web'})

Lokitus lisäkenttien avulla

Välittäkää extra={} lokikutsuun liittääksenne siihen rakenteisia kenttiä, joita JSON-muotoilijat tai lokien koontijärjestelmät voivat käyttää suodatukseen ja analysointiin.

import logging

logger = logging.getLogger('agent_trace')

def log_step_structured(step: int, tool: str, thought: str, args: dict):
    logger.debug(
        f'Step {step}: tool={tool}',
        extra={
            'step': step,
            'tool': tool,
            'thought': thought[:200],
            'tool_args': args
        }
    )

# If using a JSON formatter, this produces:
# {
#   'timestamp': '14:32:01',
#   'level': 'DEBUG',
#   'message': 'Step 3: tool=search_web',
#   'step': 3,
#   'tool': 'search_web',
#   'thought': 'I need to find recent news about...',
#   'args': {'query': 'AI news 2025'}
# }

if __name__ == '__main__':
    import sys
    handler = logging.StreamHandler(sys.stdout)
    handler.setFormatter(logging.Formatter('%(message)s | step=%(step)s tool=%(tool)s'))
    logger.addHandler(handler)
    logger.setLevel(logging.DEBUG)
    log_step_structured(3, 'search_web', 'I need to find recent news about...', {'query': 'AI news 2025'})

Lokiin kirjoittaminen tiedostoon

Kirjoittakaa tuotantokäyttöön tarkoitettujen agenttien lokitiedot tiedostoon myöhempää analyysia varten. Käyttäkää RotatingFileHandler-käsittelijää lokitiedoston koon rajoittamiseen ja levytilan loppumisen estämiseen.

import logging
from logging.handlers import RotatingFileHandler
import sys

logger = logging.getLogger('myagent')
logger.setLevel(logging.DEBUG)

# Console handler — INFO and above
console = logging.StreamHandler(sys.stdout)
console.setLevel(logging.INFO)
console.setFormatter(logging.Formatter('%(message)s'))

# File handler — DEBUG and above, rotates at 10MB
file_handler = RotatingFileHandler(
    'agent_trace.log',
    maxBytes=10 * 1024 * 1024,  # 10 MB
    backupCount=3
)
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(logging.Formatter(
    '%(asctime)s [%(levelname)s] %(message)s'
))

logger.addHandler(console)
logger.addHandler(file_handler)

logger.info('Agent task completed in 5 steps')
logger.debug('Step 1: reasoning started')

Istuntotunnusten kirjaaminen monen käyttäjän agenteille

Kun useat käyttäjät tai tehtävät suoritetaan samanaikaisesti, lokit voivat sekoittua toisiinsa. Liittäkää jokaiseen lokiviestiin istunto- tai tehtävätunnus, jotta voitte suodattaa tietyn suorituksen lokit.

import logging
import uuid

class SessionLogger:
    def __init__(self, name: str):
        self.logger = logging.getLogger(name)
        self.session_id = str(uuid.uuid4())[:8]

    def debug(self, msg: str, **kwargs):
        self.logger.debug(f'[session={self.session_id}] {msg}', **kwargs)

    def info(self, msg: str, **kwargs):
        self.logger.info(f'[session={self.session_id}] {msg}', **kwargs)

    def error(self, msg: str, **kwargs):
        self.logger.error(f'[session={self.session_id}] {msg}', **kwargs)

# Each agent run gets its own logger with a unique session ID
# log = SessionLogger('myagent')
# log.info(f'Starting task: {query}')  # [session=a3f1b290] Starting task: ...

if __name__ == '__main__':
    import sys
    logging.basicConfig(level=logging.INFO, format='%(message)s', stream=sys.stdout)
    log = SessionLogger('myagent')
    log.info(f'Starting task: summarize the quarterly report')

Kunkin vaiheen keston mittaaminen

Lisätkää kuhunkin vaihelokimerkintään ajoitustiedot pullonkaulojen tunnistamiseksi. Mikä työkalu on hitain? Kuinka kauan LLM:n päättely kestää? Nämä tiedot ohjaavat optimointia.

import time
import logging

logger = logging.getLogger('myagent')

def timed_tool_call(tool_name: str, tool_fn, args: dict) -> str:
    start = time.perf_counter()
    try:
        result = tool_fn(**args)
        elapsed = time.perf_counter() - start
        logger.debug(f'Tool {tool_name} completed in {elapsed:.2f}s')
        return result
    except Exception as e:
        elapsed = time.perf_counter() - start
        logger.error(f'Tool {tool_name} failed in {elapsed:.2f}s: {e}')
        raise

# In the agent loop:
# result = timed_tool_call('search_web', search_web, {'query': 'Python'})
# Logs: Tool search_web completed in 1.34s

if __name__ == '__main__':
    import sys
    logging.basicConfig(level=logging.DEBUG, format='%(message)s', stream=sys.stdout)
    def search_web(query):
        return f'3 results for {query}'
    result = timed_tool_call('search_web', search_web, {'query': 'Python'})
    print('Tool result:', result)

Täydellinen vaiheen jäljitysmalli

Tässä on täydellinen, tuotantokäyttöön valmis jäljityslokitusmalli agentin vaihetta varten. Jokaisessa vaiheessa kirjataan vaiheen numero, päättely, työkalun valinta, argumentit, tuloksen esikatselu ja ajoitus — näin agentin suoritus on kokonaan näkyvissä.

import time
import logging
import json

logger = logging.getLogger('myagent')

def trace_step(step_num: int, thought: str, tool: str, args: dict, execute_fn):
    # Log decision
    logger.debug(
        f'Step {step_num}: thought="{thought[:80]}" tool={tool} '
        f'args={json.dumps(args)[:100]}'
    )

    # Execute with timing
    t0 = time.perf_counter()
    try:
        result = execute_fn(tool, args)
        elapsed = time.perf_counter() - t0
        preview = str(result)[:100].replace('\n', ' ')
        logger.debug(f'Step {step_num} done in {elapsed:.2f}s: "{preview}"')
        return result
    except Exception as e:
        elapsed = time.perf_counter() - t0
        logger.error(f'Step {step_num} failed in {elapsed:.2f}s: {e}')
        return f'ERROR: {e}'

if __name__ == '__main__':
    import sys
    logging.basicConfig(level=logging.DEBUG, format='%(message)s', stream=sys.stdout)
    def execute_fn(tool, args):
        return f'42 (from {tool})'
    trace_step(1, 'I should compute the answer', 'calculator', {'expr': '6*7'}, execute_fn)

Lokituksen poistaminen käytöstä tuotannossa

Virheenkorjauksen jäljityslokit sisältävät arkaluonteisia tietoja (kyselyitä ja API-vastauksia), ja niitä voi olla erittäin paljon. Asettakaa tuotannossa lokitasoksi INFO tai WARNING, jotta jäljitystason lokit eivät tule mukaan. Käyttäkää ympäristömuuttujaa tason hallintaan.

import os
import logging
import sys

# Read log level from environment variable
log_level_str = os.environ.get('LOG_LEVEL', 'INFO').upper()
log_level = getattr(logging, log_level_str, logging.INFO)

logging.basicConfig(level=log_level, stream=sys.stdout)
logger = logging.getLogger('myagent')

# Development: LOG_LEVEL=DEBUG python agent.py     -> full traces
# Production:  LOG_LEVEL=WARNING python agent.py  -> only warnings/errors
# Default:     LOG_LEVEL not set                  -> INFO level

logger.debug('This only appears in DEBUG mode')
logger.info('This appears in INFO and DEBUG modes')
logger.warning('This always appears')

Tietotesti: Jäljityslokitus

Testatkaa ymmärrystänne agentin vaiheiden jäljityslokituksesta.

Kertaus: Agentin vaiheiden jäljityslokitus

Teillä on nyt kattava agenttien jäljityslokitusstrategia:

  • Ottakaa jäljitystason lokit käyttöön komennolla logging.basicConfig(level=DEBUG)
  • Kirjatkaa jokaisessa vaiheessa lokiin vaiheen numero, päättely, työkalun nimi ja argumentit
  • Kirjatkaa työkalujen tulokset esikatselun sekä onnistumis- tai epäonnistumistiedon kanssa
  • Käyttäkää JSON-muotoilua rakenteisille ja haettaville lokeille
  • Liittäkää istuntotunnukset usean käyttäjän tai samanaikaisesti toimiviin agentteihin
  • Lisätkää ajoitustiedot hitaiden vaiheiden tunnistamiseksi
  • Hallitkaa lokien yksityiskohtaisuutta LOG_LEVEL-ympäristömuuttujalla
Aloita maksutta

Opi Tekoälyagentit tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
60
Oppitunnit
239

Usein kysytyt kysymykset

Onko oppitunti ”Agentin vaiheiden jälkilokitus” ilmainen?

Kyllä – oppitunnin ”Agentin vaiheiden jälkilokitus” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Tekoälyagentit-kurssin, päivitä CoddyKit PROhon. Tekoälyagentit-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Agentin vaiheiden jälkilokitus”?

Kunkin päättelyvaiheen, työkalukutsun ja tuloksen kirjaaminen jälkianalyysiä varten Harjoittelet Tekoälyagentit-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Tekoälyagentit-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Tekoälyagentit-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.

Kuinka kauan ”Agentin vaiheiden jälkilokitus”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Tekoälyagentit-oppitunnilla?

Kyllä. Jokainen Tekoälyagentit-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Agenttisilmukoiden yleiset virheet
  2. Agentin vaiheiden jälkilokitus
  3. Loputtomien silmukoiden tunnistaminen ja katkaiseminen
  4. Vaiheittaisen vianetsinnän tekniikat
← Takaisin: Tekoälyagentit