DeepSeek接入Codex CLI:40轮提示词迭代构建300万行数据分析Agent
用 DeepSeek 接入 Codex CLI,通过 40 轮提示词迭代,搭建一个能处理 300 万行数据的分析 Agent,这件事拆开看并不神秘。关键是把它拆成四条主线:模型接入、提示词迭代、数据血缘、报告版本管理。Codex CLI 负责承载多轮对话和代码执行,DeepSeek 提供底层模型能力,分析 Agent 最终会变成一套能加载原始数据、执行清洗聚合、记录每一步变化、并生成可追查报告的工程化程序。本文会从环境配置开始,最终落到“项目能写进简历”的交付标准。
标题里的 DeepSeek V4,在实际代码中对应开放平台上的具体模型 ID。不同阶段模型 ID 会变化,下面示例统一使用
deepseek-chat
、
deepseek-reasoner
作为占位,落地时以 DeepSeek 开放平台文档为准。Codex CLI 这边,不同版本配置字段也有差异,我会标注“以当前安装版本为准”,避免照搬配置后踩版本坑。
1. 先理清 Codex、DeepSeek、Agent 和 Harness 的关系
1.1 Agent 和 Harness 是两回事
网络上有大量人搜索“harness和agent区别”,说明这两个词很容易被混用。Agent 是一个具备目标、能调用工具、能根据执行结果调整策略的智能体。Harness 是承载 Agent 运行的“壳”,它负责把模型输出变成可执行代码,把执行结果再反馈给模型,形成闭环。可以简单理解为:Harness 是运行环境,Agent 是运行在这个环境里的执行逻辑。
Codex CLI 就是一个典型的 Harness。它不是一个普通的命令行补全工具,而是一个能在终端里自主读取文件、编辑代码、执行命令、看到报错并继续修正的程序。你给他一个任务,它会调用底层模型,生成动作,执行动作,再把结果继续交给模型判断。整个流程就是多轮 Agent 循环。
DeepSeek 在这个结构里承担的是模型层能力。模型决定 Agent 理解任务、生成代码、诊断错误的水平。接入 DeepSeek 后,Codex CLI 的模型通道可以从默认模型切到 DeepSeek 开放平台上的模型,这样既保留了 Codex Harness 的执行能力,又换上了 DeepSeek 的处理逻辑。要注意的是,Codex 对自定义模型的支持方式会在不同版本中变化,社区里常见的做法是把 DeepSeek 的接口地址配置到 Codex 的模型提供方配置中,字段需要以自己安装版本的说明为准。
1.2 40 轮提示词的价值:从能跑到可交付
很多人用 AI 编程工具的习惯是输入一句“写一个数据分析脚本”,拿到代码就结束了。结果项目只能处理小样本,缺少异常处理,没有日志,数据一变就崩。真正可交付的工程,不可能靠一轮对话完成。
40 轮提示词的核心不是数量,而是每一轮都带着明确目标。前几轮定义项目骨架,中间几轮加入数据字典和清洗规则,后面几轮补血缘、报告、性能优化和错误处理。每一轮都把上一轮的运行结果、报错信息、输出差异反馈给模型,让模型在自己的真实执行结果上继续修正。这就是一个标准的 Agent 迭代闭环。
如果把 40 轮理解为一次性列出 40 条需求,那效果会非常差。正确的做法是让需求像软件版本一样逐轮演进:先跑通最小流程,再逐步增加约束,最后收敛到可交付状态。第四部分会展示这种迭代方式的具体组织方法。
2. 环境准备:Codex CLI、DeepSeek API 和 Python 依赖
2.1 安装 Codex CLI 并确认可执行文件在 PATH 中
Codex CLI 是需要在终端里安装的命令行工具。安装后再确认
codex
命令能被找到。很多开发者在 IDE 插件里遇到“unable to locate the codex cli binary. set codex_cli_path or ensure the executable is in your PATH”这类报错,本质就是插件的进程找不到代码里执行的外部命令。
先完成基础安装:
# 使用 npm 安装,注意 Node.js 版本
npm install -g @openai/codex
# 查看版本
codex --version
如果
codex --version
能正常输出版本号,说明命令行本身没问题。IDE 插件仍然报找不到二进制,通常是因为 IDE 启动时的 PATH 环境没有包含全局 npm 目录。解决方式有两种,优先选第一种:
# 查看 codex 安装的绝对路径
which codex
拿到绝对路径后,在 IDE 插件设置里找到
codex_cli_path
或类似字段,填入这个绝对路径。第二类方式是修改 IDE 启动环境的 PATH,让插件能自动发现。开发环境里建议直接用绝对路径,简单可靠,不会因为终端和 IDE 环境差异导致找不到命令。
2.2 配置 DeepSeek 模型接入
DeepSeek 开放平台提供 OpenAI 兼容接口,因此可以按自定义模型提供方的方式接入 Codex CLI。不同版本的 Codex 配置字段有差异,下面给出社区常见做法,作为理解配置结构的示意,落地前先查看自己版本的配置文档。
第一步是设置环境变量:
export DEEPSEEK_API_KEY="sk-这里填你的key"
第二步是修改 Codex 配置。常见入口是
~/.codex/config.toml
,示意配置如下:
# ~/.codex/config.toml
# 字段以当前 Codex 版本为准,这里只展示接入自定义模型的思路
model = "deepseek/deepseek-chat"
model_provider = "deepseek"
如果你的版本支持显式声明模型提供方,可以按这个思路配置:
[model_providers.deepseek]
name = "deepseek"
base_url = "https://api.deepseek.com"
env_key = "DEEPSEEK_API_KEY"
配置常见的问题有两种。一种是
base_url
写错,导致请求发出后接口返回 404 或认证失败。另一种是模型 ID 写错,DeepSeek 开放平台同时提供对话模型和推理模型,使用时要确认当前账号能访问的模型 ID。建议花两分钟调用一次官方接口验证 key 和模型名:
curl https://api.deepseek.com/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $DEEPSEEK_API_KEY" \
-d '{
"model": "deepseek-chat",
"messages": [{"role": "user", "content": "ping"}]
}'
能正常返回
choices
就说明 key、模型名和接口地址都没问题。
2.3 Python 分析与处理依赖
数据量到 300 万行时,处理引擎的选择会影响后续所有代码。Pandas 在行数较少时体验顺畅,但数据量较大、内存有限时,容易遇到内存飙升问题。这个项目选择 DuckDB 作为数据处理引擎,原因是它能直接在 CSV、Parquet 上做列式分析,支持 SQL,内存占用比全量加载到 DataFrame 更可控,而且 Python 集成非常简单。
创建虚拟环境并安装依赖:
python3 -m venv .venv
source .venv/bin/activate
pip install duckdb pandas pyarrow pyyaml jinja2
依赖说明如下:
| 依赖 | 用途 |
|---|---|
| duckdb | 读取 300 万行 CSV、执行 SQL 聚合、导出结果 |
| pandas | 小规模结果集转换与展示 |
| pyarrow | 与 DuckDB 配合读写 Parquet |
| pyyaml | 读取数据字典和配置 |
| jinja2 | 报告模板渲染 |
要求不高时可以只保留 duckdb 和 pyyaml,其他依赖按报告格式需要再补。这个项目的核心原则是:大表计算交给 DuckDB,小结果和展示交给 Python。
3. 分析 Agent 的工程骨架:面向 300 万行数据的模块设计
3.1 为什么 300 万行会重新要求工程结构
300 万行在数据库领域不算大,但在常见脚本处理场景里已经能暴露三类问题:内存、可追溯性、可重复运行。
内存问题最常见。用 Pandas 直接
read_csv
加载全部数据,再反复做分组聚合,内存很容易到几个 GB。换成 DuckDB 后,很多聚合可以直接下推到引擎内部完成,Python 进程只保留最终结果。这样脚本运行环境要求会低很多。
可追溯性问题在数据变大后更明显。处理 300 万行时,中间步骤往往是“读取 -> 清洗 -> 过滤 -> 聚合”。如果脚本跑完只输出一个结果文件,那么原始数据长什么样、到底过滤了哪些行、每一步处理影响了多少数据,全都不可查。项目里必须加血缘记录:记录每一步的输入表、输出表、处理函数、影响行数和结果指纹。
可重复运行问题容易被忽略。数据处理脚本如果写死了本地路径、缺少幂等处理,第二次运行就会因为表已存在、字段重复或数据重复而报错。模块化设计能把这些问题从“脚本报错”变成“有明确检查点”,这也是后续能和 Agent 高效迭代的前提。
3.2 项目结构和数据字典
项目目录需要保持清晰,目录位置建议固定,这样 Codex 反复修改代码时不会找不到文件。示意结构如下:
retail_agent/
├── configs/
│ └── data_dictionary.yaml
├── data/
│ ├── raw/
│ │ └── orders_300w.csv
│ └── processed/
├── reports/
│ ├── versions/
│ └── latest_report.md
├── src/
│ ├── loader.py
│ ├── lineage.py
│ ├── transformer.py
│ ├── report.py
│ └── main.py
├── prompts/
│ └── system.md
└── requirements.txt
configs/data_dictionary.yaml
用来定义字段类型和清洗规则。代码不直接硬编码字段名,而是从字典文件读取。这样模型在生成代码时也能理解数据语义,后续新增字段只需要改配置。
source: data/raw/orders_300w.csv
dtypes:
order_id: string
user_id: string
product_id: string
amount: double
order_time: timestamp
clean_rules:
- drop_duplicates:
subset: [order_id]
- filter:
condition: "amount > 0"
- fill_na:
columns: [user_id]
value: "unknown"
metrics:
- name: total_amount
sql: "SELECT sum(amount) AS total_amount FROM orders"
- name: order_count
sql: "SELECT count(*) AS order_count FROM orders"
prompts/system.md
放给模型看的系统提示词。它的作用不是约束模型遵循某种说话风格,而是说明项目结构、数据字典位置、代码风格和交付标准。第四部分会详细展开提示词写法。
3.3 核心模块:加载、清洗、聚合、血缘
先看加载模块
src/loader.py
。它负责把 CSV 导入 DuckDB,并返回一个指向表的引用。
import duckdb
def load_csv_to_duckdb(con: duckdb.DuckDBPyConnection, source: str, table: str = "orders") -> None:
con.execute(f"CREATE OR REPLACE TABLE {table} AS SELECT * FROM read_csv_auto('{source}')")
row_count = con.execute(f"SELECT count(*) FROM {table}").fetchone()[0]
print(f"[loader] {table} loaded, rows={row_count}")
return row_count
这里用
CREATE OR REPLACE TABLE
是为了保证脚本可重复运行。第二次运行不会因为表已存在而报错,而是直接覆盖当前表,避免重复加载。
清洗和聚合写在
src/transformer.py
。基于数据字典读取规则,然后执行 SQL:
from pathlib import Path
import yaml
import duckdb
def load_rules(config_path: Path):
with open(config_path, "r", encoding="utf-8") as f:
return yaml.safe_load(f)
def apply_clean_rules(con: duckdb.DuckDBPyConnection, rules: dict) -> None:
con.execute("CREATE OR REPLACE TABLE orders_clean AS SELECT * FROM orders")
con.execute("DELETE FROM orders_clean WHERE rowid NOT IN (SELECT min(rowid) FROM orders_clean GROUP BY order_id)")
con.execute("DELETE FROM orders_clean WHERE amount <= 0")
con.execute("UPDATE orders_clean SET user_id = 'unknown' WHERE user_id IS NULL")
def compute_metrics(con: duckdb.DuckDBPyConnection, metrics: list) -> dict:
result = {}
for metric in metrics:
key = metric["name"]
value = con.execute(metric["sql"]).fetchone()[0]
result[key] = value
print(f"[metric] {key}={value}")
return result
血缘模块
src/lineage.py
是“数据可追溯”的关键。每次处理步骤都记录输入输出表、行数变化和关键字段指纹。
import hashlib
from datetime import datetime
class LineageLogger:
def __init__(self):
self.entries = []
def log(self, step, source, target, input_rows, output_rows, source_hash, target_hash, params=None):
self.entries.append({
"executed_at": datetime.now().isoformat(),
"step": step,
"source": source,
"target": target,
"input_rows": input_rows,
"output_rows": output_rows,
"source_hash": source_hash,
"target_hash": target_hash,
"params": params or {}
})
def table_fingerprint(con, table: str) -> str:
row_count = con.execute(f"SELECT count(*) FROM {table}").fetchone()[0]
checksum = con.execute(
f"SELECT to_hex(md5(string_agg(cast(amount as varchar), '|'))) FROM {table}"
).fetchone()[0]
return f"rows={row_count};checksum={checksum}"
main.py
把流程串起来:
import duckdb
from pathlib import Path
from loader import load_csv_to_duckdb
from transformer import load_rules, apply_clean_rules, compute_metrics
from lineage import LineageLogger, table_fingerprint
def main():
con = duckdb.connect("retail_agent.duckdb")
logger = LineageLogger()
rules = load_rules(Path("configs/data_dictionary.yaml"))
source = rules["source"]
before_count = load_csv_to_duckdb(con, source, "orders")
before_hash = table_fingerprint(con, "orders")
apply_clean_rules(con, rules["clean_rules"])
after_count = con.execute("SELECT count(*) FROM orders_clean").fetchone()[0]
after_hash = table_fingerprint(con, "orders_clean")
logger.log(
step="load_and_clean",
source="raw",
target="orders_clean",
input_rows=before_count,
output_rows=after_count,
source_hash=before_hash,
target_hash=after_hash,
params=rules["clean_rules"]
)
metrics = compute_metrics(con, rules["metrics"])
print("metrics:", metrics)
if __name__ == "__main__":
main()
这个骨架跑通后,后续 40 轮提示词的迭代就都有了明确的测试基准:每次改动,行数变化、指标值变化、血缘记录是否完整,都会被记录到日志里。数据可追溯不是事后补文档,而是在每一步处理中自动留存证据。
4. 40 轮提示词迭代怎么组织,才不会变成失控对话
4.1 第一轮:给 Agent 一个可执行的起点
和智能工具协作时,最忌讳一开始就提一个模糊的大目标。第一轮提示词要控制住范围:只要求生成一个能跑通的最小项目骨架。
示例系统提示词放在
prompts/system.md
:
你是本项目的编程助手。
项目根目录:retail_agent/
数据字典:configs/data_dictionary.yaml
技术栈:Python + DuckDB
输出要求:
1. 代码可运行,命令中要包含实际路径,不要使用占位符。
2. 每个模块要给出运行入口和验证方式。
3. 不要引入数据字典之外的新字段名。
4. 每次改动要在文末列出本次改动了什么文件、测试命令是什么、预期输出是什么。
第一轮具体对话可以这样写:
请阅读 data_dictionary.yaml,创建项目骨架。
只需要实现:加载 CSV 到 DuckDB,统计总行数和总金额。不要写清洗逻辑。
运行命令写在 README.md。
完成标准:运行 python src/main.py 后能看到 orders loaded 和 total_amount 输出。
这里刻意限制了范围,让模型先产出可运行版本。跑通后再进入下一轮。
4.2 第 5 到第 20 轮:用反馈清单驱动迭代
从第 5 轮开始,重点已经不只是“代码能跑”,而是“结果是否符合预期”。代码能跑和结果正确是两件事。每次运行后,要把输出、报错、差异反馈给模型,和模型基于真实执行结果继续修改,而不是让它凭空猜。
反馈结构尽量固定:
上一轮结果:
- 命令输出:...
- 问题:金额字段出现负值,总金额偏大。
- 期望行为:过滤掉 amount <= 0 的记录。
- 请给出修改方案,并说明影响哪些指标。
到第 20 轮左右,项目会出现一个明显的临界点:基础清洗和聚合指标已经稳定,后续改动开始涉及报告格式、血缘审计、性能优化。这时提示词的重点要从“改代码”转向“补工程能力”。
4.3 后 20 轮:可追溯、报告迭代和性能验证
20 轮之后的任务列表示例:
| 轮次范围 | 任务类型 | 交付物 |
|---|---|---|
| 21-25 | 血缘模块 | 每次清洗记录输入输出行数和指纹 |
| 26-30 | 报告模板 | 用 Jinja2 生成 Markdown 报告,含指标表 |
| 31-35 | 报告版本 | 每次报告写入 reports/versions/,带时间戳 |
| 36-38 | 性能优化 | 300 万行全流程耗时测试,记录运行时间 |
| 39-40 | 文档收尾 | README、运行说明、常见问题 |
第 30 轮之后,Agent 已经具备比较完整的工程能力。此时要明确告诉它:任何改动都不能破坏血缘记录,新增报告字段必须同步更新数据字典,否则运行验证不通过。
4.4 上下文管理和提示词模板
40 轮对话会带来一个很现实的问题:上下文太长,模型容易丢失早期信息。处理方式不是把所有历史重新粘贴,而是把“稳定的约束”沉淀成项目文件,每轮只把“本轮的差异”发给模型。
需要沉淀的文件至少包括:
-
prompts/system.md:全局系统提示词,始终不变。 -
configs/data_dictionary.yaml:数据字段定义,项目内稳定。 -
docs/project_state.md:当前项目状态,包含已完成功能、未完成功能、最近两次运行结果。 -
docs/next_task.md:本轮要解决的问题,由人工从线上运行结果提炼。
每次迭代时,把
project_state.md
和
next_task.md
的内容发给模型,而不是把 20 轮之前的原始对话重新发一遍。这样模型始终聚焦在当前任务,不会被早期讨论干扰。
下面是一个可复用的“下一轮提示词”模板:
请更新 docs/project_state.md 描述的项目,并执行 next_task.md 中的任务。
项目状态文件:
[粘贴 project_state.md 内容]
当前任务:
[粘贴 next_task.md 内容]
完成标准:
[运行命令、预期输出、检查清单]
限制:
- 不允许改变 data_dictionary.yaml 中字段语义。
- 不允许移除 lineage_log 写入步骤。
- 输出改动文件清单和测试结果。
这套方法比“在同一个聊天窗口里继续聊”“每次复制全部历史”更稳定,也是 40 轮迭代能落地到工程项目的关键。
5. 数据可追溯与报告迭代如何落地
5.1 血缘记录:每一步都留证据
血缘记录要回答三个问题:数据从哪来、经过了什么处理、到哪里去。之前
lineage.py
已经能记录每步行数和指纹。在真实项目里,还需要把血缘记录持久化到一张表,而不是只放在 Python 内存中。
在 DuckDB 里创建血缘表:
CREATE TABLE IF NOT EXISTS lineage_log (
id INTEGER PRIMARY KEY,
executed_at TIMESTAMP DEFAULT current_timestamp,
step VARCHAR,
source VARCHAR,
target VARCHAR,
input_rows BIGINT,
output_rows BIGINT,
source_hash VARCHAR,
target_hash VARCHAR,
operator VARCHAR,
params JSON
);
每次运行结束时把
LineageLogger.entries
写入这张表。这样不仅当前这次运行能看到血缘,历史运行也能查询。分析结果一旦异常,可以从报告倒查:这个指标是哪一次运行、哪一步、用了什么参数算出来的。
查询血缘的示例:
SELECT executed_at, step, source, target, input_rows, output_rows, source_hash, target_hash
FROM lineage_log
ORDER BY id
LIMIT 10;
5.2 报告版本管理:让报告能对比和回滚
报告生成后要能回滚和对比。最简单的方式是每次生成报告时,把报告写到
reports/versions/
目录,文件名带时间戳:
reports/versions/20250321_103000_report.md
reports/versions/20250321_113200_report.md
同时维护一个
latest_report.md
的软链接或复制文件,指向最新报告。这样既能“看最新”,也能“找历史”。
报告内容要包含关键指标、数据快照信息、运行时间、血缘记录摘要。这样才能称得上“报告能迭代”。如果报告只是把指标打印出来,没有时间和版本上下文,就无法回答“哪次运行结果是最新的”。
5.3 验证数据一致性:行数、金额、去重
数据一致性是报告可信的前提。300 万行数据经过清洗聚合后,不能只看最终金额。每次迭代完成后,至少要做三组验证:
| 验证项 | 方法 | 预期表现 |
|---|---|---|
| 行数变化 | 对比 raw 和 clean 表的 count | 清洗后行数应小于等于原始行数 |
| 金额守恒 | 对比清洗前后总金额 | 只过滤负数和重复订单时,总金额应下降且变化可解释 |
| 重复订单 |
SELECT order_id, count(*) FROM orders GROUP BY order_id HAVING count(*) > 1
| 清洗前应能查出重复,清洗后应为 0 |
可以写一个简单的验证脚本
scripts/validate.py
,每次运行后自动输出这三项对比。这也是给 Agent 提供反馈的关键:如果模型改完代码后行数不一致,验证脚本能立刻发现问题。
6. 常见问题排查与调优
6.1 命令行工具相关的报错
| 问题现象 | 常见原因 | 检查方式 | 处理建议 |
|---|---|---|---|
| IDE 插件报 unable to locate the codex cli binary | 插件进程找不到 codex 可执行文件 |
终端执行
which codex
|
把绝对路径配置到插件
codex_cli_path
|
| 启动 Codex 后提示配置格式错误 | 配置字段写错或版本不兼容 | 查看当前版本帮助文档 | 对照本版本官方配置示例修改 |
| 接入自定义模型后请求一直失败 | 环境变量未生效或 base_url 写错 | 先用 curl 验证接口 | 确认 key、模型 ID、接口地址 |
6.2 DeepSeek API 调用延迟和超时
使用自定义模型时,Codex 执行过程中可能会遇到响应慢或等待超时。常见原因是上下文过长、输出内容太多、网络环境不稳定。若出现类似模型提供方未及时响应的报错,先做两个确认:当前请求是否携带了过长的项目上下文,模型是否正处于推理复杂任务的状态。
优化方向是把大任务拆小。不要同时让 Codex 读取 300 万行数据并生成全部代码,而是让它只处理一个模块。上下文规模小了,响应延迟通常会明显下降。如果问题持续,检查网络环境和 API 配额。
6.3 300 万行数据处理时的内存问题
如果仍然使用 Pandas 全量读取,内存会很快耗尽。切换到 DuckDB 后,要注意避免“先把数据全部导成 Pandas DataFrame,再聚合”的代码风格。正确的做法是把聚合 SQL 下推给 DuckDB,Python 只接收最终的小结果集。
如果运行时报内存不足,检查是否在代码中生成了中间大表。例如在 Python 里创建
orders_clean_pd = con.execute("SELECT * FROM orders_clean").df()
,这会把 300 万数据拉回内存。生产代码要避免这类写法。
6.4 多轮提示词后上下文漂移
40 轮迭代后,模型可能忘掉了早期约定,或者开始修改本来已经稳定的模块。这不是模型“变笨”,而是上下文里新增内容太多,早期约束被稀释了。
解决方案是引入
docs/project_state.md
,在每轮开始前把“当前状态、已完成、禁止修改项”明确写入。如果发现 Agent 开始频繁破坏稳定模块,就暂停功能迭代,先让它重读项目状态文件,并执行全量验证脚本确认没有回归。
6.5 数据验证失败时应按顺序排查
当报告输出的指标和预期不一致时,按下面顺序排查,不要先怀疑模型:
- 输入数据是否正确,来源文件是否被覆盖。
- 清洗规则是否按数据字典执行。
- 过滤条件是否影响特定字段。
- 聚合 SQL 是否忽略空值或重复。
- 血缘记录中每步行数是否符合预期。
- API 或模型本身的输出是否与上下文相关。
前五步都能在
lineage_log
中找到证据。这样定位问题的速度会快很多。
7. 项目收尾:测试、文档和写进简历的工程化方式
7.1 用验证脚本形成回归保护
项目进入稳定期后,要形成一个“一键验证”入口。可以写一个
make check
或简单 shell 脚本,每次迭代后运行:
python src/main.py
python scripts/validate.py
validate.py
的输出应该包含三部分:清洗前后行数变化、关键指标值、血缘记录条数。任何一次改动导致验证不通过,都要在当前轮内解决,不要带着失败结果进入下一轮。
7.2 README 和项目交付物
交付一个 AI 辅助开发的项目,README 需要写清楚以下内容:
- 项目是什么,解决什么问题。
- 环境依赖和安装命令。
- 数据字典位置和字段说明。
- 运行命令和验证命令。
- 报告输出位置和版本管理方式。
- 已知限制和后续优化点。
不要只写“基于 AI 生成”这种描述。交付重点是“这个项目能运行、结果可验证、数据可追溯”。
7.3 简历中怎么写这个项目
简历项目描述要突出工程能力,而不是“我用 AI 写了个脚本”。可以按这个思路组织描述:
基于 DeepSeek 与 Codex CLI 完成数据分析 Agent 的迭代开发,通过 40 轮提示词循环实现需求收敛。项目使用 Python 与 DuckDB 处理 300 万行订单数据,设计数据字典驱动清洗流程,通过血缘记录表跟踪每一步的行数和数据指纹。报告按版本管理,可回溯可对比,满足数据可解释和分析可复现要求。
这里不需要强调“AI 很厉害”,重点体现候选人的架构判断、验证习惯和交付意识。简历面试中如果被问到“为什么用 DuckDB”,能解释清楚内存和聚合下推的原因,比单纯列出工具名更有说服力。
7.4 下一步扩展方向
这个项目骨架可以继续扩展的方向:
- 把 DuckDB 换成分布式查询引擎,应对更大数据量。
- 在报告里加入图表,让指标对比更直观。
- 把血缘记录导出为标准数据目录格式,接入数据平台。
-
在提示词系统中加入更多项目状态信息,让 Agent 自动维护
project_state.md。 - 为验证脚本增加阈值检查,指标异常时直接告警。
真正值得投入精力的,不是再堆更多功能,而是让“数据可追溯、报告可迭代”这两点成为所有后续功能的基本约束。只要这一步做到位,这个项目就已经具备合格的工程交付形态。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)