AI 数据分析 Agent 协作:模型之间怎么传上下文不丢信息
AI 数据分析 Agent 协作:模型之间怎么传上下文不丢信息
一、Agent 协作:多个模型的"接力赛"
单个 AI 模型能做很多事,但复杂的数据分析任务往往需要多个模型分工合作——一个擅长写 SQL,一个擅长统计分析,一个擅长可视化,一个擅长写报告。就像接力赛:每个运动员跑自己擅长的段落,交接棒时不能掉,否则整场比赛就废了。
Agent 之间的"交接棒"就是上下文传递。模型 A 的分析结果要完整准确地传给模型 B,B 基于这些结果继续分析,再传给模型 C。如果交接棒掉了——关键信息丢失、数据被误读、结论被扭曲——后续模型的分析就是空中楼阁。
上下文丢失的典型场景:
| 场景 | 丢失什么 | 后果 |
|---|---|---|
| SQL Agent → 分析 Agent | 查询的过滤条件和聚合逻辑 | 分析 Agent 不知道数据范围,结论偏差 |
| 分析 Agent → 报告 Agent | 统计检验的置信区间和效应大小 | 报告只写"显著",不写"效应多大" |
| 分析 Agent → 可视化 Agent | 数据的分层数和异常点 | 可视化忽略异常点,图表误导 |
| 任意 Agent → 下一步 | 前置假设和排除的路径 | 后续模型重复探索已排除的路径 |
二、上下文传递的三种模式
Agent 之间传上下文不是简单地把上一个模型的输出塞给下一个模型。不同场景需要不同的传递模式:
flowchart TB
A[上下文传递模式] --> B[模式1: 结构化接力]
A --> C[模式2: 共享记忆池]
A --> D[模式3: 分层压缩]
B --> E[适合: 固定流程<br>SQL→分析→报告]
C --> F[适合: 并行探索<br>多个Agent同时工作]
D --> G[适合: 长链路任务<br>6步以上的分析]
style B fill:#4ecdc4
style C fill:#ffe66d
style D fill:#ff6b6b
模式 1:结构化接力
每个 Agent 输出标准化的结构化数据,下一个 Agent 只接收结构化输入。像接力赛交接棒——棒的形状是固定的,不会变形。
# 结构化接力模式
from typing import TypedDict, List, Optional
from datetime import datetime
# 定义标准化的上下文结构
class SQLAgentOutput(TypedDict):
"""SQL Agent 的标准输出格式"""
task_id: str # 任务唯一标识
sql: str # 执行的SQL语句
result_shape: tuple # 结果数据形状 (rows, cols)
columns: List[dict] # 列信息:名称、类型、含义
filters_applied: List[str] # 查询中应用的过滤条件
aggregation_logic: List[str] # 聚合逻辑说明
execution_time: float # SQL执行耗时(秒)
data_summary: dict # 数据概要统计
anomalies_found: List[str] # SQL阶段发现的异常
class AnalysisAgentOutput(TypedDict):
"""分析 Agent 的标准输出格式"""
task_id: str
input_task_id: str # 上一步的任务ID,形成链路
analysis_type: str # 分析类型(对比/趋势/分布/归因)
findings: List[dict] # 发现的结论列表
statistical_tests: List[dict] # 统计检验结果(含置信区间)
assumptions_made: List[str] # 做了哪些假设
paths_excluded: List[str] # 排除了哪些分析路径
confidence_level: str # 整体置信度评级
next_steps_suggested: List[str] # 建议的下一步分析
class ReportAgentOutput(TypedDict):
"""报告 Agent 的标准输出格式"""
task_id: str
input_task_id: str
title: str # 报告标题
sections: List[dict] # 报告章节
key_metrics: List[dict] # 核心指标(含数值+置信区间)
visualizations_needed: List[dict] # 需要的可视化类型和数据
limitations: List[str] # 分析局限说明
# Agent 协作链路
def run_structured_pipeline(user_query: str) -> dict:
"""结构化接力:SQL → 分析 → 报告"""
# 第一步:SQL Agent
sql_output = sql_agent(user_query)
# 第二步:分析 Agent(接收SQL Agent的完整输出)
analysis_input = {
"data_description": sql_output,
"user_intent": user_query,
"prior_context": None # 首步没有前置上下文
}
analysis_output = analysis_agent(analysis_input)
# 第三步:报告 Agent(接收分析Agent的完整输出+SQL Agent的关键信息)
report_input = {
"analysis_results": analysis_output,
"data_scope": { # 从SQL Agent传递关键元信息
"filters": sql_output["filters_applied"],
"shape": sql_output["result_shape"],
"anomalies": sql_output["anomalies_found"]
},
"user_intent": user_query
}
report_output = report_agent(report_input)
return {
"pipeline_trace": {
"sql_task_id": sql_output["task_id"],
"analysis_task_id": analysis_output["task_id"],
"report_task_id": report_output["task_id"]
},
"final_report": report_output
}
结构化接力模式的关键:每个 Agent 的输出格式是预先定义的,不能随意增减字段。这保证了下一个 Agent 总是能拿到它需要的所有信息。
三、共享记忆池:并行 Agent 的信息交换
多个 Agent 并行工作时,它们需要共享一个记忆池——像团队协作时的共享文档,每个人都能读到其他人写的内容,也能往里追加自己的发现。
# 共享记忆池模式
class SharedMemoryPool:
"""Agent协作的共享记忆池"""
def __init__(self):
self.entries = [] # 所有Agent的输出记录
self.facts = {} # 已确认的事实
self.hypotheses = {} # 待验证的假设
self.contradictions = [] # 发现的矛盾点
def add_entry(self, agent_name: str, entry_type: str,
content: dict, confidence: float) -> str:
"""Agent向记忆池追加一条记录"""
entry_id = f"{agent_name}_{len(self.entries)}"
entry = {
"id": entry_id,
"agent": agent_name,
"type": entry_type, # fact/hypothesis/observation/question
"content": content,
"confidence": confidence, # 0-1置信度
"timestamp": datetime.now().isoformat(),
"references": [] # 引用了哪些其他entry
}
self.entries.append(entry)
# 如果是高置信度的事实,加入事实库
if entry_type == "fact" and confidence >= 0.8:
self.facts[entry_id] = content
# 如果是假设,加入假设库
elif entry_type == "hypothesis":
self.hypotheses[entry_id] = content
# 检查是否与已有信息矛盾
self._check_contradictions(entry)
return entry_id
def get_relevant_context(self, agent_name: str,
task_description: str) -> dict:
"""为Agent提取与当前任务相关的上下文"""
relevant_facts = []
relevant_hypotheses = []
for entry in self.entries:
# 简单相关性判断:检查内容是否包含任务关键词
if self._is_relevant(entry["content"], task_description):
if entry["type"] == "fact":
relevant_facts.append(entry)
elif entry["type"] == "hypothesis":
relevant_hypotheses.append(entry)
return {
"relevant_facts": relevant_facts,
"relevant_hypotheses": relevant_hypotheses,
"contradictions": self.contradictions,
"total_entries": len(self.entries)
}
def _check_contradictions(self, new_entry: dict):
"""检查新entry与已有信息是否矛盾"""
if new_entry["type"] == "fact":
for fact_id, fact_content in self.facts.items():
if self._is_contradictory(new_entry["content"], fact_content):
self.contradictions.append({
"new_entry": new_entry["id"],
"existing_fact": fact_id,
"description": "新发现与已确认事实冲突"
})
def _is_relevant(self, content: dict, description: str) -> bool:
"""简单相关性判断"""
# 将内容转为字符串后做关键词匹配
content_str = str(content).lower()
# 提取任务描述的关键词
keywords = description.lower().split()
return any(kw in content_str for kw in keywords)
def _is_contradictory(self, new_content: dict,
existing_content: dict) -> bool:
"""判断两个内容是否矛盾(简化实现)"""
# 实际实现会用AI判断语义冲突
return False # 临时实现
共享记忆池的好处是——Agent 之间不需要直接"交接棒",而是通过公共区域交换信息。这样多个 Agent 可以并行工作,互相看到对方的发现,避免重复探索和结论冲突。
四、分层压缩:长链路的信息保真
当分析链路超过 5 步时,上下文会越来越长。如果每一步都把上一步的全部输出传下去,最后一步的模型可能收到上万字的上下文——信息太多反而难以聚焦。
分层压缩的核心思路:关键信息全量传递,细节信息摘要压缩。
flowchart TB
A[Agent1 全量输出] --> B[压缩层]
B --> C[关键信息: 全量传递]
B --> D[细节信息: 摘要压缩]
C --> E[Agent2 接收]
D --> E
E --> F[Agent2 全量输出]
F --> G[压缩层]
G --> H[关键信息: 全量传递]
G --> I[Agent1的关键信息: 二次压缩]
I --> J[Agent3 接收]
H --> J
style B fill:#4ecdc4
style G fill:#4ecdc4
# 分层压缩模式
def compress_context(full_output: dict, layer: int) -> dict:
"""根据链路层数压缩上下文
参数:
full_output: Agent的完整输出
layer: 当前在第几层传递(1=最近一步,2=两步前...)
"""
if layer <= 2:
# 最近2步:几乎全量传递,只去掉大块原始数据
compressed = {
"task_id": full_output["task_id"],
"analysis_type": full_output.get("analysis_type", ""),
"findings": full_output.get("findings", []),
"statistical_tests": full_output.get("statistical_tests", []),
"confidence_level": full_output.get("confidence_level", ""),
"filters_applied": full_output.get("filters_applied", []),
"assumptions_made": full_output.get("assumptions_made", []),
"paths_excluded": full_output.get("paths_excluded", []),
# 压缩:去掉原始数据详情,只保留概要
"data_summary": full_output.get("data_summary", {}),
}
elif layer <= 4:
# 3-4步前:摘要级压缩,只保留核心发现
compressed = {
"task_id": full_output["task_id"],
"key_findings": [
f["summary"] for f in full_output.get("findings", [])
], # 只保留发现的一句话摘要
"confidence_level": full_output.get("confidence_level", ""),
"assumptions_made": full_output.get("assumptions_made", []),
"paths_excluded": full_output.get("paths_excluded", []),
}
else:
# 5步以上:极简压缩,只保留结论和关键假设
compressed = {
"task_id": full_output["task_id"],
"conclusion": " ".join([
f["summary"] for f in full_output.get("findings", [])[:3]
]),
"key_assumptions": full_output.get("assumptions_made", [])[:5],
"confidence_level": full_output.get("confidence_level", ""),
}
return compressed
# 长链路协作示例
def run_long_pipeline(user_query: str, num_steps: int = 6) -> dict:
"""6步以上的长链路协作,使用分层压缩传递上下文"""
memory = SharedMemoryPool()
pipeline_trace = []
context_stack = [] # 累积的上下文栈
agents = [
("sql_agent", sql_agent),
("data_quality_agent", data_quality_agent),
("stats_agent", stats_agent),
("trend_agent", trend_agent),
("insight_agent", insight_agent),
("report_agent", report_agent)
]
for step, (agent_name, agent_fn) in enumerate(agents[:num_steps]):
# 构建当前Agent的输入上下文
if step == 0:
# 第一步:只有用户原始查询
input_context = {"user_query": user_query}
else:
# 后续步骤:压缩后的历史上下文 + 当前任务
input_context = {
"current_task": user_query,
"recent_context": compress_context(
context_stack[-1], layer=1
),
"earlier_context": [
compress_context(ctx, layer=step - i)
for i, ctx in enumerate(context_stack[:-1])
],
"shared_memory": memory.get_relevant_context(
agent_name, user_query
)
}
# 执行Agent
output = agent_fn(input_context)
# 存入上下文栈和共享记忆池
context_stack.append(output)
memory.add_entry(
agent_name, "observation",
output, float(output.get("confidence_level", "0.5"))
)
pipeline_trace.append({
"step": step + 1,
"agent": agent_name,
"task_id": output["task_id"]
})
return {
"pipeline_trace": pipeline_trace,
"final_output": context_stack[-1],
"shared_memory_summary": {
"total_facts": len(memory.facts),
"total_hypotheses": len(memory.hypotheses),
"contradictions": len(memory.contradictions)
}
}
# Agent函数示例(简化实现)
def sql_agent(input_ctx: dict) -> dict:
"""SQL Agent: 从用户查询生成并执行SQL"""
return {
"task_id": "sql_001",
"sql": "SELECT ... FROM ... WHERE ...",
"findings": [{"summary": "GMV环比下降15%", "detail": "..."}],
"filters_applied": ["dt >= 2026-06-01", "status = paid"],
"confidence_level": "0.9",
"assumptions_made": ["数据延迟不超过24小时"],
"paths_excluded": ["排除取消订单的影响"]
}
def data_quality_agent(input_ctx: dict) -> dict:
"""数据质量 Agent: 检查数据质量"""
return {
"task_id": "dq_001",
"analysis_type": "quality_check",
"findings": [{"summary": "6月数据完整度99.2%", "detail": "..."}],
"confidence_level": "0.95",
"assumptions_made": [],
"paths_excluded": []
}
def stats_agent(input_ctx: dict) -> dict:
"""统计分析 Agent: 执行统计检验"""
return {
"task_id": "stats_001",
"analysis_type": "hypothesis_test",
"findings": [{"summary": "GMV下降统计显著(p<0.01), Cohen's d=0.8", "detail": "..."}],
"statistical_tests": [{"test": "t-test", "p_value": 0.003, "effect_size": 0.8}],
"confidence_level": "0.85",
"assumptions_made": ["数据近似正态分布"],
"paths_excluded": []
}
def trend_agent(input_ctx: dict) -> dict:
return {"task_id": "trend_001", "analysis_type": "trend", "findings": [{"summary": "下降趋势持续3周", "detail": "..."}], "confidence_level": "0.7", "assumptions_made": [], "paths_excluded": []}
def insight_agent(input_ctx: dict) -> dict:
return {"task_id": "insight_001", "analysis_type": "insight", "findings": [{"summary": "核心原因是新用户转化率下降", "detail": "..."}], "confidence_level": "0.75", "assumptions_made": ["假设转化率是主要原因"], "paths_excluded": ["排除竞品影响(无数据支持)"]}
def report_agent(input_ctx: dict) -> dict:
return {"task_id": "report_001", "title": "GMV异动分析报告", "sections": [], "confidence_level": "0.8", "assumptions_made": [], "paths_excluded": []}
分层压缩的规则:
- 最近 2 步几乎全量传递——最新信息最可能被当前 Agent 直接引用
- 3-4 步前只保留核心发现的一句话摘要——细节已经不那么重要了
- 5 步以上只保留结论和关键假设——避免远古信息干扰当前判断
必须全量传递的关键信息:
- 过滤条件——不知道数据范围就无法正确解读结论
- 假设列表——不知道前置假设就无法判断结论的适用条件
- 排除路径——不知道哪些路径已排除就会重复探索
这三类信息无论压缩到什么程度都不能丢。它们是"交接棒"的核心——棒的形状可以简化,但棒的材质不能变。
五、总结
AI 数据分析 Agent 协作的核心问题是上下文传递——模型之间怎么传信息不丢关键内容。
三种传递模式各有适用场景:
- 结构化接力:适合固定流程(SQL→分析→报告),每个 Agent 输出标准化格式,下一个 Agent 只接收结构化输入
- 共享记忆池:适合并行探索,多个 Agent 通过公共记忆池交换发现,避免重复探索和结论冲突
- 分层压缩:适合长链路任务,最近 2 步全量传递,3-4 步保留摘要,5 步以上只留结论和假设
三类不能丢的信息:
- 过滤条件——不知道数据范围就无法正确解读结论
- 前置假设——不知道假设就无法判断结论的适用条件
- 排除路径——不知道已排除路径就会重复探索
Agent 协作不是简单的串行调用——它是接力赛,交接棒不能掉。上下文传递的质量,决定了协作链路的整体质量。结构化、共享、压缩,三种模式组合使用,才能在信息保真和效率之间找到平衡。
更多推荐


所有评论(0)