第 13 章 · 综合实战二:代码库只读审查助手
把第 3、5、6 章拼成真实场景:agent 在一个临时仓库里做只读审查——AGENTS.md 提供仓库规则,audit skill 提供审查清单,FilesystemBackend(virtual_mode=True) 把文件工具关在 root_dir 内。先做无 key 的结构自检,再执行模型步骤。
机制与设计选择
memory 在启动时加载 AGENTS.md;skills 是按需全文,audit skill 的三类检查点只在任务相关时被读取。tools_by_name 检查保证默认七件文件工具都可见——“只读”是 system prompt 的约定,不是工具层强制,真正强制要靠第 3 章的权限与中间件 allowlist。
示例
python
import os, pathlib, tempfile, shutil
from langchain_openai import ChatOpenAI
from deepagents import create_deep_agent
from deepagents.backends import FilesystemBackend
root = tempfile.mkdtemp(prefix="deepagents-audit-")
try:
repo = pathlib.Path(root) / "repo"
repo.mkdir()
(repo / "AGENTS.md").write_text("# Repo rules\n- All CLI writes must be idempotent\n- Tests live in tests/\n")
(repo / "main.py").write_text("import os\nos.system('rm -rf build') # risky shell use\n")
skill = pathlib.Path(root) / "skills" / "audit"
skill.mkdir(parents=True)
(skill / "SKILL.md").write_text(
"---\nname: audit\ndescription: Audit a codebase for risky shell and missing tests\n---\n"
"Flag: (1) os.system/subprocess without validation, (2) missing tests for public functions.\n"
)
model = ChatOpenAI(
model=os.environ["MODEL_ID"],
api_key=os.environ["DEEPAGENT_API_KEY"],
base_url=os.environ.get("DEEPAGENT_BASE_URL", "https://api.openai.com/v1"),
)
agent = create_deep_agent(
model=model,
backend=FilesystemBackend(root_dir=str(repo), virtual_mode=True),
memory=[str(repo / "AGENTS.md")],
skills=[str(skill.parent)],
system_prompt="Audit this repository. Inspect files with read_file/ls/grep; do not modify files.",
)
# Structural self-check (no model call needed):
available = sorted(agent.nodes["tools"].bound.tools_by_name)
for required in ["ls", "read_file", "write_file", "edit_file", "delete", "glob", "grep"]:
assert required in available, (required, available)
print("file tools visible to the model:", available)
# Model step (skipped when no key is configured):
if os.environ.get("DEEPAGENT_API_KEY") not in ("", "sk-fake"):
result = agent.invoke(
{"messages": [{"role": "user", "content": "Run the audit skill on this repo and report findings."}]},
{"configurable": {"thread_id": "ch13"}},
)
print(result["messages"][-1].content)
else:
print("model step skipped: DEEPAGENT_API_KEY not configured; structural check passed.")
finally:
shutil.rmtree(root, ignore_errors=True)运行与验收
无 key 运行:输出文件工具列表与 model step skipped,结构断言通过。配置 key 后运行:最终消息应指出 main.py 里的 os.system 风险与缺失的测试,且不修改任何仓库文件(临时目录在 finally 清理)。
容易踩的坑
系统提示词的“只读”可以被模型违反;审计类任务应在代码层限制写工具或拒绝写路径。临时目录是隔离手段,不能替代权限边界;生产仓库用 StoreBackend/远程沙箱而不是本地临时目录。
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. memory 何时加载 AGENTS.md?
2. skills 如何进入上下文?
3. tools_by_name 检查证明什么?
4. 只读如何强制?
动手实践
- 把 audit skill 换成你的项目规范。
- 用第 3 章权限规则真正禁止写 .env。
- 为 main.py 补测试,观察二次审查结果。
官方参考
核验日期:2026-09-17,示例已在本机离线运行验证。