ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Data Cleaning Agent 上线前安全评审实录:ai-data-science-team 五大风险发现、修复落地与沙箱化执行指南

Data Cleaning Agent 上线前安全评审实录:ai-data-science-team 五大风险发现、修复落地与沙箱化执行指南 Data Cleaning Agent 上线前安全评审实录ai-data-science-team 五大风险发现、修复落地与沙箱化执行指南【免费下载链接】ai-data-science-teamAn AI-powered data science team of agents to help you perform common data science tasks 10X faster.项目地址: https://gitcode.com/GitHub_Trending/ai/ai-data-science-team本文以 ai-data-science-team 仓库中的官方评审文档 planning_docs/package_review_initial_release/data_cleaning_agent_review.md 为骨架逐条解读DataCleaningAgent在正式发布前暴露的高/中/低风险问题并结合当前仓库源码ai_data_science_team/agents/data_cleaning_agent.py、ai_data_science_team/utils/sandbox.py 等核对每一项问题的修复落地情况。读完本文你将掌握LLM 生成代码类 Agent 的安全评审方法论、代码执行沙箱化的具体实现思路、Prompt 载荷token 预算治理手段以及如何正确规避invoke_agent返回值与日志路径默认值等隐蔽坑位。一、评审背景被评审的 Data Cleaning Agent 是什么1.1 Agent 的定位与能力边界DataCleaningAgent是 ai-data-science-team 提供的核心数据清洗智能体。它接收用户指令user_instructions与原始数据集data_raw由 LLM 生成一个可复现的 Python 清洗函数并在真实数据上执行最终输出清洗后的 DataFrame 与清洗摘要。从类定义ai_data_science_team/agents/data_cleaning_agent.py#L54-L158可以看到其默认清洗步骤包括删除缺失值超过 40% 的列数值列用均值mean填补缺失值类别列用众数mode填补将列转换为合适的数据类型数值 / 类别 / 时间删除重复行可选删除仍存在缺失值的行删除极端离群值超过 3 倍 IQR 的值。用户指令可以修改、增加或移除上述任何步骤这也是 Agent 灵活性的来源——但同时也是安全与稳定性风险的来源。1.2 评审聚焦点评审文档明确说明评审范围Focus为三件事graph wiring图编排LangGraph 状态图的节点连接是否正确prompts提示词各节点 Prompt 的构造质量与载荷规模execution path执行路径LLM 生成代码从产出到执行的完整链路。评审结论为存在多项高/中风险项需要在更大范围使用前完成缓解mitigation。仓库根目录的 planning_docs/package_review_initial_release/ 目录下还存放了langchain_conversation_plan.md、sandbox_plan.md等配套设计文档可见该评审隶属于初版发布前包评审阶段。二、按严重性排序的五大风险发现评审文档将发现的问题按严重性severity排序为2 项 High、2 项 Medium、1 项 Low。下面逐条展开并在每条末尾结合当前源码给出现状核对这是本篇文章相对评审文档的增量价值。2.1 【High】不受信任代码以完整解释器权限执行评审发现execute_data_cleaner_code节点直接对 LLM/用户生成代码执行exec且赋予完整解释器权限、操作真实数据。当时没有沙箱、没有超时、没有 allowlist。后果链为Prompt 注入 → 执行任意代码 → 数据外泄或宿主机受损。现状核对已修复当前仓库已经落地了完整的子进程沙箱方案。执行节点 execute_data_cleaner_code 不再使用进程内exec而是调用 run_code_sandboxed_subprocessresult, error run_code_sandboxed_subprocess( code_snippetstate.get(data_cleaner_function), function_namestate.get(data_cleaner_function_name), datastate.get(data_raw), timeout10, memory_limit_mb512, )沙箱实现ai_data_science_team/utils/sandbox.py具备五重防护独立子进程通过subprocess.run([sys.executable, -c, SANDBOX_RUNNER_SCRIPT], ...)在单独进程中执行生成代码与主进程完全隔离父进程通过subprocess.TimeoutExpired捕获超时默认 10 秒危险模块黑名单AST 静态扫描 运行时__import__拦截双重阻断禁止os、sys、subprocess、socket、http、urllib、requests、pathlib、shutil、ssl、ctypes等 18 个模块的导入sandbox.py#L53-L71最小化 builtins显式构造_SAFE_BUILTINS白名单仅保留abs、len、dict、isinstance等纯计算能力并刻意移除open、exec、eval、compilesandbox.py#L95-L134网络阻断通过NoNetSocket子类替换socket.socket并覆写create_connection、getaddrinfo、create_server彻底切断外联sandbox.py#L137-L161资源限制POSIX 下使用resource.setrlimit施加内存上限默认 512 MB与文件描述符上限sandbox.py#L39-L51。这完整覆盖了评审建议第 1 条运行隔离进程 最小 globals/builtins 时间/内存预算 AST 检查的全部要点。2.2 【High】Prompt 载荷膨胀导致 Token 越界评审发现recommend_cleaning_steps与create_data_cleaner_code两个节点的 Prompt 会把df.head(n_samples)、df.describe()、df.info()的结果全量内联进提示词且不做截断、不限制列数。中等规模 DataFrame 就会击穿模型上下文窗口并显著拖慢运行速度。评审文档甚至引用了一类典型报错原文This models maximum context length is 128000 tokens. However, your messages resulted in 333858 tokens. Please reduce the length of the messages.该报错在 make_data_cleaning_agent 的n_samples参数文档中被保留为对使用者的提示说明token 越界是该 Agent 真实踩过的坑。现状核对已修复当前源码新增了专门的摘要收敛函数 _summarize_df_for_prompt从四个维度压缩 Prompt 载荷def _summarize_df_for_prompt(df: pd.DataFrame) - str: df_limited df.iloc[:, :MAX_SUMMARY_COLUMNS] if df.shape[1] MAX_SUMMARY_COLUMNS else df summary \n\n.join( get_dataframe_summary( [df_limited], n_samplemin(n_samples, 5), skip_statsTrue, ) ) # Truncate to avoid token bloat MAX_CHARS 5000 return summary[:MAX_CHARS]列数上限MAX_SUMMARY_COLUMNS 30宽表自动截断到前 30 列模块级与函数内双重定义于 data_cleaning_agent.py#L47-L50行数收紧n_samplemin(n_samples, 5)即使调用方传入较大n_samples注入 Prompt 的预览行数也被压到不超过 5 行跳过统计段skip_statsTrue直接省略df.describe()与df.info()这两大体积来源字符兜底最终summary[:5000]强制字符截断确保极端情况下也不至于击穿上下文。至于摘要本身的内容构成可参考 ai_data_science_team/tools/dataframe.py#L84-L150 的_summarize_dataframeskip_statsTrue时仅保留数据集名、Shape、列数据类型与前 N 行预览全部为 Token 友好的轻量信息。2.3 【Medium】Bypass 路径向 LLM 注入 Recommended Steps: None评审发现当bypass_recommended_stepsTrue时create_data_cleaner_code节点仍从 state 渲染{recommended_steps}由于该分支跳过了推荐步骤节点state 中此字段为空最终 Prompt 中出现 Recommended Steps: None。这种歧义输入往往诱导 LLM 产出劣质代码正确做法应回退到默认清洗步骤。现状核对已修复当前实现已加入两级回退data_cleaning_agent.py#L606-L616if bypass_recommended_steps: all_datasets_summary_str _summarize_df_for_prompt(df) steps_for_prompt DEFAULT_CLEANING_STEPS else: all_datasets_summary_str state.get(all_datasets_summary) steps_for_prompt state.get(recommended_steps) or DEFAULT_CLEANING_STEPSbypass_recommended_stepsTrue时直接注入常量DEFAULT_CLEANING_STEPS定义于 data_cleaning_agent.py#L462-L472即文档化的六步默认清洗流程非 bypass 但recommended_steps缺失如从 checkpointer 恢复状态时or DEFAULT_CLEANING_STEPS同样兜底杜绝None进入 Prompt。同时 create_coding_agent_graph 也保证bypass_recommended_stepsTrue时根本不会向图中添加recommend_cleaning_steps节点入口直接设为create_data_cleaner_codeagent_templates.py#L378-L384从图结构上杜绝了该节点的空态污染。2.4 【Medium】Wrapper 方法丢弃结果并绕过 BaseAgent 清理逻辑评审发现invoke_agent/ainvoke_agent直接调用编译图返回None且绕过了BaseAgent.invoke/ainvoke的重复消息清理逻辑remove_consecutive_duplicates。期望拿到响应的调用方会得到None消息归一化也被跳过。现状核对部分修复返回值行为需注意当前 invoke_agent 与ainvoke_agent已改为委托self.invoke/self.ainvokeself.response self.invoke( { messages: [(user, user_instructions)] if user_instructions else [], user_instructions: user_instructions, data_raw: data_raw.to_dict(), max_retries: max_retries, retry_count: retry_count, }, **kwargs, ) return Noneself.invoke走的是 BaseAgent.invoke内部会调用remove_consecutive_duplicates清理连续重复消息——评审指出的消息去重被跳过问题已解决。但方法仍然显式return None评审建议的第 4 条让调用方收到结果在返回值层面尚未完全落实。因此调用方必须通过agent.response或get_data_cleaned()等 getter 取结果而不能依赖方法返回值。这一点在阅读本文后请务必注意。另外invoke_messages /ainvoke_messages提供了面向 Supervisor 团队编排的入口同样基于self.invoke并通过 utils/messages.py 的get_last_user_message_content从消息列表自动推断user_instructions。2.5 【Low】日志路径默认值绑定os.getcwd()评审发现模块导入期即计算的LOG_PATH os.path.join(os.getcwd(), logs/)在作为库被引用时可能写入非预期甚至不可写的目录导致日志静默失败令使用者困惑。现状核对未完全修复当前源码 data_cleaning_agent.py#L46 依然是导入期绑定 cwd 的写法LOG_PATH os.path.join(os.getcwd(), logs/)make_data_cleaning_agent中当logTrue且调用方未显式传log_path时仍会回落到该值data_cleaning_agent.py#L499-L504。评审建议的第 5 条改用项目相对路径、要求显式路径或回退到临时目录目前尚未落地。规避方式生产环境请始终显式传入log_pathoverwriteFalse时 logging.py 的 log_ai_function 会自动生成data_cleaner_1.py、data_cleaner_2.py这类递增文件名避免覆盖历史产物。三、评审建议与源码落地情况对照表#评审建议Recommended Fixes当前源码落地情况证据位置1隔离进程 最小 globals/builtins 时间/内存预算 AST 危险检查✅ 已落地sandbox.py 全文data_cleaning_agent.py#L718-L7882限制摘要列/行数、截断、暴露 skip_stats/max_columns 开关✅ 已落地MAX_SUMMARY_COLUMNS30、min(n_samples,5)、skip_statsTrue、MAX_CHARS5000data_cleaning_agent.py#L474-L4853bypass 且 recommended_steps 缺失时注入默认清洗步骤✅ 已落地DEFAULT_CLEANING_STEPS双重回退data_cleaning_agent.py#L606-L6164invoke_agent/ainvoke_agent 委托 self.invoke/ainvoke 以返回结果并去重 部分落地已委托并去重但方法仍return None需经self.response/getter 取结果data_cleaning_agent.py#L190-L2345log_path 默认改为项目相对路径或要求显式传入❌ 尚未落地仍绑定os.getcwd()data_cleaning_agent.py#L46四、评审建议的专项测试补充方案评审文档的 Next Steps 明确要求为以下行为补充定向测试这些测试点同样可以成为你在自己项目中验收同类 Agent 的检查清单宽表 Prompt 截断测试构造列数超过 30、行数远超 5 的 DataFrame断言注入 LLM 的all_datasets_summary长度被约束对应修复 2bypass 回退测试bypass_recommended_stepsTrue时断言steps_for_prompt DEFAULT_CLEANING_STEPS且 LLM Prompt 中绝不出现 None对应修复 3invoke/ainvoke 返回值测试验证invoke_agent后self.response非空、消息去重生效同时明确记录方法本身返回None的既有行为契约对应修复 4沙箱冒烟测试验证危险 import 被ImportError拒绝、网络连接抛RuntimeError、超时返回错误元组对应修复 1并可复用 sandbox.py#L53-L71 的BLOCKED_MODULES作为断言数据源。五、基于源码的推荐修复优先级评审文档给出的落地顺序为1执行安全 →2Prompt 截断 →3bypass 回退 →4wrapper 返回行为 →5日志路径默认值。结合当前仓库现状剩余工作主要集中在第 4、5 项第 4 项如希望invoke_agent像普通方法一样返回响应需将return None改为return self.response并同步更新依赖返回值的调用方如 multiagents/supervisor_ds_team.py、apps/ai-pipeline-studio-app/app.py 中的调用模式需先确认第 5 项将LOG_PATH改为惰性计算如首次写日志时基于显式参数解析或当log_path is None且 cwd 不可写时回退到tempfile.gettempdir()。此外图编排层面还应注意 agent_templates.py#L392-L399 的error_and_can_retry条件路由仅当error_key非空且retry_count max_retries时才进入fix_code节点否则无 HITL 时直接进入report_agent_outputs或 END——这是LLM 生成代码失败后自动修复重试机制的判定核心。六、实战在 ai-data-science-team 中使用 DataCleaningAgent仓库示例 examples/data_cleaning_agent.ipynb 演示了完整使用流程。核心用法摘自 data_cleaning_agent.py#L127-L152 的 docstringimport pandas as pd from langchain_openai import ChatOpenAI from ai_data_science_team.agents import DataCleaningAgent llm ChatOpenAI(modelgpt-4o-mini) data_cleaning_agent DataCleaningAgent( modelllm, n_samples50, logTrue, log_pathlogs, human_in_the_loopTrue ) df pd.read_csv(data/churn_data.csv) data_cleaning_agent.invoke_agent( user_instructionsDont remove outliers when cleaning the data., data_rawdf, max_retries3, retry_count0 ) cleaned_data data_cleaning_agent.get_data_cleaned() # 通过 getter 取清洗结果 response data_cleaning_agent.response # 或直接读 response 属性参数速查默认值均取自源码签名 data_cleaning_agent.py#L160-L173参数默认值作用与注意事项n_samples30数据集摘要采样行数token 越界时调小实际注入 Prompt 的行数被钳制在min(n_samples, 5)log/log_pathFalse/None是否落盘生成代码与错误日志建议始终显式传log_path规避 cwd 绑定问题file_name/function_namedata_cleaner.py/data_cleaner生成代码的文件名与函数名overwriteTrueFalse时自动生成递增文件名避免覆盖human_in_the_loopFalse开启后需 checkpointer自动回退MemorySaver()并要求bypass_recommended_steps强制为Falsedata_cleaning_agent.py#L487-L497bypass_recommended_stepsFalse跳过 LLM 推荐步骤改用DEFAULT_CLEANING_STEPSbypass_explain_codeFalse跳过最终报告节点执行成功即结束max_retries/retry_count3/0驱动fix_data_cleaner_code自动修复的重试上限与当前计数运行时若生成代码报错错误会写入data_cleaner_error与data_cleaner_error_log_path由 logging.py 的 log_ai_error 追加写入file_name_errors.log并在report_agent_outputs节点中随recommended_steps、data_cleaner_function、data_cleaning_summary等一并序列化到最终messagesdata_cleaning_agent.py#L818-L833。七、结论与后续步骤以评审文档为镜ai-data-science-team 的 Data Cleaning Agent 已从直接execLLM 生成代码演进为子进程沙箱 受限 builtins 网络阻断 资源配额的多层防御体系Prompt 载荷也完成了列数、行数、统计段与字符数的四重收敛bypass_recommended_steps的None注入问题同样被默认步骤兜底消除。剩余待办集中于两点invoke_agent系列方法的返回值契约当前为None依赖self.response取数以及LOG_PATH对os.getcwd()的隐式依赖。对任何构建LLM 生成代码并自动执行类功能的团队而言这份评审清单执行隔离 → 载荷收敛 → 空值兜底 → 返回值契约 → 路径显式化本身就是一份可复用的上线前安全 Checklist——这正是 planning_docs/package_review_initial_release/data_cleaning_agent_review.md 留给我们的最大价值。【免费下载链接】ai-data-science-teamAn AI-powered data science team of agents to help you perform common data science tasks 10X faster.项目地址: https://gitcode.com/GitHub_Trending/ai/ai-data-science-team创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表