
DeepSeek Agent Harness 2026终极指南 - 第11章第52节 文件树注入让Agent看见项目全貌第51节解决了历史太长但还有个问题——Agent 不知道项目长什么样。你让它改一下用户模块的代码它得先猜文件在哪、有哪些文件、依赖是什么。这节做文件树注入把项目结构树、README、pyproject、git 状态一起塞进上下文让 Agent 一启动就看见项目全貌不用瞎猜、不用反复 grep。本文导航Agent 为什么需要看见项目项目结构树生成与token控制重要文件自动注入git状态与最近提交注入完整实现context_inject.py实测Agent 一启动就懂项目小结Agent 为什么需要看见项目想象两个场景场景A没有文件树。你问 Agent改一下登录逻辑Agent 的对话是Agent: 让我先找找登录相关的代码。 → grep login → 找到 auth.py、login.py、user.py 三个文件但不知道哪个是主入口 → 还得再读 README、读 pyproject 确定项目结构 → 来回好几轮才搞清楚项目长什么样场景B有文件树注入。你问同样的问题Agent 一启动就看到项目结构 deep_pilot/ ├── config.py # 配置 ├── client.py # DeepSeek 客户端 ├── auth.py # 登录认证逻辑 ├── ...Agent: 我看到了auth.py 是登录认证模块直接改它就行。环境感知是 Agent 效率的关键。注入项目结构能让 Agent 少做很多无用功。项目结构树生成与token控制用os.walk或Path.rglob生成目录树# deep_pilot/context_inject.py —— 环境注入 v0.6from__future__importannotationsfrompathlibimportPathfromdeep_pilot.loggerimportget_logger loggerget_logger(__name__)# 忽略的目录生成文件树时跳过IGNORE_DIRS{.git,node_modules,.venv,__pycache__,dist,build,.pytest_cache,.tox}# 忽略的文件IGNORE_FILES{.pyc,.pyo,.so,.dll,.exe}defgenerate_tree(root:Path,max_depth:int3,max_files:int200)-str: 生成项目结构树。 max_depth: 最大目录深度 max_files: 最多列出的文件数 rootPath(root).resolve()lines[]file_count0defwalk(dir_path:Path,prefix:str,depth:int):nonlocalfile_countifdepthmax_depth:lines.append(f{prefix}...深度超限已省略)returnentriessorted(dir_path.iterdir(),keylambdap:(p.is_file(),p.name))forentryinentries:# 跳过忽略项ifentry.nameinIGNORE_DIRS:continueifentry.is_file()andentry.suffixinIGNORE_FILES:continueiffile_countmax_files:lines.append(f{prefix}...文件数超限已省略)returnifentry.is_dir():lines.append(f{prefix}├──{entry.name}/)walk(entry,prefix│ ,depth1)else:lines.append(f{prefix}├──{entry.name})file_count1lines.append(f{root.name}/)walk(root,,1)return\n.join(lines)token 控制的三板斧max_depth限制目录深度太深的目录不展开max_files限制文件数量超过就省略忽略目录.git、node_modules等大目录直接跳过一个典型的中型项目生成的文件树约 800-1500 token可接受。重要文件自动注入除了结构树几个关键文件值得完整注入——它们是理解项目的钥匙definject_important_files(root:Path)-str:注入重要文件内容README/pyproject等important_files[README.md,pyproject.toml,.env.example,]parts[]forfnameinimportant_files:fpathroot/fnameiffpath.exists():contentfpath.read_text(encodingutf-8,errorsignore)# 限制每个文件最多注入 1000 字符iflen(content)1000:contentcontent[:1000]\n...[已截断]parts.append(f###{fname}\n\n{content}\n)return\n\n.join(parts)为什么是这几个文件README.md项目是干嘛的、怎么用一目了然pyproject.toml依赖、版本、构建配置理解技术栈.env.example需要哪些环境变量不含真实密钥git状态与最近提交注入git 状态告诉 Agent最近在改什么避免重复劳动importsubprocessdefinject_git_status(root:Path)-str:注入 git 状态和最近提交parts[]# git statustry:statussubprocess.run([git,status,--short],cwdroot,capture_outputTrue,textTrue,timeout5,)ifstatus.returncode0andstatus.stdout.strip():parts.append(f### Git 状态未提交的改动\n\n{status.stdout.strip()}\n)exceptException:pass# 最近提交try:logsubprocess.run([git,log,--oneline,-5],cwdroot,capture_outputTrue,textTrue,timeout5,)iflog.returncode0andlog.stdout.strip():parts.append(f### 最近提交\n\n{log.stdout.strip()}\n)exceptException:passreturn\n\n.join(parts)git 状态的价值如果 Agent 看到已经有 3 个文件被修改正在改登录功能它就会接着这个思路往下做而不是另起炉灶。完整实现context_inject.py整合成完整模块拼装成一段环境上下文# deep_pilot/context_inject.py —— 完整版from__future__importannotationsimportsubprocessfrompathlibimportPathfromdeep_pilot.loggerimportget_logger loggerget_logger(__name__)IGNORE_DIRS{.git,node_modules,.venv,__pycache__,dist,build,.pytest_cache,.tox}IGNORE_FILES{.pyc,.pyo,.so,.dll,.exe}defgenerate_tree(root:Path,max_depth:int3,max_files:int200)-str:rootPath(root).resolve()lines[]file_count0defwalk(dir_path:Path,prefix:str,depth:int):nonlocalfile_countifdepthmax_depth:lines.append(f{prefix}...深度超限)returnentriessorted(dir_path.iterdir(),keylambdap:(p.is_file(),p.name))forentryinentries:ifentry.nameinIGNORE_DIRS:continueifentry.is_file()andentry.suffixinIGNORE_FILES:continueiffile_countmax_files:lines.append(f{prefix}...文件数超限)returnifentry.is_dir():lines.append(f{prefix}├──{entry.name}/)walk(entry,prefix│ ,depth1)else:lines.append(f{prefix}├──{entry.name})file_count1lines.append(f{root.name}/)walk(root,,1)return\n.join(lines)definject_important_files(root:Path)-str:parts[]forfnamein[README.md,pyproject.toml,.env.example]:fpathroot/fnameiffpath.exists():contentfpath.read_text(encodingutf-8,errorsignore)iflen(content)1000:contentcontent[:1000]\n...[已截断]parts.append(f###{fname}\n\n{content}\n)return\n\n.join(parts)definject_git_status(root:Path)-str:parts[]try:statussubprocess.run([git,status,--short],cwdroot,capture_outputTrue,textTrue,timeout5)ifstatus.returncode0andstatus.stdout.strip():parts.append(f### Git 状态\n\n{status.stdout.strip()}\n)exceptException:passtry:logsubprocess.run([git,log,--oneline,-5],cwdroot,capture_outputTrue,textTrue,timeout5)iflog.returncode0andlog.stdout.strip():parts.append(f### 最近提交\n\n{log.stdout.strip()}\n)exceptException:passreturn\n\n.join(parts)defbuild_environment_context(root:Path|str.)-str:构建完整的环境上下文用于注入 system prompt 或首条消息rootPath(root).resolve()sections[]treegenerate_tree(root)sections.append(f## 项目结构\n\n{tree}\n)importantinject_important_files(root)ifimportant:sections.append(f## 重要文件\n{important})git_infoinject_git_status(root)ifgit_info:sections.append(git_info)return\n\n.join(sections)实测Agent 一启动就懂项目uv run python-c from deep_pilot.context_inject import build_environment_context env_ctx build_environment_context(.) print(env_ctx[:800]) print(...) print(f环境上下文总长度: {len(env_ctx)} 字符) 控制台输出精简## 项目结构deep-pilot/├── deep_pilot/│ ├──init.py│ ├── agent_loop.py│ ├── client.py│ ├── config.py│ ├── file_tools.py│ ├── …├── tests/├── pyproject.toml├── README.md## 重要文件 ### pyproject.toml[project]name “deep-pilot”dependencies [“openai”, “pydantic”, …]... 环境上下文总长度: 2847 字符Agent 一启动就看见了项目结构、依赖、README不用瞎猜。实际使用时把这段环境上下文注入到 system prompt 或首条 user 消息里# agent_loop.py 里env_ctxbuild_environment_context(.)messages[{role:system,content:f你是 DeepPilot 编程助手。\n\n当前项目环境\n{env_ctx}},{role:user,content:user_query},]小结环境感知是效率关键注入项目结构让 Agent 少做无用功一启动就懂项目。文件树生成三控max_depth 限深度、max_files 限数量、IGNORE_DIRS 跳过无关目录。重要文件注入README项目是什么、pyproject技术栈、.env.example环境变量。git 状态注入告诉 Agent最近在改什么避免重复劳动、接着思路做。token 可控文件树约 800-1500 token重要文件限 1000 字符整体几千字符可接受。注入到 system prompt环境上下文放 systemAgent 全程可见。DeepPilot v0.6 文件树注入完成——Agent 从瞎子摸象到一眼看全效率大幅提升。下节预告注入了项目结构Agent看见了。但还有个更根本的问题——系统提示词怎么写。system prompt 是 Agent 的灵魂决定了它的行为方式。下一节做系统提示词工程把 DeepPilot 的系统提示词逐段拆解角色定义/工具规范/安全约束/输出格式再讲版本管理和回归测试。如果觉得本文对你有帮助欢迎点赞、收藏、关注三连本系列持续更新中关注不迷路~