通过1Password CLI,将保存的密码和API密钥用于命令及配置模板,完成安装、认证、秘密值读取,并通过环境变量向命令传递凭据。
- 安装并配置1Password CLI
- 使用已保存的API密钥运行命令
- 向配置模板填入秘密值
通过暂停Python执行、查看变量和跟踪执行流程来排查故障。根据场景使用pdb或debugpy,也可检查失败的测试、异常现场及正在运行的进程。
Debug Python: pdb REPL + debugpy remote (DAP).
暂停Python执行,查看变量值和函数调用流程,帮助查找故障原因。本技能介绍在本地使用breakpoint()或python -m pdb,以及在远程环境或运行中的进程上使用debugpy的方法。还涵盖逐行执行、按条件暂停、查看异常发生位置的变量,以及调试子进程。
当测试报错无法解释某个值为何出错,或需要跟踪函数内列表、字典如何变化时,可以使用本技能。它也适用于排查长时间运行的进程,以及问题实际出在子进程而非父进程的情况。
debugpy连接到运行中的Python进程的步骤。”支持Linux和macOS。目标环境需要预先安装debugpy。在Hermes中,应准备与生产环境分开的开发和测试环境。捕获输出的测试运行环境无法进行交互式调试。提交代码前,需要移除用于暂停执行的代码。
本介绍由 AI(OpenAI Codex)根据公开的 SKILL.md 撰写。准确的规格请查看下方原文。
AI 仅根据 SKILL.md 的内容,从 4 个方面进行了评估。星标数和热度不计入评估。
总分按每项 A=25 分、B=15 分、C=5 分相加。 由 AI(OpenAI Codex)于 2026年10月19日 评估。仅供参考,安装前请同时查看原文。
安装前可以查看交给 AI 代理的指令内容。
Three tools, picked by situation:
| Tool | When |
|---|---|
breakpoint() + pdb | Local, interactive, simplest. Add breakpoint() in the source, run normally, get a REPL at that line. |
python -m pdb | Launch an existing script under pdb with no source edits. Useful for quick poking. |
debugpy | Remote / headless / "attach to already-running process." Talks DAP, scriptable from terminal, works for long-lived processes (gateway, daemon, PTY children). |
Start with breakpoint(). It's the cheapest thing that works.
_SlashWorker, PTY bridge worker) is the actual bug siteDon't use for: things print() / logging.debug solve in under a minute, or things pytest -vv --tb=long --showlocals already reveals.
Inside any pdb prompt ((Pdb)):
| Command | Action |
|---|---|
h / h cmd | help |
n | next line (step over) |
s | step into |
r | return from current function |
c | continue |
unt N | continue until line N |
j N | jump to line N (same function only) |
l / ll | list source around current line / full function |
w | where (stack trace) |
u / d | move up / down in the stack |
a | print args of the current function |
p expr / pp expr | print / pretty-print expression |
display expr | auto-print expr on every stop |
b file:line | set breakpoint |
b func | break on function entry |
b file:line, cond | conditional breakpoint |
cl N | clear breakpoint N |
tbreak file:line | one-shot breakpoint |
!stmt | execute arbitrary Python (assignments included) |
interact | drop into full Python REPL in current scope (Ctrl+D to exit) |
q | quit |
The interact command is the most powerful — you can import anything, inspect complex objects, even call methods that mutate state. Locals are read-only by default; use !x = 42 from the (Pdb) prompt to mutate.
Easiest. Edit the file:
def compute(x, y):
result = some_helper(x)
breakpoint() # <-- drops into pdb here
return result + y
Run the code normally. You land at the breakpoint() line with full access to locals.
Don't forget to remove breakpoint() before committing. Use git diff or a pre-commit grep:
rg -n 'breakpoint\(\)' --type py
python -m pdb path/to/script.py arg1 arg2
# Lands at first line of script
(Pdb) b path/to/script.py:42
(Pdb) c
Use terminal and the canonical runner for noninteractive diagnostics:
# Show locals in tracebacks without pdb:
scripts/run_tests.sh tests/path/to/test_file.py --showlocals --tb=long
scripts/run_tests.sh captures each file in a separate subprocess, so --pdb
or --trace cannot provide an interactive prompt there. For an interactive
debugger only, use the independent development/test interpreter prepared in
Recipe 5 (never a production generation):
.venv/bin/python -m pytest tests/foo_test.py::test_bar --pdb
This bypasses the hermetic-env guarantees — fine for debugging, but re-run under the wrapper to confirm before pushing.
import pdb, sys
try:
run_the_thing()
except Exception:
pdb.post_mortem(sys.exc_info()[2])
Or wrap a whole script:
python -m pdb -c continue script.py
# When it crashes, pdb catches it and you're in the frame of the exception
Or set a global hook in a repl/jupyter:
import sys
def excepthook(etype, value, tb):
import pdb; pdb.post_mortem(tb)
sys.excepthook = excepthook
For long-lived processes: Hermes gateway, tui_gateway, a daemon, a process that's already misbehaving and can't be restarted clean.
For Hermes, use a separate development checkout and data home, not a live
production generation. Follow the
PM developer workflow
and activate that checkout — PowerShell: . .\activate.ps1. The declared dev
extra includes debugpy, which PM activation does not sync (all excludes it).
Through terminal, build a fresh, caller-owned debug/test environment with the
prepared checkout's Python:
source ./activate
python -m pm.build_env --source . --out .venv --group dev --group test
.venv/bin/python -c "import debugpy; print(debugpy.__file__)"
The output must not already exist. Stop its processes and intentionally remove
only that disposable environment before rebuilding. Keep the same isolated
HERMES_HOME for the debug target. .venv/bin/python is this explicitly built
debug environment, not a guessed application venv, and the patterns below run
through it. Do not add debugpy to a running production environment; reproduce
there only with an already-prepared debug target or arrange a restart in the
development environment.
Add near the top of the entry point (or inside the function you want to debug):
import debugpy
debugpy.listen(("127.0.0.1", 5678))
print("debugpy listening on 5678, waiting for client...", flush=True)
debugpy.wait_for_client()
debugpy.breakpoint() # optional: pause immediately once attached
Start the process; it blocks on wait_for_client().
-m debugpy.venv/bin/python -m debugpy --listen 127.0.0.1:5678 --wait-for-client your_script.py arg1
Equivalent for module entry:
.venv/bin/python -m debugpy --listen 127.0.0.1:5678 --wait-for-client -m your.module
Needs the PID and debugpy preinstalled in the target's environment:
.venv/bin/python -m debugpy --listen 127.0.0.1:5678 --pid <pid>
# debugpy injects itself into the process. Then attach a client as below.
Some kernels/security configs block the ptrace-based injection (/proc/sys/kernel/yama/ptrace_scope). Fix with:
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
The easiest terminal-side DAP client is VS Code CLI or a small script. From inside Hermes you have two practical options:
Option 1: debugpy's own CLI REPL — not an official feature, but a tiny DAP client script:
# ~/.hermes/cache/scratch/dap_client.py
import socket, json, itertools, time, sys
HOST, PORT = "127.0.0.1", 5678
s = socket.create_connection((HOST, PORT))
seq = itertools.count(1)
def send(msg):
msg["seq"] = next(seq)
body = json.dumps(msg).encode()
s.sendall(f"Content-Length: {len(body)}\r\n\r\n".encode() + body)
def recv():
header = b""
while b"\r\n\r\n" not in header:
header += s.recv(1)
length = int(header.decode().split("Content-Length:")[1].split("\r\n")[0].strip())
body = b""
while len(body) < length:
body += s.recv(length - len(body))
return json.loads(body)
send({"type": "request", "command": "initialize", "arguments": {"adapterID": "python"}})
print(recv())
send({"type": "request", "command": "attach", "arguments": {}})
print(recv())
send({"type": "request", "command": "setBreakpoints",
"arguments": {"source": {"path": sys.argv[1]},
"breakpoints": [{"line": int(sys.argv[2])}]}})
print(recv())
send({"type": "request", "command": "configurationDone"})
# ... loop reading events and sending continue/stepIn/etc.
This is fine for one-off automation but painful as an interactive UX.
Option 2: Attach from VS Code / Cursor / Zed — if the user has one open, they can add a launch.json:
{
"name": "Attach to Hermes",
"type": "debugpy",
"request": "attach",
"connect": { "host": "127.0.0.1", "port": 5678 },
"justMyCode": false,
"pathMappings": [
{ "localRoot": "${workspaceFolder}", "remoteRoot": "<hermes-agent-repo>" }
]
}
Option 3: Ditch DAP, use remote-pdb — usually what you actually want from a terminal agent:
For an independently owned Python project, declare remote-pdb in that
project's development dependencies and prepare its debug environment through
the project's package manager. This is not a Hermes SDK install recipe. For
Hermes, prefer the declared debugpy dependency; the remote-pdb examples below
require a separately declared, freshly built debug environment, never an
in-place pip install into the selected application generation.
In your code:
from remote_pdb import set_trace
set_trace(host="127.0.0.1", port=4444) # blocks until connection
Then from the terminal:
nc 127.0.0.1 4444
# You get a (Pdb) prompt exactly as if debugging locally.
remote-pdb is the cleanest agent-friendly choice when debugpy's DAP protocol is overkill. Use debugpy only when you actually need IDE integration.
See Recipe 3. The wrapper captures subprocess output, so run pytest directly for interactive pdb.
run_agent.py / CLI — one-shotIn the prepared debug checkout, add breakpoint() near the suspect line, then
run python hermes. Control returns to your terminal at the pause point.
tui_gateway subprocess (spawned by hermes --tui)The gateway runs as a child of the Node TUI. Options:
A. Source-edit the gateway:
# tui_gateway/server.py near the top of serve()
import debugpy
debugpy.listen(("127.0.0.1", 5678))
debugpy.wait_for_client()
Start python hermes --tui from the prepared debug checkout. The TUI will appear frozen (its backend is waiting). Attach a client; execution resumes when you continue. Check the child's interpreter and imports before assuming it inherited the debug environment.
B. Use remote-pdb at a specific handler:
from remote_pdb import set_trace
set_trace(host="127.0.0.1", port=4444) # in the RPC handler you want to trap
Trigger the matching slash command from the TUI, then nc 127.0.0.1 4444 in another terminal.
_SlashWorker subprocessSame pattern — remote-pdb with set_trace() inside the worker's exec path. The worker is persistent across slash commands, so the first trigger blocks until you connect; subsequent slash commands pass through normally unless you re-arm.
gateway/run.py)Long-lived. Use remote-pdb at a handler, or debugpy with --wait-for-client if you're restarting the gateway anyway.
pdb under a parallel/output-capturing runner silently does nothing. You won't see the prompt, the test just hangs (true of pytest-xdist and of scripts/run_tests.sh's captured per-file subprocesses). Run pytest directly on a single file for interactive debugging.
breakpoint() in CI / non-TTY contexts hangs the process. Safe locally; never commit it. Add a pre-commit grep as a safety net.
PYTHONBREAKPOINT=0 disables all breakpoint() calls. Check the env if your breakpoint isn't hitting:
echo $PYTHONBREAKPOINT
debugpy.listen blocks only if you also call wait_for_client(). Without it, execution continues and your first breakpoint may fire before the client is attached.
Attach to PID fails on hardened kernels. ptrace_scope=1 (Ubuntu default) allows only same-user ptrace of child processes. Workaround: echo 0 > /proc/sys/kernel/yama/ptrace_scope (needs root) or launch under debugpy from the start.
Threads. pdb only debugs the current thread. For multithreaded code, use debugpy (thread-aware DAP) or set threading.settrace() per thread.
asyncio. pdb works in coroutines but await inside pdb requires Python 3.13+ or await from interact mode on older versions. For 3.11/3.12, use asyncio.run_coroutine_threadsafe tricks or !stmt-based awaits via asyncio.ensure_future.
scripts/run_tests.sh strips credentials and sets HOME=<tmpdir>. If your bug depends on user config or real API keys, it won't reproduce under the wrapper. Debug with raw pytest first to repro, then re-confirm under the wrapper.
Forking / multiprocessing. pdb does not follow forks. Each child needs its own breakpoint() or set_trace(). For Hermes subagents, debug one process at a time.
.venv/bin/python -c "import debugpy; print(debugpy.__version__); print(debugpy.__file__)"ss -tlnp | grep 5678PYTHONBREAKPOINT=0, you're under a parallel/capturing runner, or execution finished before attach)where / w shows the expected call stackbreakpoint() / set_trace() in committed code
rg -n 'breakpoint\(\)|set_trace\(|debugpy\.listen' --type py
"Why is this dict missing a key?"
# add above the KeyError site
breakpoint()
# then in pdb:
(Pdb) pp d
(Pdb) pp list(d.keys())
(Pdb) w # how did we get here
"This test passes in isolation but fails in the suite."
scripts/run_tests.sh tests/the_test.py # confirm it fails under the isolated runner first
# For interactive debugging, or if it only fails WITH other tests, use the
# independent development/test interpreter prepared in Recipe 5:
.venv/bin/python -m pytest tests/ -x --pdb
# Now it pdb-traps at the exact failing test after state accumulated.
"My async handler deadlocks."
# Add at handler entry
import remote_pdb; remote_pdb.set_trace(host="127.0.0.1", port=4444)
Trigger the handler. nc 127.0.0.1 4444, then w to see the suspended frame, !import asyncio; asyncio.all_tasks() to see what else is pending.
"Post-mortem on a crash in an Ink child process / subprocess."
PYTHONFAULTHANDLER=1 python -m pdb -c continue path/to/entrypoint.py
# On crash, pdb lands at the frame of the exception with full locals
还没有评价。欢迎分享你的使用感受。
无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。
还没有评论。来写第一条吧。
通过1Password CLI,将保存的密码和API密钥用于命令及配置模板,完成安装、认证、秘密值读取,并通过环境变量向命令传递凭据。
创建用公式联动利润表、资产负债表和现金流量表的 Excel 模型,分阶段填入历史实际数据与预测假设,比较不同情景,并检查三张报表之间的一致性。
Adapt existing PyTorch training scripts to use multiple GPUs or machines with limited code changes. The skill guides configuration, launch commands, mixed precision, which uses lower-precision numbers, and DeepSpeed or FSDP settings for distributing training work and memory.
中文简介正在准备中。当前显示英语简介。
Configure Hermes to run AI models through Actual Computer on your own hardware. Set up either the hosted relay or a local connection, select models, verify responses, and troubleshoot request errors or empty output.
中文简介正在准备中。当前显示英语简介。
扮演不擅长技术、容易不满的用户测试应用,发现难懂的操作和导致放弃使用的障碍。将实际可改进的问题与个人抱怨分开,整理截图、修复建议和任务单。
从中立立场解决两个智能体分别修改代码产生的Git冲突,对照双方差异和意图,记录每处冲突的取舍理由,并通过构建或测试验证合并结果。