code: def train_agent(
      agent,
      env,
      steps,
      outdir,
      checkpoint_freq=None,
      max_episode_len=None,
      step_offset=0,
      evaluator=None,
      successful_score=None,
      step_hooks=(),
      eval_during_episode=False,
      logger=None,
  ):
      logger = logger or logging.getLogger(__name__)
  
      episode_r = 0
      episode_idx = 0
  
      # o_0, r_0
      obs = env.reset()
  
      t = step_offset
      if hasattr(agent, "t"):
          agent.t = step_offset
  
      eval_stats_history = []  # List of evaluation episode stats dict
      episode_len = 0
      try:
          while t < steps:
              # a_t
              action = agent.act(obs)
              # o_{t+1}, r_{t+1}
              obs, r, done, info = env.step(action)
              t += 1
              episode_r += r
              episode_len += 1
              reset = episode_len == max_episode_len or info.get(
                  "needs_reset", False
              )
              agent.observe(obs, r, done, reset)
  
              for hook in step_hooks:
                  hook(env, agent, t)
  
              episode_end = done or reset or t == steps
  
              if episode_end:
                  logger.info(
                      "outdir:%s step:%s episode:%s R:%s",
                      outdir,
                      t,
                      episode_idx,
                      episode_r,
                  )
                  stats = agent.get_statistics()
                  logger.info("statistics:%s", stats)
                  episode_idx += 1
  
              if evaluator is not None and (
                  episode_end or eval_during_episode
              ):
                  eval_score = evaluator.evaluate_if_necessary(
                      t=t, episodes=episode_idx
                  )
                  if eval_score is not None:
                      eval_stats = dict(agent.get_statistics())
                      eval_stats["eval_score"] = eval_score
                      eval_stats_history.append(eval_stats)
                  if (
                      successful_score is not None
                      and evaluator.max_score >= successful_score
                  ):
                      break
  
              if episode_end:
                  if t == steps:
                      break
                  # Start a new episode
                  episode_r = 0
                  episode_len = 0
                  obs = env.reset()
              if checkpoint_freq and t % checkpoint_freq == 0:
                  save_agent(
                      agent, t, outdir, logger, suffix="_checkpoint"
                  )
  
      except (Exception, KeyboardInterrupt):
          # Save the current model before being killed
          save_agent(agent, t, outdir, logger, suffix="_except")
          raise
  
      # Save the final model
      save_agent(agent, t, outdir, logger, suffix="_finish")
  
      return eval_stats_history
  
imports: import logging
  import os
  from pfrl.experiments.evaluator import Evaluator, save_agent
  from pfrl.utils.ask_yes_no import ask_yes_no
label_desc: Use image node_id 3 for calling a global function with example usage: train_agent(agent, env, steps, outdir, checkpoint_freq, max_episode_len, step_offset, evaluator, successful_score, step_hooks, eval_during_episode, logger) and returns: eval_stats_history