AI Agents · 课时

逐步调试技术

在代理代码中添加断点和中间输出,并使用调试器。

第 4 / 4 课13 个步骤

逐步调试技术 是 CoddyKit 上的免费 AI Agents 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 AI Agents 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 AI Agents 课程共包含 4 节课。

调试代理不同于调试函数

函数具有明确的输入和输出。代理则包含由 LLM 调用、工具执行和历史记录修改组成的循环——其中任何环节都可能以细微的方式出错。

逐步调试可以让您在每个步骤暂停、检查代理状态,并准确了解发生了什么问题。

Python 内置调试器:pdb

Python 调试器 pdb 可让您暂停执行、检查变量并逐行执行代码。在代理循环中的任意位置插入 import pdb; pdb.set_trace(),即可进入交互式调试会话。

import pdb

def run_agent_loop(query: str):
    history = []
    for step in range(1, 21):
        action = decide_action(query, history)

        # Drop into debugger at step 3 to inspect state
        if step == 3:
            import pdb; pdb.set_trace()
            # At this point you can:
            # (Pdb) print(action)       -- inspect current action
            # (Pdb) print(history)      -- inspect full history
            # (Pdb) n                   -- next line
            # (Pdb) c                   -- continue execution
            # (Pdb) q                   -- quit

        result = execute_tool(action['tool'], action['args'])
        history.append({'tool': action['tool'], 'result': result})

Python 3.7+:breakpoint() 函数

Python 3.7+ 包含内置的 breakpoint() 函数——比 import pdb; pdb.set_trace() 更简洁。它还遵循 PYTHONBREAKPOINT 环境变量,您可以借此替换为其他调试器。

def run_agent_loop(query: str):
    history = []
    for step in range(1, 21):
        action = decide_action(query, history)

        breakpoint()  # cleaner than pdb.set_trace()

        result = execute_tool(action['tool'], action['args'])
        history.append({'tool': action['tool'], 'result': result})

# Disable all breakpoints without changing code:
# PYTHONBREAKPOINT=0 python agent.py

# Use ipdb (better UI) instead:
# PYTHONBREAKPOINT=ipdb.set_trace python agent.py
# pip install ipdb

pdb 命令参考

用于调试代理循环的最重要 pdb 命令:

  • n — 下一行(跳过执行)
  • s — 进入函数调用
  • c — 继续执行,直到下一个断点
  • p expr — 输出表达式的值
  • pp expr — 美化输出(适用于字典和列表)
  • l — 列出当前行附近的源代码
  • q — 退出调试器
# Typical pdb debugging session for an agent loop:
# (Pdb) p step           -- print current step number: 3
# (Pdb) pp action        -- pretty-print the action dict
# {'type': 'tool', 'tool': 'search_web', 'args': {'query': 'Python docs'}}
# (Pdb) pp history       -- see full conversation so far
# (Pdb) p len(history)   -- count messages: 6
# (Pdb) n                -- execute next line
# (Pdb) p result         -- see tool result
# (Pdb) c                -- continue to next breakpoint
print('pdb lets you inspect agent state at any point in the loop')

条件断点

仅在特定条件为真时暂停,例如仅在选中特定工具或步骤计数较高时暂停。这样可以避免在较长循环的每次迭代中都暂停。

def run_agent_loop(query: str):
    history = []
    for step in range(1, 21):
        action = decide_action(query, history)

        # Break only if the agent picks the wrong tool
        if action.get('tool') == 'calculate' and 'weather' in query.lower():
            breakpoint()  # This is suspicious — weather shouldn't use calculator

        # Break only if we're near the step limit
        if step >= 18:
            breakpoint()  # Why hasn't the agent concluded yet?

        result = execute_tool(action['tool'], action['args'])
        history.append({'tool': action['tool'], 'result': result})

用于代理代码的 VS Code 调试器

VS Code Python 调试器提供可视化的逐步执行体验,包括变量检查面板、调用栈和监视表达式。配置一个 launch.json,即可在调试模式下运行代理。

# .vscode/launch.json
# {
#   'version': '0.2.0',
#   'configurations': [
#     {
#       'name': 'Debug Agent',
#       'type': 'python',
#       'request': 'launch',
#       'program': 'agent_cli.py',
#       'args': ['--query', 'What is the weather in Paris?'],
#       'env': {
#         'OPENAI_API_KEY': 'your-key',
#         'LOG_LEVEL': 'DEBUG'
#       },
#       'console': 'integratedTerminal'
#     }
#   ]
# }

# Set breakpoints by clicking the left margin in VS Code
# Press F5 to start debugging, F10 to step over, F11 to step into
print('VS Code debugger provides visual debugging with no code changes needed')

向 CLI 添加 --debug 标志

向代理 CLI 添加 --debug 标志。启用后,它会记录详细日志、输出每个步骤,并可选择在发生错误时进入 pdb。这样您无需修改源代码即可进行调试。

import argparse
import logging

parser = argparse.ArgumentParser()
parser.add_argument('--query', required=True)
parser.add_argument('--debug', action='store_true', help='Enable step-by-step debugging output')
parser.add_argument('--pdb-on-error', action='store_true', help='Drop into pdb on any exception')
args = parser.parse_args()

if args.debug:
    logging.basicConfig(level=logging.DEBUG)
    print('[DEBUG MODE] Step-by-step output enabled')

try:
    result = run_agent(args.query, verbose=args.debug)
    print(result['answer'])
except Exception as e:
    if args.pdb_on_error:
        import pdb; pdb.post_mortem()  # debug the crash
    else:
        raise

使用详细模式逐步执行

详细模式会将每个步骤的详细信息输出到标准输出,让您无需调试器即可跟踪代理的执行过程。向代理循环添加 verbose=True 标志。

import json

def run_agent(query: str, verbose: bool = False) -> dict:
    history = []

    for step in range(1, 21):
        action = decide_action(query, history)

        if verbose:
            print(f'\n--- Step {step} ---')
            print(f'Action type: {action["type"]}')
            if action['type'] == 'tool':
                print(f'Tool: {action["tool"]}')
                print(f'Args: {json.dumps(action["args"], indent=2)}')

        if action['type'] == 'final_answer':
            if verbose:
                print(f'\nFinal answer: {action["answer"]}')
            return {'status': 'ok', 'answer': action['answer']}

        result = execute_tool(action['tool'], action['args'])
        if verbose:
            print(f'Result: {str(result)[:200]}')
        history.append({'tool': action['tool'], 'result': result})

    return {'status': 'max_steps', 'answer': None}

使用 pdb.post_mortem() 进行事后调试

当代理因异常而崩溃时,pdb.post_mortem() 会在确切的失败位置打开调试器,同时保留调用栈。无需重新复现问题,这对于理解崩溃原因非常有帮助。

import pdb
import sys
import traceback

def run_agent_with_postmortem(query: str, debug: bool = False) -> dict:
    try:
        return run_agent(query)
    except Exception as e:
        if debug:
            print(f'\nAgent crashed: {e}')
            traceback.print_exc()
            print('\nDropping into post-mortem debugger...')
            pdb.post_mortem()  # opens debugger at the crash site
            return {'status': 'crashed', 'error': str(e)}
        else:
            raise

# Usage:
# python agent.py --query 'test' --pdb-on-error

在调试器中检查消息历史

调试代理时,最值得检查的内容是对话历史。使用 pdb 的 pp 命令美化输出历史记录,或者遍历历史记录,以了解代理目前为止看到的内容。

# Inside a pdb session, common inspection commands:

# Print the full history:
# (Pdb) pp history

# Print only user and assistant messages:
# (Pdb) pp [m for m in history if m['role'] in ('user', 'assistant')]

# Count messages:
# (Pdb) p len(history)

# Find tool calls in history:
# (Pdb) pp [m for m in history if m.get('role') == 'tool']

# Print the last message:
# (Pdb) pp history[-1]

# Print total token estimate (rough):
# (Pdb) p sum(len(str(m)) for m in history)
print('History inspection is the key to understanding agent state')

不调用 LLM 的逐步执行模拟

为了快速迭代,您可以构建一种模拟模式,在每个步骤中手动指定代理采取的操作。这样,您无需调用任何 LLM API 即可测试工具执行和历史记录管理。

def run_agent_simulation(query: str, scripted_actions: list) -> dict:
    'Simulate agent steps without LLM calls, using pre-defined actions'
    history = []

    for step, action in enumerate(scripted_actions, 1):
        print(f'Step {step}: {action}')

        if action['type'] == 'final_answer':
            return {'status': 'ok', 'answer': action['answer'], 'steps': step}

        result = execute_tool(action['tool'], action['args'])
        print(f'  Result: {str(result)[:100]}')
        history.append({'tool': action['tool'], 'result': result})

    return {'status': 'script_exhausted', 'history': history}

# Test tool execution logic without any LLM:
# result = run_agent_simulation('test', [
#     {'type': 'tool', 'tool': 'search_web', 'args': {'query': 'Python'}},
#     {'type': 'final_answer', 'answer': 'Python is a programming language.'}
# ])

知识检查:逐步调试

测试您对代理代码调试技术的理解。

回顾:逐步调试技术

现在,您已经拥有一套完整的代理循环调试工具:

  • 使用 breakpoint()(Python 3.7+)或 import pdb; pdb.set_trace() 进行交互式调试
  • 使用条件断点,仅在出现可疑情况时暂停
  • 配置 VS Code 的 launch.json,通过图形界面进行调试
  • 添加 --debug 和 --pdb-on-error CLI 标志,以便按需调试
  • 使用 pdb.post_mortem() 检查已经发生的崩溃
  • 构建模拟模式,在不调用 LLM 的情况下测试工具逻辑
  • 使用详细模式跟踪执行过程,而无需暂停
免费开始

用 AI 导师学习 AI Agents — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
60
课程
239

常见问题解答

「逐步调试技术」课时是免费的吗?

是的 — 「逐步调试技术」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 AI Agents 课程的其余内容,请升级到 CoddyKit PRO。 AI Agents 课程共包含 4 节课。

「逐步调试技术」这节课中我会学到什么?

在代理代码中添加断点和中间输出,并使用调试器。 你通过在浏览器中直接运行的动手代码来练习 AI Agents,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 AI Agents 需要有经验吗?

无需任何先前经验。CoddyKit 上的 AI Agents 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「逐步调试技术」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 AI Agents 课中编写并运行代码吗?

能。每节 AI Agents 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 常见的代理循环故障
  2. 代理步骤的跟踪日志
  3. 检测并打破无限循环
  4. 逐步调试技术
← 返回 AI Agents