用 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 数据验证失败时应按顺序排查

当报告输出的指标和预期不一致时,按下面顺序排查,不要先怀疑模型:

  1. 输入数据是否正确,来源文件是否被覆盖。
  2. 清洗规则是否按数据字典执行。
  3. 过滤条件是否影响特定字段。
  4. 聚合 SQL 是否忽略空值或重复。
  5. 血缘记录中每步行数是否符合预期。
  6. 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
  • 为验证脚本增加阈值检查,指标异常时直接告警。

真正值得投入精力的,不是再堆更多功能,而是让“数据可追溯、报告可迭代”这两点成为所有后续功能的基本约束。只要这一步做到位,这个项目就已经具备合格的工程交付形态。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐