如果你最近在关注 AI 编程工具,大概率会看到两个高频词同时出现:DeepSeek 和 Codex。一个是参数规模大、API 成本低的开源大模型,一个是 OpenAI 推出的命令行 Agent 编程工具。把它们放在一起,很多人第一反应是“这不就是用国产模型跑 Codex 吗”。但真正把这条路走通之后,你会发现这件事的价值远不止“换个模型省钱”。
这篇实战文章,我会用完整过程拆解一个具体项目:如何基于 DeepSeek 接入 Codex,通过多轮提示词驱动一个数据分析 Agent 的开发,最终交付一个支持 300 万行数据量级、报告可追溯、结果可复盘迭代的工程化项目。整个过程中,我会把环境配置、模型接入、提示词推进、代码实现、验证排错串成一条完整链路。读完你不仅能复现这个项目,更能把“AI 辅助开发”从聊天式体验,升级成真正能写进简历的工程化能力。
先说一个核心判断:Codex 与 DeepSeek 的组合,改变的不是“谁在写代码”,而是“代码怎么被组织、验证和交付”。相比直接在网页对话框里让 AI 生成一段代码,这种模式把 LLM 从“问答工具”变成了“工作区里的开发协作者”。它真正降低的是数据分析项目的交付成本——从需求澄清、代码生成、数据实验,到报告产出和版本沉淀,都可以在同一个 Agent 工作流中完成。
1. 这篇文章真正要解决的问题
数据分析项目里,真正耗时的是什么?不是写统计代码本身,而是几个容易被人忽略的环节:
第一,环境与数据管线反复调试。拿到一份几百万行的 CSV,第一步不是跑模型,而是搞清字段含义、数据类型、缺失值分布、内存占用。这些工作琐碎,但一步做错,后面全错。
第二,分析报告不可复现。很多人做数据分析是“临时写脚本、临时出图、临时截图”,结果过两周有人问“这个数怎么来的”,回答不上来。没有数据指纹、没有参数记录、没有版本管理,就没法追溯。
第三,需求总是多轮的。业务方看完第一版报告会说“这个维度不对”“我要换一个口径”“能不能再按区域拆一下”。如果你的分析代码是硬编码的脚本,每一轮需求变更都意味着重写一遍。
这些问题恰恰是 Agent 化开发能解决的。用 DeepSeek 接入 Codex 做数据分析 Agent,核心并不是让 AI 自动写一个groupby或pivot_table,而是通过多轮提示词,把一个临时性的数据分析需求,变成可维护、可追踪、可迭代的工程产物。
什么样的读者最应该关注这条链路?
- 你正在用 AI 编程助手,但总觉得生成代码碎片化、没法沉淀成项目;
- 你负责数据分析和报表开发,需要频繁响应业务方的新口径、新维度;
- 你在准备简历项目,希望把“AI 编程”“Agent 开发”“数据分析工程化”作为可描述的硬技能。
这篇文章要解决的问题就是:把这三类需求,用一条可复现的技术路径打通。
2. DeepSeek 与 Codex:为什么把这两个放在一起
先用最通俗的方式解释一下这两个东西。
DeepSeek 是一个大语言模型,可以通过 API 被外部应用调用。它最大的吸引力在于开放性和性价比:你不需要自己部署大模型,只需要在代码里调用 API,就能获得生成代码、处理文本、分析逻辑的能力。在数据分析场景里,它的用途是理解人的意图,生成和修改 Python 代码,以及生成分析报告文本。
Codex 是 OpenAI 出的命令行 Agent 编程工具。它和普通“AI 对话”的区别是,它能直接操作你的项目工作区:读取目录文件、修改代码、执行命令、查看运行结果,然后根据结果继续修改。它本质上是一个“跑在终端里的 AI 开发代理”。
为什么会有人把 DeepSeek 接入 Codex?
原因很简单:Codex 支持通过配置模型提供商(Model Provider)来替换默认模型。你把 Codex 的模型配置指向 DeepSeek 的 API,Codex 负责“干活”——读文件、改代码、跑测试,DeepSeek 负责“思考”——生成代码片段、解释报错、设计实现方案。
用一个对比例子会更容易理解:
| 维度 | 传统数据分析脚本 | Agent 化数据分析 |
|---|---|---|
| 需求变更 | 手动改代码、重跑脚本 | 多轮对话调整,Agent 改代码后自动验证 |
| 数据血缘 | 依赖个人记忆 | 每次运行记录数据指纹、参数、结果 |
| 报告生成 | 手动整理结果、写文档 | 自动生成 Markdown 报告并归档 |
| 结果可追溯 | 弱,难以复现 | 强,每次运行有元数据记录 |
| 进入门槛 | 需要完整数据分析技术栈 | 仍需数据分析基础,但复杂度大幅降低 |
这个组合的真正价值在工程流程层,而不是“模型跑分”。Codex 让 AI 不再是“只给建议的旁观者”,DeepSeek 让这种 Agent 能力能以极低价格接入国内开发者工作流。两个工具合在一起,AI 从“回答问题”变成了“在你的项目里干活”。
当然,这里必须提醒一个容易混淆的点:Codex 是 OpenAI 的产品,DeepSeek 是第三方模型服务,两者通过标准 API 协议对接。这种对接不是 OpenAI 官方提供的默认能力,而是通过配置文件指定的自定义 Provider。所以版本兼容性、模型可用性都需要以实际环境为准。
3. 环境准备与安装配置
下面进入实操环节。整个环境准备围绕三个目标:装好 Codex CLI、配置 DeepSeek API、验证模型可以正常调用。
3.1 安装 Node.js 环境
Codex CLI 是一个 npm 包,所以需要 Node.js 环境。版本请以实际项目安装要求为准,本文重点演示通用思路。安装完成后用node -v验证。如果还没有安装 Node.js,去官网下载 LTS 版本安装即可,Windows、macOS、Linux 都可以。
3.2 安装 Codex CLI
打开终端,执行全局安装:
npm install -g @openai/codex安装完成后,验证命令是否可用:
codex --version这一步虽然不是最复杂的一步,却是很多人第一次卡住的地方。如果你在终端执行codex提示“command not found”,大概率是全局 npm 包的 bin 目录没有加入 PATH。可以运行npm prefix -g查看全局目录,然后把它下面的 bin 目录加入系统 PATH。
从最近社区反馈看,有一个非常典型的问题:
unable to locate the codex cli binary. set codex cli path or ensure the elec...这个报错通常出现在图形界面工具尝试调用 Codex CLI 时。解决办法是确认 CLI 已安装,并确认调用方能够从 PATH 中找到codex可执行文件。如果你在终端已经能跑codex --version,而某个桌面工具仍然报这个错,就去该工具的设置里手动指定 codex 可执行文件的路径。
3.3 配置 DeepSeek API Key
去 DeepSeek 开放平台注册账号,创建 API Key。然后在系统环境变量里配置:
export DEEPSEEK_API_KEY="你的密钥"注意,这只是一次性环境变量配置,终端关闭后失效。建议写入 shell 配置文件(.bashrc、.zshrc或 Windows 环境变量),让配置持久化。
3.4 配置 Codex 使用 DeepSeek 模型
Codex 的配置文件通常位于~/.codex/config.toml。打开或创建这个文件,添加以下配置:
model = "deepseek-chat" model_provider = "deepseek" [model_providers.deepseek] name = "DeepSeek" base_url = "https://api.deepseek.com/v1" env_key = "DEEPSEEK_API_KEY"这里的逻辑是:
model:指定要使用的模型名,deepseek-chat是 DeepSeek 的通用对话模型。model_provider:指定模型中转服务商,这里命名为deepseek。base_url:DeepSeek API 的地址。env_key:服务商读取 API Key 的环境变量名。
配置完成后,运行一个最简单的 Codex 聊天命令验证:
codex "用一句话解释什么是数据分析 Agent"如果能够正常返回结果,说明 Codex 与 DeepSeek 的连接链路已经打通。
如果你的环境里还有 OpenAI 的官方登录状态,建议区分清楚:Codex 默认会尝试使用 OpenAI 账号鉴权,但当你配置了自定义model_provider指向 DeepSeek 时,真正生效的是你配置的env_key。遇到认证冲突时,检查环境变量是否被正确加载,以及配置文件中是否有其他认证配置干扰。
4. 提示词工程:把需求变成 40 轮可推进的开发会话
标题里写着“40 轮提示词”,很多人会觉得这是“狂聊 40 句话才把代码写出来”的夸张说法。其实不是。它对应的是 Agent 工作流的真实节奏:一个复杂项目不可能靠一次性提示词生成全部代码,而是靠多轮对话逐步收敛。
这部分是整篇文章方法论含量最高的部分。
4.1 为什么不能一次生成全部代码
数据分析 Agent 和“生成一个冒泡排序函数”完全不同。它涉及数据加载、内存优化、统计逻辑、报告生成、审计记录、异常处理等多个模块。如果你把全项目一次性丢给大模型生成,结果通常是一个“看起来完整但跑不起来”的大杂烩。
问题出在三个地方:
- 上下文窗口有限,模型不能同时精确处理所有模块的细节;
- 生成代码后必须在真实数据上验证,错误需要定位到具体模块;
- 需求会在开发过程中逐步明确,多轮对话本身就是需求澄清的过程。
4.2 40 轮对话的推进节奏
所谓“多轮提示词”,不是每一轮都让模型“再写点东西”,而是每一轮都让 Agent 在项目里做一次具体的开发动作。下面是真实项目中常见的推进节奏:
第一类:项目初始化轮
这一轮的目标是确定项目结构和依赖清单。
提示词示例:
帮我在当前目录创建一个数据分析 Agent 项目,要求: 1. 使用 Python,使用 pandas 处理数据; 2. 项目结构包含 src、data、outputs、config 四个目录; 3. 依赖写入 requirements.txt; 4. 每个模块用单独文件实现,方便后续修改。Codex 会读取当前工作区,创建目录和基础文件。这是整个项目的地基。
第二类:数据理解轮
项目结构建立后,你需要让 Agent 先理解数据。
提示词示例:
请写一个脚本读取 data/sales_300w.csv,输出: 1. 总行数和总列数; 2. 每一列的数据类型; 3. 每一列的缺失值数量; 4. 内存占用估算。 不要做任何清洗,先给我数据全貌。这轮的目的是让 Agent 基于真实数据写代码,也为后续分析做准备。你会发现,它生成的代码可能不是最优的,但它能让你看到数据基本情况,下一步的提示才更有针对性。
第三类:功能模块实现轮
数据情况清楚后,开始实现核心分析模块。
提示词示例:
实现 src/analyzer.py,要求: 1. 支持按“城市”“品类”“时间”三个维度做聚合统计; 2. 统计指标包括总销售额、订单数、客单价、同比变化; 3. 输出结果为 pandas DataFrame,不要直接打印; 4. 在 main.py 中调用并演示一个小数据集的运行结果。这一类提示词的特点是范围精确、验收标准明确。Codex 完成的代码可以直接跑,跑失败则把报错信息继续丢给 Agent 修改。
第四类:验证与修复轮
这一轮实际上是“多轮”里最常见的循环:运行代码、报错、把错误丢回给 Agent 修改、继续运行。
提示词示例:
运行 main.py 时出现以下错误: KeyError: 'category' 请检查数据列名,找出实际列名,修改代码后重新运行。这种提示词不需要你懂具体原因,只需要如实把报错粘贴给 Agent。Codex 的核心能力之一就是定位报错并修改代码。
第五类:报告与交付轮
功能跑通后,让 Agent 生成可交付报告。
提示词示例:
写一个函数,把分析结果渲染成 Markdown 报告,要求: 1. 包含摘要、图表、结论三部分; 2. 报告中注明本次分析使用的数据文件、运行时间、版本; 3. 报告保存到 outputs/reports/; 4. 每次运行生成新的版本,不要覆盖旧报告。到这里,40 轮不是“聊了 40 句废话”,而是 40 个“需求确认 → 代码生成 → 运行验证 → 修复迭代”的循环。每一轮都让项目往前推进了一步。
4.3 提示词设计的核心原则
经过这个项目,我总结出几个提示词工程原则,直接分享给你:
原则一:每一轮只改一个点。不要在一轮提示里同时要求“增加新功能 + 重构代码 + 写测试”。Agent 不是不能做,但一旦出错,你很难判断是哪部分逻辑的问题。
原则二:先跑通最小链路,再叠加复杂逻辑。比如先让 Agent 用 1 万行数据跑通分析流程,再切到 300 万行数据压测。这样定位问题更快,也避免一上来就因为性能问题误判模型能力。
原则三:贴报错原文,胜过自己翻译。很多开发者习惯把报错“用自己的话”先总结一遍再问 AI,这样做反而丢失了关键信息。直接粘贴完整报错,Agent 的定位准确率会更高。
原则四:把约定写进提示词。比如“生成代码时加上类型标注”“关键函数写 docstring”“文件读写用 utf-8 编码”。这类约定虽然琐碎,但对后期维护至关重要。
5. 完整示例:一个可追溯、可迭代的数据分析 Agent
下面给出一个可直接复制的最小完整示例。这个示例体现了三个关键设计:调用 DeepSeek 生成分析逻辑、记录数据指纹保证可追溯、报告按版本迭代不覆盖。
5.1 项目结构
data-analysis-agent/ ├── config.yaml # 配置文件 ├── requirements.txt # 项目依赖 ├── main.py # 主程序 ├── src/ │ ├── __init__.py │ ├── llm_client.py # DeepSeek API 调用封装 │ ├── audit.py # 数据指纹与版本记录 │ └── analyzer.py # 数据统计分析 └── outputs/ └── reports/ # 报告输出目录5.2 依赖文件
文件路径:requirements.txt
pandas pyyaml openai5.3 配置文件
文件路径:config.yaml
model: provider: deepseek name: deepseek-chat base_url: https://api.deepseek.com/v1 api_key_env: DEEPSEEK_API_KEY temperature: 0.2 data: file_path: data/sales_300w.csv encoding: utf-8 report: output_dir: outputs/reports description: "数据分析 Agent 自动生成的报告"这里需要注意的是,base_url里的地址是 DeepSeek API 的通用入口,实际接入时请以 DeepSeek 开放平台当前文档为准。如果 API 版本升级、路径有变化,优先根据官方文档调整。
5.4 DeepSeek 客户端封装
文件路径:src/llm_client.py
import os import yaml from openai import OpenAI def load_config(config_path="config.yaml"): with open(config_path, "r", encoding="utf-8") as f: return yaml.safe_load(f) def create_llm_client(config): api_key = os.getenv(config["model"]["api_key_env"]) if not api_key: raise ValueError("请先设置 DEEPSEEK_API_KEY 环境变量") return OpenAI( api_key=api_key, base_url=config["model"]["base_url"], ) def generate_analysis_prompt(describe_text: str, aggregate_result: str) -> str: """把数据全貌和分析结果组装成给 LLM 的提示词""" prompt = f""" 你是一名资深数据分析师。请基于以下数据描述和聚合统计结果,生成一份简要的数据分析结论。 数据描述: {describe_text} 聚合统计结果: {aggregate_result} 请输出: 1. 数据整体情况概述; 2. 核心业务结论(不超过 5 条); 3. 潜在风险和异常点; 4. 下一步分析建议。 注意:请使用 Markdown 格式输出,结论要具体、可执行。 """ return prompt def generate_report(client, config, describe_text: str, aggregate_result: str) -> str: response = client.chat.completions.create( model=config["model"]["name"], temperature=config["model"]["temperature"], messages=[ {"role": "system", "content": "你是一名严谨的数据分析专家,只输出结论和可执行建议,不输出无关内容。"}, {"role": "user", "content": generate_analysis_prompt(describe_text, aggregate_result)}, ], ) return response.choices[0].message.content这段代码的核心是把 DeepSeek API 调用封装成一个函数,外部只需要传入数据描述和聚合结果,就能得到一份 Markdown 格式的分析报告。api_key_env的设计意味着密钥不落盘,只在环境变量中读取,更安全。
5.5 审计与可追溯模块
文件路径:src/audit.py
import hashlib import json import time import uuid def compute_file_hash(file_path: str, chunk_size: int = 1024 * 1024) -> str: """计算文件 SHA-256,作为数据指纹""" sha256 = hashlib.sha256() with open(file_path, "rb") as f: while True: chunk = f.read(chunk_size) if not chunk: break sha256.update(chunk) return sha256.hexdigest() def create_run_metadata(data_file: str, file_hash: str, config: dict) -> dict: """生成一次运行的元数据""" return { "run_id": uuid.uuid4().hex, "timestamp": time.strftime("%Y-%m-%d %H:%M:%S"), "data_file": data_file, "data_hash": file_hash, "model": config["model"]["name"], "temperature": config["model"]["temperature"], } def save_report_with_metadata(report_content: str, metadata: dict, output_dir: str) -> str: """保存报告和元数据,返回报告文件路径""" import os os.makedirs(output_dir, exist_ok=True) report_path = os.path.join(output_dir, f"report_{metadata['run_id']}.md") meta_path = os.path.join(output_dir, f"report_{metadata['run_id']}.meta.json") with open(report_path, "w", encoding="utf-8") as f: f.write(report_content) with open(meta_path, "w", encoding="utf-8") as f: json.dump(metadata, f, ensure_ascii=False, indent=2) return report_path这个模块是整个项目“可追溯”的关键。每次运行都会计算输入数据文件的 SHA-256 指纹,并把运行时间、模型名、参数、数据文件路径一起写入.meta.json。以后无论什么时候,只要你拿到这份元数据,就能知道“这份报告是在什么时间、用什么模型、基于哪个数据文件生成的”。如果数据文件发生了变化,指纹也会变化,一眼就能看出旧报告已经不能反映当前数据。
5.6 主程序
文件路径:main.py
import os import pandas as pd from src.audit import compute_file_hash, create_run_metadata, save_report_with_metadata from src.llm_client import create_llm_client, load_config, generate_report def load_data(file_path: str, nrows: int | None = None) -> pd.DataFrame: """加载数据。nrows 用于小数据量测试,正式跑请传 None""" df = pd.read_csv(file_path, encoding="utf-8", nrows=nrows) return df def build_describe_text(df: pd.DataFrame) -> str: """生成数据描述文本,供 LLM 理解数据全貌""" lines = [] lines.append(f"数据集共 {df.shape[0]} 行,{df.shape[1]} 列。") for col in df.columns: dtype = df[col].dtype null_count = int(df[col].isna().sum()) lines.append(f"- 字段 {col}:类型 {dtype},缺失值 {null_count} 个") return "\n".join(lines) def build_aggregate_result(df: pd.DataFrame) -> str: """简单聚合统计,实际项目里请替换成更贴合业务的分析逻辑""" numeric_cols = df.select_dtypes(include="number").columns.tolist() if not numeric_cols: return "没有可用的数值列,无法进行数值聚合。" describe = df[numeric_cols].describe().to_string() return describe def main(): config = load_config() data_path = config["data"]["file_path"] # 小数据量验证时,可以设置 nrows=10000;正式跑全量请传 None df = load_data(data_path, nrows=None) describe_text = build_describe_text(df) aggregate_result = build_aggregate_result(df) client = create_llm_client(config) report_content = generate_report(client, config, describe_text, aggregate_result) file_hash = compute_file_hash(data_path) metadata = create_run_metadata(data_path, file_hash, config) report_path = save_report_with_metadata( report_content, metadata, config["report"]["output_dir"], ) print(f"报告已生成:{report_path}") print(f"元数据已生成:{report_path.replace('.md', '.meta.json')}") if __name__ == "__main__": main()整个主程序的流程是:加载数据 → 生成数据全貌 → 计算聚合统计 → 调用 DeepSeek 生成报告 → 记录数据指纹和运行元数据 → 保存报告。每一步都只做一件事,逻辑清楚,方便 Agent 后续按需修改。
5.7 使用 Codex 驱动项目开发
在这个项目里写代码,不需要从零手写所有文件。你可以先建好config.yaml和requirements.txt,然后把main.py的需求描述发给 Codex,让 Agent 生成代码。比如在终端运行:
codex "请根据 config.yaml 和 src 目录下的现有模块,实现 main.py 和 src/analyzer.py。要求:支持 pandas 读取 CSV;读取配置文件;调用 src.llm_client 中的函数;输出报告时使用 src.audit 中的审计模块。"Codex 会读取工作区现有文件结构,生成完整代码。生成后再运行验证,发现问题继续让它修复,就是上面 4.2 节讲的多轮协作节奏。
6. 运行结果与效果验证
运行项目前,确认两件事:第一,DEEPSEEK_API_KEY环境变量已经配置;第二,数据文件路径和config.yaml中的file_path一致。
执行命令:
python main.py如果一切正常,输出大致为:
报告已生成:outputs/reports/report_1a2b3c4d5e6f.md 元数据已生成:outputs/reports/report_1a2b3c4d5e6f.meta.json打开生成的 Markdown 报告,会看到 DeepSeek 根据你提供的聚合统计写出的分析结论。打开同名的.meta.json文件,内容类似:
{ "run_id": "1a2b3c4d5e6f", "timestamp": "2025-01-15 10:30:00", "data_file": "data/sales_300w.csv", "data_hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "model": "deepseek-chat", "temperature": 0.2 }如何判断项目跑通了?有三个标准:
第一,报告内容和数据对得上。你可以在报告里抽查几个聚合数字和build_aggregate_result手动输出的描述是否一致。如果一致,说明 DeepSeek 没有“瞎编”数值,这是使用 LLM 生成报告时最重要的底线。
第二,元数据完整且可复现。拿着data_hash重新计算一次数据文件的 SHA-256,如果一致,说明任何时刻拿到报告和元数据,都能确认它基于哪一份数据产生。
第三,重复运行生成新版本。连续运行两次python main.py,会发现生成了两个不同的报告文件(run_id不同),旧文件不会被覆盖。这就是“报告能迭代”的工程含义。
对于标题中提到的“300 万行”数据量级,有一个务实的验证思路:
- 先用
nrows=10000跑通整个分析流程,确认代码逻辑正确、报告格式正常; - 再改用全量数据运行,观察内存占用和运行时长;
- 如果内存不足,优先检查是否有非必要的中间变量,或者改用分块读取、只读取必要列。
300 万行并不是一个特别大的数据量,但要避免在数据全量加载后,再生成df.copy()一类的冗余副本。用df.info()可以快速确认内存占用情况。
7. 常见问题与排查思路
这一节把所有容易踩的坑集中整理成一张排查表。每一条都是 AI 编程和模型接入场景下的高频问题。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
终端提示codex: command not found | npm 全局 bin 目录未加入 PATH | 执行npm prefix -g查看全局路径 | 把全局 bin 目录加入 PATH,或重新安装 CLI |
桌面工具报unable to locate the codex cli binary | 调用方找不到 codex 可执行文件 | which codex查看实际路径 | 在工具设置里手动指定 codex CLI 路径 |
| Codex 调用 DeepSeek 返回 401 认证失败 | API Key 未设置或设置错误 | 检查echo $DEEPSEEK_API_KEY | 重新配置环境变量,确认密钥无多余空格 |
| 请求返回 404 或 model not supported | 模型名或 base_url 配置错误 | 对照 DeepSeek 开放平台文档确认 | 将model改为当前可用模型名,检查地址正确 |
| 首次运行时本地代理请求失败 | 本地网络代理或网关拦截了 API 请求 | 查看完整报错信息,确认请求是否走了代理 | 清理本节代理配置,直接通过官方 API 入口访问 |
| 数据量大时内存溢出 | 一次性加载过多数据或产生大量副本 | 用df.info()观察内存占用 | 分块读取、减少列、避免复制 DataFrame |
| 生成的报告缺少分析深度 | 给 LLM 的统计结果过于粗略 | 检查aggregate_result内容 | 在提示词补充更多分组、时间趋势、异常值等上下文 |
| 报告里数字与数据不一致 | LLM 输出了幻觉数字 | 对比聚合结果和报告文字 | 在提示词中强调“只能使用给定数据,不要编造”,并增加人工抽查环节 |
有一个值得单独强调的经验:遇到任何报错,先把完整报错信息直接粘贴给 Codex,让 Agent 自己定位。这是 Agent 工作流和传统“遇到问题百度”最大的区别。Codex 能看到项目文件结构,能读取报错对应的代码,很多时候它可以直接给出修改方案并帮你改好。
8. 最佳实践与工程建议
8.1 数据安全边界
数据分析 Agent 一旦接入真实业务数据,就要认真考虑安全边界。尤其是使用第三方模型 API 时,原始数据会以文本形式发送到模型服务端。这里有几个原则:
- 不要在提示词中发送不必要的全量明细数据,只发送聚合统计结果;
- 如果数据包含手机号、身份证号等敏感字段,先脱敏再进入分析流程;
- 生产环境接入时,先走审批流程,明确数据使用范围和合规边界;
- 如果要处理高度敏感的数据,优先考虑私有化部署模型,而不是外部 API。
在本文的最小示例中,传给 DeepSeek 的只有数据描述和聚合结果,而不是原始明细数据,这本身就是一种降低风险的设计。
8.2 提示词与代码一起纳入版本管理
很多人用 AI 编程不会把提示词存下来,每次都是现场重写。这是浪费。建议把每一轮的关键提示词保存到prompts/目录,和代码一起提交到 Git。这样做的好处是:
- 你随时能知道“这个功能当初是怎么跟 AI 说的”;
- 项目迭代时可以复用历史提示词,而不是从零开始;
- 写简历和复盘时,这些提示词就是你的“过程资产”。
8.3 报告迭代要有版本意识
“报告能迭代”不是简单地在旧报告上改,而是每次运行都产生新版本、保留旧版本、记录版本差异。体现在工程上就是:
- 每次运行记录
run_id; - 元数据中包含数据指纹、模型名、时间戳;
- 报告中注明数据日期和生成时间;
- 需要对比时,对比两份报告的
.meta.json就能定位差异原因。
这套做法在企业里叫“数据血缘”的轻量版,不需要额外的数据平台,一个 JSON 文件就能实现。
8.4 成本和速度优化
调用 DeepSeek API 的成本很低,但如果在每个环节都调用一次大模型,累计的 token 量仍然不可忽视。实用建议是:
- 聚合计算用 pandas 完成,不要让模型做精确计算;
- 只把最终统计结果发送给模型,减少对话轮次和 token 消耗;
- 在调试阶段使用小数据集跑通流程,再切换全量数据;
- 如果报告篇幅长,可以分段生成,避免一次输出过长导致截断或成本激增。
8.5 把项目写出简历价值
如果你想把这类项目写进简历,不要只写“使用了 DeepSeek 和 Codex”。更有说服力的写法是:
- 项目目标:构建一个支持 300 万行数据量级的数据分析 Agent,交付可追溯、可迭代的分析报告;
- 技术方案:基于 Codex CLI 的 Agent 工作流,接入 DeepSeek API,通过多轮提示词完成需求拆解、代码生成和验证修复;
- 工程亮点:数据指纹审计、报告版本管理、聚合结果前置计算、敏感数据脱敏;
- 量化结果:相比传统脚本开发,需求迭代无需重写代码;每次运行自动生成报告和元数据,可追溯性显著提升。
这种写法的核心是用工程化语言描述 AI 协作过程,而不是强调“AI 帮我写了代码”。
9. 总结与后续学习方向
这篇文章其实只讲了一件事:把 DeepSeek 和 Codex 组合起来,用 Agent 工作流完成一个数据分析项目的全流程交付。你跟着配置完环境、把提示词跑完、运行了 main.py,应该已经能感受到这种模式和“网页对话框里生成代码”的差别。区别不在于代码写得好不好,而在于整个过程有没有沉淀成项目、有没有验证、有没有记录。
下一步值得深入探索的方向有三个:
第一个方向是提示词工作流的工程化。你现在应该有一批经过验证的提示词,不妨把它们整理成项目里的模板文件,把“需求描述 → 数据理解 → 模块实现 → 验证修复 → 报告交付”这个循环固化下来,下次做类似项目时直接复用。
第二个方向是数据分析能力的扩展。当前示例只做了描述性统计,后续可以加入图表生成、AB 实验分析、异常检测、归因分析等能力。每加一个能力,本质上就是往 Agent 的提示词和代码库中新增一个模块。
第三个方向是Agent 协作流程的优化。40 轮提示词并不是上限,而是数据说明了“真实项目的复杂度需要多轮推进”。你可以尝试把曾经做过的成功提示词整理成策略模板,然后在新的 Codex 会话中复用,观察项目交付效率是否提升。
如果你在配置 Codex 接入 DeepSeek 时遇到问题,排查路径建议按照第三节的顺序:先确认 CLI 可用,再确认密钥有效,最后检查模型配置。把这三个环节跑通了,整个项目的地基就稳了。