ワンクリックで
generating-dataflow-pipeline
Reasoning-guided pipeline planner that generates standard DataFlow pipeline code
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Reasoning-guided pipeline planner that generates standard DataFlow pipeline code
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Reasoning-guided pipeline planner that generates standard DataFlow pipeline code. Use when the user asks to generate, create, or build a DataFlow pipeline, wants to process JSONL data with LLM operators, mentions PromptedGenerator / PromptedFilter / Text2MultiHopQAGenerator, or asks about DataFlow operator chains. Also use when user provides a .jsonl file and asks what pipeline to write.
DataFlow 开发专家上下文加载器。当用户在 DataFlow 仓库中进行开发时触发, 涵盖:新建算子/Pipeline/Prompt、诊断报错、规范审查、 以及感知仓库变更并建议更新知识库。 Trigger: user is developing in DataFlow repo, asks to create operator/pipeline/prompt, encounters errors, wants code review, or asks about operators.
Build production-grade DataFlow operator scaffolds (generate/filter/refine/eval) for Codex and coding agents. Trigger when users ask to create/new/scaffold operators, add OPERATOR_REGISTRY registration, generate DataFlowStorage-based CLI wrappers, or generate operator unit/registry/smoke tests.
Build reusable DataFlow prompt_template classes for existing operators with two-round AskUserQuestion intake, two-stage auditable outputs, and static acceptance checks. Trigger when users ask to generate/rewrite/optimize prompt_template or reuse operator logic with new prompt requirements.
DataFlow development expert context loader. Use when developing in the DataFlow repo: creating operators/pipelines/prompts, diagnosing errors, code review, or detecting repo changes to update the knowledge base. Trigger: user is developing in DataFlow repo, asks to create operator/pipeline/prompt, encounters errors, wants code review, or asks about operators.
Build production-grade DataFlow operator scaffolds (generate/filter/refine/eval). Use when users ask to create/new/scaffold operators, add OPERATOR_REGISTRY registration, generate DataFlowStorage-based CLI wrappers, or generate operator unit/registry/smoke tests.
| name | generating-dataflow-pipeline |
| description | Reasoning-guided pipeline planner that generates standard DataFlow pipeline code |
| version | 1.0.0 |
This skill is used when users provide:
The skill must:
first_entry_file_name set to the user-provided file pathUsers provide:
Target: [Clear task description]
Sample file: [Path to JSONL file, e.g., ./data/input.jsonl]
Expected outputs: [Optional field list]
Important: The sample file is a JSONL file (one JSON object per line), not a JSON array.
Six Core Primitives (high-coverage operators for most data science tasks):
PromptedGenerator - Single-field LLM generationFormatStrPromptedGenerator - Multi-field template generationText2MultiHopQAGenerator - Multi-hop QA pair constructionPromptedFilter - LLM-based quality filteringGeneralFilter - Rule-based filteringFileOrURLToMarkdownConverterFlash → KBCChunkGenerator → KBCTextCleanerThese are preferred primitives, not fixed workflows. They can be used repeatedly and combined flexibly.
When a specialized operator exists for the task, it MUST be used over generic operators. Do NOT use PromptedGenerator to replicate functionality that a dedicated operator already provides.
Decision table (check in order, use the first match):
| Task / Scenario | Required Operator | Do NOT use |
|---|---|---|
| Generate QA pairs from text | Text2MultiHopQAGenerator | PromptedGenerator with QA prompt |
| Convert file path / URL to text | KBC trio (FileOrURLToMarkdownConverterFlash → KBCChunkGenerator → KBCTextCleaner) | PromptedGenerator to summarize files |
| Score / evaluate using multiple fields | FormatStrPromptedGenerator + GeneralFilter | PromptedFilter (single input_key only) |
| Filter by deterministic rule on existing fields | GeneralFilter | PromptedFilter |
| Generate new content from a single field | PromptedGenerator | — |
| Generate new content from multiple fields | FormatStrPromptedGenerator | Multiple PromptedGenerator steps |
Key principle: PromptedGenerator is the fallback for generic single-field generation. If the target mentions "QA", "question-answer", "问答" — always reach for Text2MultiHopQAGenerator first. In MCP/WebUI mode, browse top-level category core_text; do not hallucinate query categories like core_text/generate.
If both core_text and another top-level category seem plausible, call recommend_operator_categories with the task description plus dataset columns before spending more MCP context. Treat its result as a hard budget: inspect at most the top 1-2 suggested categories, then switch to get_operator_detail_by_name instead of further category scans.
When this skill is used through the WebUI agent rather than raw local codegen, first call get_dataset_columns for the registered dataset id and treat those returned column names as the ground-truth initial field set.
PromptedGenerator or FormatStrPromptedGenerator to create missing semantic fieldsvalidate_pipeline_config before create/update; field-flow errors should be fixed before commitvalidate_pipeline_config returns missing_input_field, treat its suggested_fields and repair_hint as the first repair path. Fix the binding and re-validate; do not broaden MCP browsing or switch categories just because a field name was wrong.✗ WRONG: Filter by "quality_score" before generating it
✓ CORRECT: Generate "quality_score" first, then filter by it
The KBC trio must always be used in this exact order:
FileOrURLToMarkdownConverterFlash — converts file path / URL → Markdown text (field: text_path)KBCChunkGenerator — splits Markdown into chunks (field: raw_chunk)KBCTextCleaner — LLM-cleans each chunk (field: cleaned_chunk)Rules:
output_key becomes the next step's input_key.text_path, raw_chunk, cleaned_chunk) unless explicitly requested otherwise.GeneralFilter lambda rules must ONLY reference fields that exist in sample data or are produced by upstream steps.
PromptedFilter only accepts a single input_key. For multi-field evaluation (e.g., scoring QA pairs), use FormatStrPromptedGenerator to score + GeneralFilter to filter.
Important caveat for Text2MultiHopQAGenerator output: The QA_pairs column is a nested list of dicts, not separate question/answer columns. You cannot directly pass question or answer as kwargs to FormatStrPromptedGenerator after Text2MultiHopQAGenerator. To score or filter individual QA pairs, use post-processing (explode the list into rows, then optionally score/filter in a second pipeline or in Python code).
Two-stage output required:
Output this first:
{
"ops": ["OperatorA", "OperatorB", "OperatorC"],
"field_flow": "field_a -> field_b -> field_c",
"reason": "Why this ordered operator chain satisfies the target, how field dependencies are satisfied, and why prompted operators are or are not used."
}
Before generating pipeline code, the agent MUST confirm the user's LLM serving configuration. If any LLM-dependent operator is used (e.g., PromptedGenerator, FormatStrPromptedGenerator, PromptedFilter, Text2MultiHopQAGenerator, KBCTextCleaner), the following information is required:
Required information (ask the user if not provided):
api_url: The LLM API endpoint (e.g., https://api.openai.com/v1/chat/completions or a self-hosted/proxy URL)model_name: The model to use (e.g., gpt-4o, gpt-4o-mini, deepseek-chat)OPENAI_API_KEY, DF_API_KEY, etc.), or ask the user to provide itWhen to ask:
api_url or model_name in their request, ask before generating codePipeline 中使用了 LLM 算子,请确认以下配置:
1. API 端点 (api_url):例如 https://api.openai.com/v1/chat/completions
2. 模型名称 (model_name):例如 gpt-4o
3. API Key 环境变量名:例如 OPENAI_API_KEY(默认为 DF_API_KEY)
echo $OPENAI_API_KEY or equivalentWhen NOT to ask (skip the pre-check):
GeneralFilter, KBCChunkGenerator, FileOrURLToMarkdownConverterFlash)WebUI deployment context:
When the pipeline is intended for WebUI execution (not local python pipeline.py), the serving must also be registered in the WebUI Serving Manager. After generating code, remind the user:
api_url, model_name, and api_keyFailed to process parameter: llm_serving errors at execution timelist_servings; the backend now provides both list_serving and a backward-compatible alias, but prefer list_serving in new prompts/skillscreate_pipeline config structure (MANDATORY — WebUI/MCP mode)When building a pipeline via the MCP create_pipeline / update_pipeline tools (NOT
local codegen), the operator params JSON has two buckets — init and run — and
where each value goes is determined by the operator's real signature, which you
MUST fetch first with get_operator_detail_by_name. Getting this wrong makes the
pipeline crash at execution time, not at create time.
Hard rules:
LLM serving goes in init.llm_serving, as the serving id (not the name).
Call list_serving, find the serving the user named, and use its id
(e.g. "0510fc816d385c6f"). NEVER put serving in a run param such as
serving_name — the operator's run() does not accept it and
run(**run_params) will raise "unexpected keyword argument".
system_prompt / user_prompt / json_schema / prompt_template are init
params, not run params for generator operators (e.g. PromptedGenerator,
ReasoningAnswerGenerator). Only put a value in run if it appears in the
operator's run() signature returned by get_operator_detail_by_name.
Never send None (or empty string) for an optional text param that has a
non-empty default. If you don't have a real user_prompt, OMIT the param
entirely so the operator uses its own default (e.g. user_prompt=""). Sending
None can cause None + str TypeErrors inside the operator.
prompt_template must be a plain allowed class name string (e.g.
"MathAnswerGeneratorPrompt"), taken from the operator detail's
allowed_prompts. Do NOT send the <class '...'> repr — the validator rejects it.
Always call validate_pipeline_config before create_pipeline and fix any
reported error (not just warnings) before creating.
Minimal correct example (PromptedGenerator, one LLM op):
operators: [{
name: "PromptedGenerator",
params: {
init: [
{ name: "llm_serving", value: "<serving_id_from_list_serving>" },
{ name: "system_prompt", value: "You are a helpful assistant." }
// user_prompt omitted -> operator default "" is used
],
run: [
{ name: "input_key", value: "instruction" },
{ name: "output_key", value: "generated_answer" }
]
}
}]
All generated Python code must follow the standard pipeline organization shown in the examples/ folder of this skill package.
Input Data Format:
first_entry_file_name MUST be set to the user-provided file path (the JSONL sample file).jsonl (one JSON object per line, NOT an array)Required structure: __init__ (storage + llm_serving + operators) → forward (sequential operator.run(storage=self.storage.step(), ...)) → if __name__ == "__main__" entry point.
DO NOT: generate custom runtime executors, forward(plan) style frameworks, or dynamic dispatch engines.
Use repository-valid constructor/run signatures only. Never invent parameter names.
FileStorage
FileStorage(
first_entry_file_name="...jsonl",
cache_path="./cache",
file_name_prefix="dataflow_cache_step",
cache_type="jsonl"
)
APILLMServing_request
APILLMServing_request(
api_url="...", # user's LLM API endpoint
key_name_of_api_key="OPENAI_API_KEY", # env var name holding the API key (reads os.environ at runtime)
model_name="gpt-4o",
max_workers=10
)
Note: key_name_of_api_key is the name of the environment variable (not the key itself).
The class default is "DF_API_KEY", but most deployments use "OPENAI_API_KEY".
Always match the env var the user has set. The api_url should be the user's actual
API endpoint, not a placeholder.
API Key handling in different contexts:
pipeline.py: Set os.environ["DF_API_KEY"] = "sk-xxx" before running, or use
key_name_of_api_key to match an existing env var. Never hardcode the key in source code.api_key field when creating/editing a serving. The WebUI backend injects it into the
environment at execution time. Do NOT include api_key or key_name_of_api_key in
operators.json — the engine handles this via the serving config.1) PromptedGenerator
PromptedGenerator(llm_serving, system_prompt="You are a helpful agent.", user_prompt="", json_schema=None)json_schema rule: If using json_schema, every "type": "object" in the schema MUST include "additionalProperties": False. Omitting it causes API 500 errors and infinite retries.run(storage=self.storage.step(), input_key="raw_content", output_key="generated_content")input_key column must exist. Generated rows written to output_key.2) FormatStrPromptedGenerator
FormatStrPromptedGenerator(llm_serving, system_prompt="You are a helpful agent.", prompt_template=FormatStrPrompt(...), json_schema=None)json_schema rule: If using json_schema, every "type": "object" in the schema MUST include "additionalProperties": False. Omitting it causes API 500 errors and infinite retries.run(storage=self.storage.step(), output_key="generated_content", **input_keys)**input_keys: each kwarg maps a template variable name (key) to a dataframe column name (value). Internally does row[input_keys[key]] per row, then prompt_template.build_prompt(need_fields, **key_dict).{placeholder} names in FormatStrPrompt.f_str_template. Kwarg values must be existing dataframe columns.prompt_template cannot be None (raises ValueError). Must pass an instantiated FormatStrPrompt(f_str_template="...").from dataflow.prompts.core_text import FormatStrPrompt3) Text2MultiHopQAGenerator
Text2MultiHopQAGenerator(llm_serving=self.llm_serving, seed=0, lang="en", prompt_template=None, num_q=5)
llm_serving — LLM serving instance (required)seed (int, default 0) — random seed for reproducibilitylang (str, default "en") — language for generation prompt; controls sentence splitting ("." for "en", "。" for "zh")prompt_template — custom DIYPromptABC instance; pass None to use default Text2MultiHopQAGeneratorPromptnum_q (int, default 5) — maximum number of QA pairs to keep per input row (truncates the generated list; actual generation count depends on sentence triples in the text)run(storage, input_key="cleaned_chunk", output_key="QA_pairs", output_meta_key="QA_metadata")
input_key must exist (cleaned text chunk column)output_key — column containing a nested list of QA dicts per row. Each dict has keys: question (str), reasoning_steps (list of {step: str}), answer (str), supporting_facts (list of str), type (str)output_meta_key — column containing metadata dict per row with keys: source, timestamp, complexityoutput_key / output_meta_key must NOT pre-exist.output_key column. The list items are dicts — question, answer, etc. are NOT separate dataframe columns. Downstream operators like FormatStrPromptedGenerator cannot directly reference question or answer as column names. To use individual QA pairs downstream, you must post-process (explode the list into separate rows) outside the operator chain.qa_pairs: []):
. or 2+ 。)4) PromptedFilter
PromptedFilter(llm_serving, system_prompt="...", min_score=1, max_score=5)run(storage=self.storage.step(), input_key="raw_content", output_key="eval")input_key must exist. output_key is numeric score column; rows outside [min_score, max_score] are filtered out.input_key is empty, null, or falsy are silently dropped before scoring — they will not appear in the output at all. Ensure the upstream operator produces non-empty values for every row, or expect row count to decrease.system_prompt controls the evaluation rubric. Default: "Please evaluate the quality of this data on a scale from 1 to 5.". Set a custom prompt for better scoring accuracy (e.g., specify evaluation criteria).5) GeneralFilter
GeneralFilter([lambda df: df["score"] >= 4, ...])run(storage=self.storage.step())pd.Series. Referenced fields must already exist.6) KBC Trio (always used in this order)
Step 1 — FileOrURLToMarkdownConverterFlash
FileOrURLToMarkdownConverterFlash(intermediate_dir="../example_data/KBCleaningPipeline/flash/", mineru_model_path="opendatalab/MinerU2.5-2509-1.2B", batch_size=4, replicas=1, num_gpus_per_replica=1.0, engine_gpu_util_rate_to_ray_cap=0.9)llm_serving — this operator has no LLM dependency.mineru_model_path is required — passing None raises ValueError. Use a HuggingFace model ID or local path.run(storage=self.storage.step(), input_key="source", output_key="text_path").pdf, .png, .jpg, .jpeg, .webp, .gif, .html, .xml, .txt, .md).Step 2 — KBCChunkGenerator
KBCChunkGenerator(chunk_size=512, chunk_overlap=50, split_method="token", min_tokens_per_chunk=100, tokenizer_name="bert-base-uncased")run(storage=self.storage.step(), input_key="text_path", output_key="raw_chunk")split_method options: "token", "sentence", "semantic", "recursive".Step 3 — KBCTextCleaner
KBCTextCleaner(llm_serving, lang="en")run(storage=self.storage.step(), input_key="raw_chunk", output_key="cleaned_chunk")# Base components
from dataflow.utils.storage import FileStorage
from dataflow.serving import APILLMServing_request
# Operators
from dataflow.operators.core_text import PromptedGenerator, FormatStrPromptedGenerator, Text2MultiHopQAGenerator, PromptedFilter, GeneralFilter
from dataflow.operators.knowledge_cleaning import FileOrURLToMarkdownConverterFlash, KBCChunkGenerator, KBCTextCleaner
The sibling skill core_text (located at ../core_text/) provides detailed per-operator API documentation that supplements the summary signatures above.
Each operator directory contains:
SKILL.md — Full English reference: constructor signature, run() signature, execution logic, mandatory rules, return value semanticsSKILL_zh.md — Chinese translation of the referenceexamples/good.md — Best-practice pipeline exampleexamples/bad.md — Common mistakes and failure casesWhen to consult core_text:
BenchAnswerGenerator, ChunkedPromptedGenerator, EmbeddingGenerator, RetrievalGenerator, RandomDomainKnowledgeRowGenerator)bad.md examples document the most frequent mistakesNote: The 6 core primitives documented above in "Operator Parameter Signature Rule" remain the primary reference for standard pipeline generation. The core_text skill provides deeper detail and covers additional operators not in the core set.
Path: ../core_text/generate/
Available operator references (8 operators):
| Operator | Subdirectory | Description |
|---|---|---|
PromptedGenerator | prompted-generator/ | Single-field LLM generation — full execution logic, skip-falsy rules |
FormatStrPromptedGenerator | format-str-prompted-generator/ | Multi-field template generation — placeholder-to-column mapping details,@prompt_restrict validation |
Text2MultiHopQAGenerator | text2multihopqa-generator/ | Multi-hop QA pair construction — text filtering thresholds (100–200k chars), output structure, row-count behavior |
BenchAnswerGenerator | bench-answer-generator/ | Benchmark answer generation —eval_type variants, conditional field requirements |
ChunkedPromptedGenerator | chunked-prompted-generator/ | Long document chunk-by-chunk processing — token-based splitting, file I/O conventions |
EmbeddingGenerator | embedding-generator/ | Text vectorization — supported serving backends,/v1/embeddings endpoint usage |
RandomDomainKnowledgeRowGenerator | random-domain-knowledge-row-generator/ | Domain-specific row generation — seed dataframe requirements,generation_num constraints |
RetrievalGenerator | retrieval-generator/ | Async RAG generation —LightRAGServing.create() async initialization, await run() requirement |
Path: ../core_text/eval/
Available operator references (5 operators):
| Operator | Subdirectory | Description |
|---|---|---|
BenchDatasetEvaluator | bench-dataset-evaluator/ | Benchmark answer comparison —match (math verification) and semantic (LLM-based) modes |
BenchDatasetEvaluatorQuestion | bench-dataset-evaluator-question/ | Extended benchmark evaluator — adds question context and subquestion support over BenchDatasetEvaluator |
PromptedEvaluator | prompted-evaluator/ | LLM-based row scoring — writes score into new column without removing rows |
Text2QASampleEvaluator | text2qa-sample-evaluator/ | QA pair quality evaluation — 4 dimensions, 8 output columns (grades + feedbacks per dimension) |
UnifiedBenchDatasetEvaluator | unified-bench-dataset-evaluator/ | Unified benchmark evaluation — 6 eval_type variants, writes 4 output columns |
Path: ../core_text/filter/
Available operator references (3 operators):
| Operator | Subdirectory | Description |
|---|---|---|
GeneralFilter | general-filter/ | Rule-based row filtering — lambda conditions combined with AND, removes rows only, adds no new columns |
KCenterGreedyFilter | kcentergreedy-filter/ | Diversity-based downsampling — K-Center Greedy algorithm, requires pre-computed embedding vectors |
PromptedFilter | prompted-filter/ | LLM semantic filtering — internally uses PromptedEvaluator, retains rows with scores in [min_score, max_score] |
Path: ../core_text/refine/
Available operator references (2 operators):
| Operator | Subdirectory | Description |
|---|---|---|
PandasOperator | pandas-operator/ | Custom DataFrame transformation — applies a sequential list of functions, no LLM calls |
PromptedRefiner | prompted-refiner/ | LLM text refinement — rewrites text in-place, overwrites original column with refined results |
Analyze sample data content to determine task nature:
File path fields (e.g., pdf_path, image_path, doc_path):
FileOrURLToMarkdownConverterFlash → KBCChunkGenerator → KBCTextCleaner (supports .pdf, .png, .jpg, .jpeg, .webp, .gif, .html, .xml, .txt, .md)Plain text fields (e.g., text, content, review_text):
PromptedGenerator, PromptedFilter, Text2MultiHopQAGenerator, FormatStrPromptedGenerator, GeneralFilterMultiple semantic fields (e.g., instruction, output, question, answer):
FormatStrPromptedGenerator for combining fieldsGeneralFilter for field-based rulesSee examples/ folder for complete workflows:
examples/basic_generate_and_filter.md — PromptedGenerator + PromptedFilter (simplest pattern)examples/multifield_scoring.md — FormatStrPromptedGenerator with multi-field scoringexamples/multi_stage_pipeline.md — Multiple PromptedGenerator stages + GeneralFilterexamples/kbc_pdf_to_qa.md — KBC trio (FileOrURLToMarkdownConverterFlash + KBCChunkGenerator + KBCTextCleaner) + Text2MultiHopQAGenerator + PromptedFilter (scores nested QA_pairs column per chunk)These are strategy guidance, not templates to copy blindly. Generated code must follow standard pipeline structure.