Agent 终于会“看”表格了——read_csv 和 read_excel 的故事 Agent 终于会“看”表格了——read_csv 和 read_excel 的故事以前只能“写”现在终于能“读”了一、一个让我很无语的场景前几天我在 REPL 里测试数据分析能力。我手头有一个 CSV 文件大概 2000 多行里面有“ASR 识别文本”和“是否是 POI”两列。我想让 Agent 帮我看看这个文件长什么样。我说“读取一下这个 CSV看看它有多少行有哪些列。”Agent 说好的然后调用了read_file。read_file返回了什么呢一大坨原始的 CSV 文本。2000 多行的内容密密麻麻全是逗号和引号。模型面对这堆东西完全没办法理解——它只能看到一堆文本不知道哪行是表头、哪列是什么含义、有多少行、有多少空值。结果 Agent 含糊地说“这个文件看起来有一些数据……”就这我当时的内心 OS你倒是跟我说说有几行几列啊后来我才意识到这不是模型的问题——是我的工具设计有问题。二、先解释一个概念什么是“数据预览”概念解释数据预览Dataset Preview不是把整个文件的内容都倒出来而是先看一眼它的“骨架”这个表格有几行几列列名叫什么每列是什么类型的数据数字、文字、日期有没有空值前几行长什么样就像你拿到一本厚厚的书不会从第一页开始读——你会先看目录、看摘要、看第一章的前几段判断这本书值不值得读。数据预览就是这个道理先看一眼“骨架”再决定怎么用。如果模型能先拿到这些信息它就能做出更好的判断“哦这个表有 2473 行两列ASR识别文本有 12 个空值”——那它就知道数据质量还可以可以继续分析。“哦这个表有 10 万行”——那它就知道不能用read_file全量读取得用采样或聚合方式处理。—三、为什么之前没有这个能力回顾一下我当时手上的工具写侧已经有工具能力write_csv写入 CSVcreate_excel创建 Excel读侧之前没有工具能力读取 CSV / Excel 的结构化信息我只能“写”表格不能“读”表格。这就很尴尬了——Agent 可以生成一个 Excel 给你但它打不开你发给它的 Excel。就像一个作家只会写书、不会读书。四、解决方案read_csv和read_excel今天新增了两个工具工具作用read_csv读取 CSV 文件返回结构化预览read_excel读取 Excel 文件返回结构化预览4.1 具体返回什么当 Agent 调用read_csv或read_excel时返回的不是原始文本而是一个结构化预览{path:data/sample.csv,format:csv,rows:2473,columns:[ASR识别文本,是否是POI],dtypes:{ASR识别文本:string,是否是POI:string},nullCounts:{ASR识别文本:12,是否是POI:0},sample:[{ASR识别文本:今天天气不错,是否是POI:},{ASR识别文本:去天安门广场,是否是POI:是}],sheets:[Sheet1],sheet:Sheet1,scannedRows:2473,bytes:128400}模型拿到了这些信息就可以很准确地告诉用户“这个 CSV 有 2473 行、2 列。”“列名是ASR识别文本和是否是POI。”“ASR识别文本列有 12 个空值需要注意。”“前两行数据是……展示样例”4.2 两个关键参数为了让模型能灵活控制预览的“深度”我添加了两个参数参数说明默认sample_size返回多少行样例10最多 50scan_rows扫描多少行做统计5000也就是说即使一个文件有 100 万行read_csv也不会全量加载——它只扫描前 5000 行来推断列类型和空值统计然后返回 10 行样例。控制 token 消耗避免撑爆上下文。4.3 环境变量调优READ_DATA_MAX_BYTES15000000 # 最大读取大小15MB READ_DATA_SAMPLE_SIZE10 # 默认样例行数 READ_DATA_SCAN_ROWS5000 # 统计扫描行数五、对比以前 vs. 现在场景用户说“帮我看看这个 CSV”之前用read_fileAgent: 调用了 read_file(data.csv) read_file: 返回 2000 行原始 CSV 文本全是逗号和引号 Agent: “这个文件有一些数据……”含糊其辞 用户: 现在用read_csvAgent: 调用了 read_csv(data.csv) read_csv: 返回结构化预览行数、列名、类型、空值、样例 Agent: “这个 CSV 有 2473 行、2 列。列名是 ASR识别文本 和 是否是POI。ASR识别文本 有 12 个空值建议先处理空值再分析。” 用户: 清晰、有用同一个文件不同的工具天壤之别。六、为什么这样设计—— 三点思考6.1 专用工具 通用工具read_file是“万能”的——什么文件都能读但什么都不精。read_csv和read_excel是“专用”的——它们只做一件事但做得好。这让我想起一个设计原则通用工具解决“能不能做”的问题专用工具解决“做得好不好”的问题。给 Agent 一堆万能工具它能做很多事但每件事都做得一般。给它一堆专用工具它才能在特定领域做得专业。6.2 预览 全量加载以前我总觉得“要分析数据就得把全部数据给模型”。但这是错的——模型不是数据库它的优势是“理解”和“推理”不是“存储”和“检索”。正确的做法是先预览骨架再按需读取细节。就像数据分析师拿到一个数据集不会先看全部数据——他会先head()看看前几行info()看看列类型describe()看看统计分布。read_csv和read_excel做的就是这个事。6.3 读侧补全写侧形成闭环写侧write_csv→ 创建 CSV写侧create_excel→ 创建 Excel读侧read_csv→ 读取 CSV读侧read_excel→ 读取 Excel现在 Agent 终于有了完整的数据操作闭环能写、能读、能分析。七、和之前的功能怎么配合功能作用和 read_csv/excel 的关系write_csv/create_excel写数据读侧和写侧对称形成闭环TaskStateTracker检查子任务完成度read_csv可以作为“验证”子任务的完成条件ContextCompressor压缩上下文read_csv返回的是预览小体积天然友好IntentPlanner拆子任务数据分析场景下会优先推荐read_csv/read_excel举个例子用户说“分析这个 Excel 的数据质量”。IntentPlanner 拆出子任务读取 Excel 预览 →read_excel检查空值占比 → 从nullCounts中读取总结数据质量 → 模型推理TaskStateTracker 确保每一步都完成才会允许 final_answer。环环相扣。