
sidebar.wechat

sidebar.feishu
sidebar.chooseYourWayToJoin

sidebar.scanToAddConsultant
在 AskTable Canvas 中,不同类型的节点需要不同的 Agent 来处理:Data 节点生成 SQL、Chart 节点生成图表配置、Python 节点生成数据处理代码。如何设计一个灵活、可扩展的多 Agent 系统?
本文将深入剖析 AskTable Canvas Agent 的分工协作机制。
职责:
工具:
schema_linker:元数据检索sql_executor:SQL 执行sql_guard:权限控制职责:
工具:
chart_recommender:图表推荐echarts_generator:配置生成职责:
工具:
python_executor:代码执行dataframe_loader:加载父节点数据class BaseAgent(ABC):
"""Agent 基类"""
def __init__(self, node: NodeModel):
self.node = node
self.messages: list[dict] = []
self.result: dict = {}
@abstractmethod
async def run(self, message: str) -> AsyncGenerator[dict, None]:
"""流式执行,返回事件流"""
pass
@abstractmethod
def get_result(self) -> dict:
"""获取最终结果"""
pass
def get_messages(self) -> list[dict]:
"""获取对话历史"""
return self.messages
class DataNodeAgent(BaseAgent):
"""Data 节点 Agent"""
def __init__(
self,
node: NodeModel,
datasource: DataSourceAdmin,
reference_context: dict | None = None,
):
super().__init__(node)
self.datasource = datasource
self.reference_context = reference_context
async def run(self, message: str) -> AsyncGenerator[dict, None]:
"""流式执行"""
# 1. Schema Linking
yield {"type": "status", "data": "检索元数据..."}
meta_context = await self.schema_linker.link(message)
# 2. 生成 SQL
yield {"type": "status", "data": "生成 SQL..."}
sql = await self.generate_sql(message, meta_context)
yield {"type": "sql", "data": sql}
# 3. 执行 SQL
yield {"type": "status", "data": "执行查询..."}
df = await self.datasource.execute_sql(sql)
yield {"type": "dataframe", "data": df.to_dict()}
# 4. 生成解释
yield {"type": "status", "data": "生成解释..."}
explanation = await self.generate_explanation(message, df)
yield {"type": "explanation", "data": explanation}
# 5. 保存结果
self.result = {
"sql": sql,
"dataframe": df,
"explanation": explanation,
}
class ChartNodeAgent(BaseAgent):
"""Chart 节点 Agent"""
def __init__(
self,
node: NodeModel,
parent_contexts: list[dict],
):
super().__init__(node)
self.parent_contexts = parent_contexts
async def run(self, message: str) -> AsyncGenerator[dict, None]:
"""流式执行"""
# 1. 分析数据
yield {"type": "status", "data": "分析数据..."}
df = self.parent_contexts[0]["dataframe"]
# 2. 推荐图表类型
yield {"type": "status", "data": "推荐图表..."}
chart_type = await self.recommend_chart_type(df, message)
yield {"type": "chart_type", "data": chart_type}
# 3. 生成图表配置
yield {"type": "status", "data": "生成配置..."}
config = await self.generate_chart_config(df, chart_type, message)
yield {"type": "config", "data": config}
# 4. 保存结果
self.result = {
"chart_type": chart_type,
"config": config,
}
class ToolRegistry:
"""工具注册表"""
def __init__(self):
self.tools: dict[str, Callable] = {}
def register(self, name: str, func: Callable):
"""注册工具"""
self.tools[name] = func
async def call(self, name: str, **kwargs) -> Any:
"""调用工具"""
if name not in self.tools:
raise ValueError(f"Tool {name} not found")
return await self.tools[name](**kwargs)
# 注册工具
registry = ToolRegistry()
registry.register("execute_sql", execute_sql)
registry.register("generate_chart", generate_chart)
# Agent 调用工具
result = await registry.call("execute_sql", sql=sql, datasource=ds)
AskTable Canvas Agent 系统通过清晰的职责划分和灵活的工具调用机制,实现了高效的多 Agent 协作:
✅ 职责清晰:每个 Agent 专注于特定任务 ✅ 工具复用:通过工具注册表共享能力 ✅ 流式输出:实时反馈执行进度 ✅ 易于扩展:新增 Agent 类型简单
相关阅读:
技术交流:
sidebar.noProgrammingNeeded
sidebar.startFreeTrial