一、核心问题:单Agent上下文「膨胀污染」
面试官关注的核心痛点是:单Agent处理复杂任务时,上下文会无限膨胀且充斥冗余信息 。
比如回答「这个项目用什么测试框架?」,单Agent需要读取5个文件、执行多次bash命令,这些文件内容、命令输出会永久留在上下文里------父任务只需要「pytest」这个结论,但上下文里全是无关的原始数据,导致:
- 上下文过长,模型推理变慢、易出错;
- 核心信息被冗余内容淹没,模型抓不住重点;
- 多步骤任务的上下文混乱,难以维护。
二、核心方案:父-子Agent(次级代理)架构
核心逻辑是「父Agent做规划协调,子Agent做具体执行,执行完销毁上下文,只返回摘要」,彻底解决上下文膨胀问题,先看核心架构:
父Agent(Parent) 子Agent(Sub/次级)
+------------------------+ +------------------------+
| 职责:拆分任务、汇总结果 | 职责:执行单一子任务 |
| 上下文:干净,只存核心信息 | 上下文:独立、新鲜、用完丢|
| 工具:包含「task」工具 | 工具:基础工具(bash/读写)|
| | | |
| 1. 收到用户大任务 | | 1. 接收父Agent的子任务 |
| 2. 调用「task」工具派生子Agent| --> | 2. 用全新空上下文执行 |
| 3. 等待子Agent返回摘要 | <-- | 3. 执行完返回最终文本摘要|
| 4. 用摘要回答用户 | | 4. 销毁自身所有上下文 |
+------------------------+ +------------------------+
三、核心代码逻辑(上下文管理是关键)
1. 工具分层:父有「派生子任务」能力,子只有基础工具
python
# 子Agent的基础工具(bash/读写文件等,无递归能力)
CHILD_TOOLS = [bash_tool, read_file_tool, write_file_tool, edit_file_tool]
# 父Agent的工具 = 子工具 + task工具(核心:派生子Agent)
PARENT_TOOLS = CHILD_TOOLS + [
{
"name": "task",
"description": "Spawn a subagent with fresh context.", # 生成新上下文的子Agent
"input_schema": {
"type": "object",
"properties": {"prompt": {"type": "string"}}, # 传给子Agent的子任务指令
"required": ["prompt"],
}
},
]
- 子Agent没有「task」工具:避免无限递归派生子Agent;
- 父Agent独有「task」工具:唯一能触发子Agent的入口,保证层级可控。
2. 子Agent执行函数(核心:独立上下文+用完销毁)
python
def run_subagent(prompt: str) -> str:
# 关键1:子Agent的上下文是全新空列表,和父Agent完全隔离
sub_messages = [{"role": "user", "content": prompt}]
# 安全限制:最多执行30轮工具调用,防止死循环
for _ in range(30):
# 调用模型:用子Agent的独立上下文、子工具集
response = client.messages.create(
model=MODEL,
system=SUBAGENT_SYSTEM, # 子Agent的专属系统提示(更聚焦执行)
messages=sub_messages, # 子Agent的独立上下文,和父无关
tools=CHILD_TOOLS, # 只有基础工具,不能派生新子Agent
max_tokens=8000,
)
# 子Agent的上下文更新(只在自己的列表里加,不影响父)
sub_messages.append({"role": "assistant", "content": response.content})
# 如果子Agent完成任务(不需要再调用工具),终止循环
if response.stop_reason != "tool_use":
break
# 执行子Agent调用的工具(bash/读写等)
results = []
for block in response.content:
if block.type == "tool_use":
handler = TOOL_HANDLERS.get(block.name)
output = handler(**block.input)
results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": str(output)[:50000] # 子Agent的原始输出(只在自己上下文里)
})
# 工具结果加入子Agent的独立上下文
sub_messages.append({"role": "user", "content": results})
# 关键2:子Agent只返回最终文本摘要,丢弃所有中间上下文
return "".join(b.text for b in response.content if hasattr(b, "text")) or "(no summary)"
上下文管理核心点:
sub_messages是子Agent的独立上下文,从空列表开始,和父Agent的messages完全隔离;- 子Agent执行过程中,所有工具调用、原始输出都只存在于
sub_messages中; - 执行完成后,只返回「最终文本摘要」给父Agent,
sub_messages被销毁(函数执行完局部变量释放),父上下文里只有摘要,没有冗余原始数据。
3. 父Agent调用子Agent的逻辑
父Agent收到用户的复杂任务后,会:
- 决定拆分出子任务(比如「检查项目测试框架」);
- 调用「task」工具,传入子任务prompt;
- 执行
run_subagent(prompt),得到子Agent返回的摘要(比如「pytest」); - 把这个摘要加入自己的上下文,继续处理其他子任务;
- 最终用所有子任务的摘要汇总,回答用户。
四、面试官最关心的「上下文管理」核心要点
- 隔离性:父、子Agent的上下文完全独立,子Agent的上下文是「新鲜空列表」,不会继承父的冗余信息;
- 销毁机制:子Agent执行完子任务后,其所有中间上下文(文件内容、bash输出等)全部销毁,只返回摘要,父上下文只保留核心结论;
- 层级可控:只有父Agent能派生子Agent,子Agent没有「task」工具,避免无限递归;
- 轻量化:父Agent的上下文始终「干净」,只存任务拆分、子任务摘要等核心信息,解决单Agent上下文膨胀的问题。
五、举例理解(面试能直接说的场景)
用户问:「构建登录功能并写测试,告诉我用了什么测试框架,测试是否通过」。
- 父Agent拆分2个子任务:① 构建登录功能;② 编写并执行测试,确认测试框架和结果;
- 父Agent调用「task」工具,给子Agent1传prompt「构建登录功能」,子Agent1用全新上下文执行(创建文件、写代码),返回摘要「登录功能已构建,文件路径:login.py」;
- 父Agent再调用「task」工具,给子Agent2传prompt「测试login.py,确认用的测试框架和测试结果」,子Agent2用全新上下文执行(读取文件、执行pytest命令、查看输出),返回摘要「测试框架:pytest,测试通过,共2个用例」;
- 父Agent汇总两个摘要,回答用户,其上下文里只有「子任务1摘要+子任务2摘要」,没有子Agent执行过程中读取的文件内容、bash输出等冗余信息。
总结(面试答法)
多Agent的上下文管理核心是「分层隔离+用完销毁+只传摘要」:
- 父Agent做任务拆分和结果汇总,上下文只保留核心信息,保证轻量化;
- 子Agent处理单一子任务,使用独立的全新上下文,避免父上下文被冗余数据污染;
- 子Agent执行完后销毁自身所有中间上下文,只返回摘要给父Agent,从根本上解决单Agent上下文膨胀、信息冗余的问题。
这种架构的优势是上下文清晰、模型推理效率高,尤其适合复杂、多步骤的任务,这也是面试官关注的核心------你要能说清「隔离」「销毁」「摘要」这三个关键词,以及它们如何解决上下文管理的痛点。