dtflow 0.5.5__tar.gz → 0.5.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. {dtflow-0.5.5 → dtflow-0.5.7}/PKG-INFO +43 -4
  2. {dtflow-0.5.5 → dtflow-0.5.7}/README.md +42 -1
  3. dtflow-0.5.7/dtflow/SKILL.md +225 -0
  4. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/__init__.py +1 -1
  5. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/__main__.py +33 -52
  6. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/cli/commands.py +16 -10
  7. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/cli/sample.py +159 -11
  8. dtflow-0.5.7/dtflow/cli/skill.py +72 -0
  9. {dtflow-0.5.5 → dtflow-0.5.7}/pyproject.toml +0 -4
  10. {dtflow-0.5.5 → dtflow-0.5.7}/tests/test_cli_sample.py +99 -0
  11. dtflow-0.5.5/dtflow/mcp/__init__.py +0 -29
  12. dtflow-0.5.5/dtflow/mcp/__main__.py +0 -18
  13. dtflow-0.5.5/dtflow/mcp/cli.py +0 -388
  14. dtflow-0.5.5/dtflow/mcp/docs.py +0 -416
  15. dtflow-0.5.5/dtflow/mcp/server.py +0 -153
  16. {dtflow-0.5.5 → dtflow-0.5.7}/.gitignore +0 -0
  17. {dtflow-0.5.5 → dtflow-0.5.7}/CHANGELOG.md +0 -0
  18. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/cli/__init__.py +0 -0
  19. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/cli/clean.py +0 -0
  20. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/cli/common.py +0 -0
  21. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/cli/io_ops.py +0 -0
  22. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/cli/lineage.py +0 -0
  23. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/cli/pipeline.py +0 -0
  24. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/cli/stats.py +0 -0
  25. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/cli/transform.py +0 -0
  26. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/cli/validate.py +0 -0
  27. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/converters.py +0 -0
  28. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/core.py +0 -0
  29. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/framework.py +0 -0
  30. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/lineage.py +0 -0
  31. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/pipeline.py +0 -0
  32. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/presets.py +0 -0
  33. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/schema.py +0 -0
  34. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/storage/__init__.py +0 -0
  35. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/storage/io.py +0 -0
  36. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/streaming.py +0 -0
  37. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/tokenizers.py +0 -0
  38. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/utils/__init__.py +0 -0
  39. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/utils/display.py +0 -0
  40. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/utils/field_path.py +0 -0
  41. {dtflow-0.5.5 → dtflow-0.5.7}/dtflow/utils/helpers.py +0 -0
  42. {dtflow-0.5.5 → dtflow-0.5.7}/tests/README.md +0 -0
  43. {dtflow-0.5.5 → dtflow-0.5.7}/tests/benchmark_io.py +0 -0
  44. {dtflow-0.5.5 → dtflow-0.5.7}/tests/benchmark_sharegpt.py +0 -0
  45. {dtflow-0.5.5 → dtflow-0.5.7}/tests/test_cli_benchmark.py +0 -0
  46. {dtflow-0.5.5 → dtflow-0.5.7}/tests/test_cli_clean.py +0 -0
  47. {dtflow-0.5.5 → dtflow-0.5.7}/tests/test_cli_stats.py +0 -0
  48. {dtflow-0.5.5 → dtflow-0.5.7}/tests/test_cli_transform.py +0 -0
  49. {dtflow-0.5.5 → dtflow-0.5.7}/tests/test_converters.py +0 -0
  50. {dtflow-0.5.5 → dtflow-0.5.7}/tests/test_field_path.py +0 -0
  51. {dtflow-0.5.5 → dtflow-0.5.7}/tests/test_framework.py +0 -0
  52. {dtflow-0.5.5 → dtflow-0.5.7}/tests/test_io.py +0 -0
  53. {dtflow-0.5.5 → dtflow-0.5.7}/tests/test_lineage.py +0 -0
  54. {dtflow-0.5.5 → dtflow-0.5.7}/tests/test_pipeline.py +0 -0
  55. {dtflow-0.5.5 → dtflow-0.5.7}/tests/test_schema.py +0 -0
  56. {dtflow-0.5.5 → dtflow-0.5.7}/tests/test_streaming.py +0 -0
  57. {dtflow-0.5.5 → dtflow-0.5.7}/tests/test_tokenizers.py +0 -0
  58. {dtflow-0.5.5 → dtflow-0.5.7}/tests/test_transformer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dtflow
3
- Version: 0.5.5
3
+ Version: 0.5.7
4
4
  Summary: A flexible data transformation tool for ML training formats (SFT, RLHF, Pretrain)
5
5
  Project-URL: Homepage, https://github.com/yourusername/DataTransformer
6
6
  Project-URL: Documentation, https://github.com/yourusername/DataTransformer#readme
@@ -69,8 +69,6 @@ Requires-Dist: tokenizers>=0.15.0; extra == 'full'
69
69
  Requires-Dist: toolong>=1.5.0; extra == 'full'
70
70
  Provides-Extra: logs
71
71
  Requires-Dist: toolong>=1.5.0; extra == 'logs'
72
- Provides-Extra: mcp
73
- Requires-Dist: mcp>=1.0.0; extra == 'mcp'
74
72
  Provides-Extra: similarity
75
73
  Requires-Dist: datasketch>=1.5.0; extra == 'similarity'
76
74
  Requires-Dist: scikit-learn>=0.24.0; extra == 'similarity'
@@ -99,6 +97,17 @@ pip install transformers # Token 统计(HuggingFace 模型)
99
97
  pip install datasets # HuggingFace Dataset 转换
100
98
  ```
101
99
 
100
+ ## 🤖 Claude Code 集成
101
+
102
+ dtflow 内置了 [Claude Code](https://docs.anthropic.com/en/docs/claude-code) skill:
103
+
104
+ ```bash
105
+ dt install-skill # 安装 skill
106
+ dt skill-status # 查看状态
107
+ ```
108
+
109
+ 安装后在 Claude Code 中输入 `/dtflow`,Claude 将掌握 dtflow 的完整用法,可直接协助你完成数据处理任务。
110
+
102
111
  ## 快速开始
103
112
 
104
113
  ```python
@@ -423,6 +432,8 @@ dt sample data.csv --num=100 --sample_type=head
423
432
  dt sample data.jsonl 1000 --by=category # 分层采样
424
433
  dt sample data.jsonl 1000 --by=meta.source # 按嵌套字段分层采样
425
434
  dt sample data.jsonl 1000 --by=messages.# # 按消息数量分层采样
435
+ dt sample data.jsonl --where="category=tech" # 筛选后采样
436
+ dt sample data.jsonl --where="messages.#>=2" # 多条件筛选
426
437
 
427
438
  # 数据转换 - 预设模式
428
439
  dt transform data.jsonl --preset=openai_chat
@@ -471,6 +482,10 @@ dt concat a.jsonl b.jsonl -o merged.jsonl
471
482
  # 数据统计
472
483
  dt stats data.jsonl
473
484
 
485
+ # Claude Code Skill 安装
486
+ dt install-skill # 安装到 ~/.claude/skills/
487
+ dt skill-status # 查看安装状态
488
+
474
489
  # 数据验证
475
490
  dt validate data.jsonl --preset=openai_chat # 使用预设 schema 验证
476
491
  dt validate data.jsonl --preset=alpaca --verbose # 详细输出
@@ -496,7 +511,7 @@ CLI 命令中的字段参数支持嵌套路径语法,可访问深层嵌套的
496
511
 
497
512
  | 命令 | 参数 | 示例 |
498
513
  |------|------|------|
499
- | `sample` | `--by=` | `--by=meta.source`、`--by=messages.#` |
514
+ | `sample` | `--by=`, `--where=` | `--by=meta.source`、`--where=messages.#>=2` |
500
515
  | `dedupe` | `--key=` | `--key=meta.id`、`--key=messages[0].content` |
501
516
  | `clean` | `--drop-empty=` | `--drop-empty=meta.source` |
502
517
  | `clean` | `--min-len=` | `--min-len=messages.#:2` |
@@ -504,6 +519,18 @@ CLI 命令中的字段参数支持嵌套路径语法,可访问深层嵌套的
504
519
  | `token-stats` | `--field=` | `--field=messages[-1].content` |
505
520
  | `diff` | `--key=` | `--key=meta.uuid` |
506
521
 
522
+ `--where` 支持的操作符:
523
+
524
+ | 操作符 | 含义 | 示例 |
525
+ |--------|------|------|
526
+ | `=` | 等于 | `--where="category=tech"` |
527
+ | `!=` | 不等于 | `--where="source!=wiki"` |
528
+ | `~=` | 包含 | `--where="content~=机器学习"` |
529
+ | `>` | 大于 | `--where="score>0.8"` |
530
+ | `>=` | 大于等于 | `--where="messages.#>=2"` |
531
+ | `<` | 小于 | `--where="length<1000"` |
532
+ | `<=` | 小于等于 | `--where="turns<=10"` |
533
+
507
534
  示例数据:
508
535
  ```json
509
536
  {"meta": {"source": "wiki"}, "messages": [{"role": "user", "content": "hi"}, {"role": "assistant", "content": "hello"}]}
@@ -601,6 +628,18 @@ dt history processed.jsonl
601
628
  dt history processed.jsonl --json # JSON 格式输出
602
629
  ```
603
630
 
631
+ ### 日志查看
632
+
633
+ dtflow 内置了 [toolong](https://github.com/Textualize/toolong) 日志查看器:
634
+
635
+ ```bash
636
+ pip install dtflow[logs] # 安装日志工具
637
+
638
+ tl app.log # 交互式 TUI 查看
639
+ tl --tail app.log # 实时跟踪(类似 tail -f)
640
+ dt logs # 查看使用说明
641
+ ```
642
+
604
643
  ### 大文件流式处理
605
644
 
606
645
  专为超大文件设计的流式处理接口,内存占用 O(1),支持 JSONL、CSV、Parquet、Arrow 格式:
@@ -13,6 +13,17 @@ pip install transformers # Token 统计(HuggingFace 模型)
13
13
  pip install datasets # HuggingFace Dataset 转换
14
14
  ```
15
15
 
16
+ ## 🤖 Claude Code 集成
17
+
18
+ dtflow 内置了 [Claude Code](https://docs.anthropic.com/en/docs/claude-code) skill:
19
+
20
+ ```bash
21
+ dt install-skill # 安装 skill
22
+ dt skill-status # 查看状态
23
+ ```
24
+
25
+ 安装后在 Claude Code 中输入 `/dtflow`,Claude 将掌握 dtflow 的完整用法,可直接协助你完成数据处理任务。
26
+
16
27
  ## 快速开始
17
28
 
18
29
  ```python
@@ -337,6 +348,8 @@ dt sample data.csv --num=100 --sample_type=head
337
348
  dt sample data.jsonl 1000 --by=category # 分层采样
338
349
  dt sample data.jsonl 1000 --by=meta.source # 按嵌套字段分层采样
339
350
  dt sample data.jsonl 1000 --by=messages.# # 按消息数量分层采样
351
+ dt sample data.jsonl --where="category=tech" # 筛选后采样
352
+ dt sample data.jsonl --where="messages.#>=2" # 多条件筛选
340
353
 
341
354
  # 数据转换 - 预设模式
342
355
  dt transform data.jsonl --preset=openai_chat
@@ -385,6 +398,10 @@ dt concat a.jsonl b.jsonl -o merged.jsonl
385
398
  # 数据统计
386
399
  dt stats data.jsonl
387
400
 
401
+ # Claude Code Skill 安装
402
+ dt install-skill # 安装到 ~/.claude/skills/
403
+ dt skill-status # 查看安装状态
404
+
388
405
  # 数据验证
389
406
  dt validate data.jsonl --preset=openai_chat # 使用预设 schema 验证
390
407
  dt validate data.jsonl --preset=alpaca --verbose # 详细输出
@@ -410,7 +427,7 @@ CLI 命令中的字段参数支持嵌套路径语法,可访问深层嵌套的
410
427
 
411
428
  | 命令 | 参数 | 示例 |
412
429
  |------|------|------|
413
- | `sample` | `--by=` | `--by=meta.source`、`--by=messages.#` |
430
+ | `sample` | `--by=`, `--where=` | `--by=meta.source`、`--where=messages.#>=2` |
414
431
  | `dedupe` | `--key=` | `--key=meta.id`、`--key=messages[0].content` |
415
432
  | `clean` | `--drop-empty=` | `--drop-empty=meta.source` |
416
433
  | `clean` | `--min-len=` | `--min-len=messages.#:2` |
@@ -418,6 +435,18 @@ CLI 命令中的字段参数支持嵌套路径语法,可访问深层嵌套的
418
435
  | `token-stats` | `--field=` | `--field=messages[-1].content` |
419
436
  | `diff` | `--key=` | `--key=meta.uuid` |
420
437
 
438
+ `--where` 支持的操作符:
439
+
440
+ | 操作符 | 含义 | 示例 |
441
+ |--------|------|------|
442
+ | `=` | 等于 | `--where="category=tech"` |
443
+ | `!=` | 不等于 | `--where="source!=wiki"` |
444
+ | `~=` | 包含 | `--where="content~=机器学习"` |
445
+ | `>` | 大于 | `--where="score>0.8"` |
446
+ | `>=` | 大于等于 | `--where="messages.#>=2"` |
447
+ | `<` | 小于 | `--where="length<1000"` |
448
+ | `<=` | 小于等于 | `--where="turns<=10"` |
449
+
421
450
  示例数据:
422
451
  ```json
423
452
  {"meta": {"source": "wiki"}, "messages": [{"role": "user", "content": "hi"}, {"role": "assistant", "content": "hello"}]}
@@ -515,6 +544,18 @@ dt history processed.jsonl
515
544
  dt history processed.jsonl --json # JSON 格式输出
516
545
  ```
517
546
 
547
+ ### 日志查看
548
+
549
+ dtflow 内置了 [toolong](https://github.com/Textualize/toolong) 日志查看器:
550
+
551
+ ```bash
552
+ pip install dtflow[logs] # 安装日志工具
553
+
554
+ tl app.log # 交互式 TUI 查看
555
+ tl --tail app.log # 实时跟踪(类似 tail -f)
556
+ dt logs # 查看使用说明
557
+ ```
558
+
518
559
  ### 大文件流式处理
519
560
 
520
561
  专为超大文件设计的流式处理接口,内存占用 O(1),支持 JSONL、CSV、Parquet、Arrow 格式:
@@ -0,0 +1,225 @@
1
+ ---
2
+ name: dtflow
3
+ description: 数据文件处理(JSONL/CSV/Parquet)- 去重/采样/统计/过滤/转换/Schema验证/训练框架导出
4
+ ---
5
+
6
+ # dtflow - 机器学习训练数据格式转换工具
7
+
8
+ ## 设计理念
9
+
10
+ - **函数式优于类继承**:直接用 lambda/函数做转换,不需要 OOP 抽象
11
+ - **KISS 原则**:一个 `DataTransformer` 类搞定所有操作
12
+ - **链式 API**:`dt.filter(...).to(...).save(...)`
13
+
14
+ ## Python API
15
+
16
+ ```python
17
+ from dtflow import DataTransformer
18
+
19
+ # 加载数据(支持 JSONL/JSON/CSV/Parquet/Arrow,使用 Polars 引擎)
20
+ dt = DataTransformer.load("data.jsonl")
21
+
22
+ # 链式操作
23
+ (dt.filter(lambda x: x.score > 0.8)
24
+ .to(lambda x: {"q": x.question, "a": x.answer})
25
+ .dedupe("text")
26
+ .save("output.jsonl"))
27
+ ```
28
+
29
+ ### 数据过滤
30
+
31
+ ```python
32
+ dt.filter(lambda x: x.score > 0.8)
33
+ dt.filter(lambda x: x.language == "zh")
34
+ ```
35
+
36
+ ### 数据验证
37
+
38
+ ```python
39
+ # 简单验证
40
+ errors = dt.validate(lambda x: len(x.messages) >= 2)
41
+
42
+ # Schema 验证
43
+ from dtflow import Schema, Field, openai_chat_schema
44
+
45
+ result = dt.validate_schema(openai_chat_schema) # 预设 Schema
46
+ valid_dt = dt.validate_schema(schema, filter_invalid=True) # 过滤无效数据
47
+ ```
48
+
49
+ **预设 Schema**:`openai_chat_schema`、`alpaca_schema`、`sharegpt_schema`、`dpo_schema`
50
+
51
+ ### 数据转换
52
+
53
+ ```python
54
+ # 自定义转换
55
+ dt.to(lambda x: {"question": x.q, "answer": x.a})
56
+
57
+ # 使用预设模板
58
+ dt.to(preset="openai_chat", user_field="q", assistant_field="a")
59
+ ```
60
+
61
+ **预设模板**:`openai_chat`、`alpaca`、`sharegpt`、`dpo_pair`、`simple_qa`
62
+
63
+ ### Token 统计
64
+
65
+ ```python
66
+ from dtflow import count_tokens, token_counter, token_filter, token_stats
67
+
68
+ count = count_tokens("Hello world", model="gpt-4")
69
+ dt.transform(token_counter("text")).save("with_tokens.jsonl")
70
+ dt.filter(token_filter("text", max_tokens=2048))
71
+
72
+ # Messages Token 统计(多轮对话)
73
+ from dtflow import messages_token_counter, messages_token_filter
74
+ dt.transform(messages_token_counter(model="gpt-4", detailed=True))
75
+ dt.filter(messages_token_filter(min_turns=2, max_turns=10))
76
+ ```
77
+
78
+ ### 格式转换器
79
+
80
+ ```python
81
+ from dtflow import (
82
+ to_hf_dataset, from_hf_dataset, # HuggingFace Dataset
83
+ to_openai_batch, from_openai_batch, # OpenAI Batch API
84
+ to_llama_factory, to_llama_factory_sharegpt, # LLaMA-Factory
85
+ to_swift_messages, to_swift_query_response, # ms-swift
86
+ messages_to_text, # messages 转纯文本
87
+ )
88
+ ```
89
+
90
+ ### 训练框架导出
91
+
92
+ ```python
93
+ # 检查兼容性
94
+ result = dt.check_compatibility("llama-factory")
95
+
96
+ # 一键导出
97
+ files = dt.export_for("llama-factory", "./output/") # 生成 data.json + dataset_info.json + train_args.yaml
98
+ files = dt.export_for("swift", "./output/") # 生成 data.jsonl + train_swift.sh
99
+ files = dt.export_for("axolotl", "./output/") # 生成 data.jsonl + config.yaml
100
+ ```
101
+
102
+ ### 大文件流式处理
103
+
104
+ ```python
105
+ from dtflow import load_stream, load_sharded
106
+
107
+ # O(1) 内存,100GB 文件也能处理
108
+ (load_stream("huge.jsonl")
109
+ .filter(lambda x: x["score"] > 0.5)
110
+ .save("output.jsonl"))
111
+
112
+ # 分片文件加载
113
+ (load_sharded("data/train_*.parquet")
114
+ .filter(lambda x: len(x["text"]) > 10)
115
+ .save("merged.jsonl"))
116
+
117
+ # 分片保存
118
+ load_stream("huge.jsonl").save_sharded("output/", shard_size=100000)
119
+ ```
120
+
121
+ ### 其他操作
122
+
123
+ ```python
124
+ dt.sample(100) # 随机采样
125
+ dt.head(10) / dt.tail(10) # 取前/后 N 条
126
+ train, test = dt.split(ratio=0.8) # 分割
127
+ dt.shuffle(seed=42) # 打乱
128
+ dt.stats() # 统计
129
+ ```
130
+
131
+ ## CLI 命令
132
+
133
+ ```bash
134
+ # 统计(推荐首先使用)
135
+ dt stats data.jsonl # 基本统计(文件大小、条数、字段)
136
+ dt stats data.jsonl --full # 完整模式:值分布、唯一值、非空率
137
+ dt stats data.jsonl --full -n 20 # 显示 Top 20 值分布
138
+
139
+ # Token 统计
140
+ dt token-stats data.jsonl # 默认统计 messages 字段
141
+ dt token-stats data.jsonl -f text # 指定统计字段
142
+ dt token-stats data.jsonl -m qwen2.5 # 指定分词器 (cl100k_base/qwen2.5/llama3)
143
+ dt token-stats data.jsonl --detailed # 显示详细统计
144
+
145
+ # 采样(支持字段路径语法)
146
+ dt sample data.jsonl 100 # 随机采样 100 条
147
+ dt sample data.jsonl 100 -t head # 取前 100 条 (head/tail/random)
148
+ dt sample data.jsonl 1000 --by=category # 分层采样
149
+ dt sample data.jsonl 1000 --by=category --uniform # 均匀分层采样
150
+ dt sample data.jsonl --where="messages.#>=2" # 条件筛选
151
+ dt sample data.jsonl 10 -f input,output # 只显示指定字段
152
+ dt sample data.jsonl 10 --raw # 输出原始 JSON(不截断)
153
+ dt sample data.jsonl 100 --seed=42 -o out.jsonl # 固定随机种子并保存
154
+
155
+ # 去重
156
+ dt dedupe data.jsonl --key=text # 精确去重
157
+ dt dedupe data.jsonl --key=meta.id # 按嵌套字段去重
158
+ dt dedupe data.jsonl --key=text --similar=0.8 # 相似度去重
159
+ dt dedupe data.jsonl --key=text -o deduped.jsonl # 指定输出文件
160
+
161
+ # 清洗
162
+ dt clean data.jsonl --drop-empty=text,answer # 删除空值记录
163
+ dt clean data.jsonl --min-len=text:10 # 最小长度过滤
164
+ dt clean data.jsonl --max-len=text:2000 # 最大长度过滤
165
+ dt clean data.jsonl --min-len=messages.#:2 # 最少 2 条消息
166
+ dt clean data.jsonl --keep=question,answer # 只保留指定字段
167
+ dt clean data.jsonl --drop=metadata # 删除指定字段
168
+ dt clean data.jsonl --strip # 去除字符串首尾空白
169
+ dt clean data.jsonl --strip --drop-empty=input -o cleaned.jsonl # 组合使用
170
+
171
+ # 验证
172
+ dt validate data.jsonl --preset=openai_chat # 预设: openai_chat/alpaca/dpo/sharegpt
173
+ dt validate data.jsonl -p alpaca -f -o valid.jsonl # 过滤无效数据并保存
174
+ dt validate data.jsonl -p openai_chat -v # 显示详细信息
175
+ dt validate data.jsonl -p openai_chat --max-errors=50 # 最多显示 50 条错误
176
+
177
+ # 转换
178
+ dt transform data.jsonl --preset=openai_chat
179
+ dt transform data.jsonl # 交互式生成配置文件
180
+
181
+ # 合并与对比
182
+ dt concat a.jsonl b.jsonl -o merged.jsonl # 合并文件
183
+ dt concat a.jsonl b.jsonl -o merged.jsonl --strict # 严格模式(字段必须一致)
184
+ dt diff a.jsonl b.jsonl --key=id # 对比差异
185
+ dt diff a.jsonl b.jsonl --key=id -o report.md # 输出对比报告
186
+
187
+ # 查看数据
188
+ dt head data.jsonl 10 # 前 10 条
189
+ dt head data.jsonl 10 -f input,output # 只显示指定字段
190
+ dt head data.jsonl 10 --raw # 输出完整 JSON(不截断)
191
+ dt tail data.jsonl 10 # 后 10 条
192
+
193
+ # 其他
194
+ dt run pipeline.yaml # Pipeline 执行
195
+ dt history processed.jsonl # 数据血缘
196
+ dt install-skill # 安装 Claude Code skill
197
+ ```
198
+
199
+ ## 字段路径语法
200
+
201
+ | 语法 | 含义 | 示例 |
202
+ |------|------|------|
203
+ | `a.b.c` | 嵌套字段 | `meta.source` |
204
+ | `a[0].b` | 数组索引 | `messages[0].role` |
205
+ | `a[-1].b` | 负索引 | `messages[-1].content` |
206
+ | `a.#` | 数组长度 | `messages.#` |
207
+ | `a[*].b` | 展开所有元素 | `messages[*].role` |
208
+
209
+ ## Pipeline 配置
210
+
211
+ ```yaml
212
+ # pipeline.yaml
213
+ version: "1.0"
214
+ seed: 42
215
+ input: raw_data.jsonl
216
+ output: processed.jsonl
217
+
218
+ steps:
219
+ - type: filter
220
+ condition: "score > 0.5"
221
+ - type: transform
222
+ preset: openai_chat
223
+ - type: dedupe
224
+ key: text
225
+ ```
@@ -60,7 +60,7 @@ from .tokenizers import (
60
60
  token_stats,
61
61
  )
62
62
 
63
- __version__ = "0.5.5"
63
+ __version__ = "0.5.7"
64
64
 
65
65
  __all__ = [
66
66
  # core
@@ -6,21 +6,21 @@ Usage:
6
6
  dt --install-completion # 安装 shell 自动补全
7
7
 
8
8
  Commands:
9
- sample 从数据文件中采样
10
- head 显示文件的前 N 条数据
11
- tail 显示文件的后 N 条数据
12
- transform 转换数据格式(核心命令)
13
- stats 显示数据文件的统计信息
14
- token-stats Token 统计
15
- diff 数据集对比
16
- dedupe 数据去重
17
- concat 拼接多个数据文件
18
- clean 数据清洗
19
- run 执行 Pipeline 配置文件
20
- history 显示数据血缘历史
21
- validate 使用 Schema 验证数据格式
22
- mcp MCP 服务管理(install/uninstall/status)
23
- logs 日志查看工具使用说明
9
+ sample 从数据文件中采样
10
+ head 显示文件的前 N 条数据
11
+ tail 显示文件的后 N 条数据
12
+ transform 转换数据格式(核心命令)
13
+ stats 显示数据文件的统计信息
14
+ token-stats Token 统计
15
+ diff 数据集对比
16
+ dedupe 数据去重
17
+ concat 拼接多个数据文件
18
+ clean 数据清洗
19
+ run 执行 Pipeline 配置文件
20
+ history 显示数据血缘历史
21
+ validate 使用 Schema 验证数据格式
22
+ logs 日志查看工具使用说明
23
+ install-skill 安装 dtflow skill 到 Claude Code
24
24
  """
25
25
 
26
26
  import os
@@ -35,12 +35,15 @@ from .cli.commands import dedupe as _dedupe
35
35
  from .cli.commands import diff as _diff
36
36
  from .cli.commands import head as _head
37
37
  from .cli.commands import history as _history
38
+ from .cli.commands import install_skill as _install_skill
38
39
  from .cli.commands import run as _run
39
40
  from .cli.commands import sample as _sample
41
+ from .cli.commands import skill_status as _skill_status
40
42
  from .cli.commands import stats as _stats
41
43
  from .cli.commands import tail as _tail
42
44
  from .cli.commands import token_stats as _token_stats
43
45
  from .cli.commands import transform as _transform
46
+ from .cli.commands import uninstall_skill as _uninstall_skill
44
47
  from .cli.commands import validate as _validate
45
48
 
46
49
  # 创建主应用
@@ -67,10 +70,11 @@ def sample(
67
70
  uniform: bool = typer.Option(False, "--uniform", help="均匀采样模式"),
68
71
  fields: Optional[str] = typer.Option(None, "--fields", "-f", help="只显示指定字段(逗号分隔)"),
69
72
  raw: bool = typer.Option(False, "--raw", "-r", help="输出原始 JSON(不截断)"),
73
+ where: Optional[List[str]] = typer.Option(None, "--where", "-w", help="筛选条件 (可多次使用)"),
70
74
  ):
71
75
  """从数据文件中采样指定数量的数据"""
72
76
  actual_num = num_arg if num_arg is not None else num
73
- _sample(filename, actual_num, type, output, seed, by, uniform, fields, raw)
77
+ _sample(filename, actual_num, type, output, seed, by, uniform, fields, raw, where)
74
78
 
75
79
 
76
80
  @app.command()
@@ -262,48 +266,25 @@ dtflow 内置了 toolong 日志查看器,安装后可直接使用 tl 命令:
262
266
  print(help_text)
263
267
 
264
268
 
265
- # ============ MCP 子命令 ============
269
+ # ============ Skill 命令 ============
266
270
 
267
- mcp_app = typer.Typer(help="MCP 服务管理")
268
- app.add_typer(mcp_app, name="mcp")
269
271
 
272
+ @app.command("install-skill")
273
+ def install_skill():
274
+ """安装 dtflow skill 到 Claude Code"""
275
+ _install_skill()
270
276
 
271
- @mcp_app.command()
272
- def install(
273
- name: str = typer.Option("datatron", "--name", "-n", help="MCP 服务名称"),
274
- target: str = typer.Option("code", "--target", "-t", help="安装目标: desktop/code/all"),
275
- ):
276
- """安装 Datatron MCP 服务"""
277
- from .mcp.cli import MCPCommands
278
-
279
- MCPCommands().install(name, target)
280
-
281
-
282
- @mcp_app.command()
283
- def uninstall(
284
- name: str = typer.Option("datatron", "--name", "-n", help="MCP 服务名称"),
285
- target: str = typer.Option("all", "--target", "-t", help="移除目标: desktop/code/all"),
286
- ):
287
- """移除 Datatron MCP 服务"""
288
- from .mcp.cli import MCPCommands
289
-
290
- MCPCommands().uninstall(name, target)
291
-
292
-
293
- @mcp_app.command()
294
- def status():
295
- """查看 MCP 服务安装状态"""
296
- from .mcp.cli import MCPCommands
297
-
298
- MCPCommands().status()
299
277
 
278
+ @app.command("uninstall-skill")
279
+ def uninstall_skill():
280
+ """卸载 dtflow skill"""
281
+ _uninstall_skill()
300
282
 
301
- @mcp_app.command()
302
- def test():
303
- """测试 MCP 服务是否正常"""
304
- from .mcp.cli import MCPCommands
305
283
 
306
- MCPCommands().test()
284
+ @app.command("skill-status")
285
+ def skill_status():
286
+ """查看 skill 安装状态"""
287
+ _skill_status()
307
288
 
308
289
 
309
290
  def _show_completion_hint():
@@ -13,25 +13,27 @@ CLI 命令统一导出入口
13
13
  """
14
14
 
15
15
  # 采样命令
16
- from .sample import head, sample, tail
17
-
18
- # 转换命令
19
- from .transform import transform
20
-
21
- # 统计命令
22
- from .stats import stats, token_stats
23
-
24
16
  # 清洗命令
25
17
  from .clean import clean, dedupe
26
18
 
27
19
  # IO 操作命令
28
20
  from .io_ops import concat, diff
29
21
 
22
+ # 血缘追踪命令
23
+ from .lineage import history
24
+
30
25
  # Pipeline 命令
31
26
  from .pipeline import run
27
+ from .sample import head, sample, tail
32
28
 
33
- # 血缘追踪命令
34
- from .lineage import history
29
+ # Skill 命令
30
+ from .skill import install_skill, skill_status, uninstall_skill
31
+
32
+ # 统计命令
33
+ from .stats import stats, token_stats
34
+
35
+ # 转换命令
36
+ from .transform import transform
35
37
 
36
38
  # 验证命令
37
39
  from .validate import validate
@@ -58,4 +60,8 @@ __all__ = [
58
60
  "history",
59
61
  # 验证
60
62
  "validate",
63
+ # Skill
64
+ "install_skill",
65
+ "uninstall_skill",
66
+ "skill_status",
61
67
  ]