数据处理
数据处理算子
基类算子
lazyllm.tools.data.LazyLLMDataBase
数据处理算子基类。为注册到 data_register 的算子提供统一行为,包括并发执行、结果保存/恢复、进度记录和错误收集。
主要方法和行为:
- forward(self, input, **kwargs): 处理单条数据(子类/函数实现)。
- forward_batch_input(self, inputs, **kwargs): 处理批量数据并返回最终结果(子类/函数实现)。
- call(self, inputs): 统一入口,会根据子类是否实现 forward 或 forward_batch_input 选择执行逻辑;支持并发执行、断点续传和保存结果。
- set_output(self, path): 设置导出路径,调用后 call 返回导出文件路径而不是内存结果。
构造函数参数:
- _concurrency_mode (str): 并发模式,'process'|'thread'|'single'。
- _save_data (bool): 是否保存中间结果到磁盘以便 Resume。
- _max_workers (int|None): 最大并发工作进程/线程数,None 表示使用默认。
- _ignore_errors (bool): 是否忽略任务异常。
- **kwargs (dict): 其它传递给算子的参数。
配置项(通过 lazyllm.config):
- data_process_path (str): 存储处理结果的根路径。
- data_process_resume (bool): 是否开启 Resume 功能,从进度文件继续处理。
Examples:
from lazyllm.tools.data import LazyLLMDataBase
# simple usage: subclass and implement forward
class EchoOp(LazyLLMDataBase):
def forward(self, data):
return {'text': data.get('text', '')}
op = EchoOp(_save_data=True)
res = op([{'text': 'hello'}]) # returns list or exported path depending on set_output
Source code in lazyllm/tools/data/base_data.py
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 | |
forward(input_data, **kwargs)
子类需要实现的方法,处理单条数据。返回值支持:
- dict: 表示处理后的单条结果。
- list: 表示将一条输入展开为多条输出。
- None: 表示保留原始输入(不修改)。
- 抛出异常或返回错误对象会被记录到错误文件并跳过(依赖配置和调用者)。
Parameters:
-
input(dict) –单条输入数据字典。
-
**kwargs(dict, default:{}) –其它用户传入的参数。
Examples:
from lazyllm.tools.data import LazyLLMDataBase
class MyOp(LazyLLMDataBase):
def forward(self, data):
# return dict or list or None
return {'text': data.get('text', '').upper()}
op = MyOp()
print(op([{'text': 'a'}]))
Source code in lazyllm/tools/data/base_data.py
forward_batch_input(inputs, **kwargs)
子类可实现的批量处理方法,用于在非逐条并发场景下直接接收整个输入列表并返回最终结果列表(可用于自定义批量逻辑或外部服务一次性处理)。
Parameters:
-
inputs(list[dict]) –输入数据列表。
-
**kwargs(dict, default:{}) –其它用户传入的参数。
Examples:
from lazyllm.tools.data import LazyLLMDataBase
class BatchOp(LazyLLMDataBase):
def forward_batch_input(self, inputs):
# implement batch processing and return a list
return [{'text': i.get('text', '').lower()} for i in inputs]
op = BatchOp()
print(op([{'text': 'A'}, {'text': 'B'}]))
Source code in lazyllm/tools/data/base_data.py
set_output(output_path)
设置输出路径,用于把最终结果导出为 jsonl 文件并返回文件路径。
Parameters:
-
output_path(str) –文件夹路径或具体 .jsonl 文件路径。若为文件夹,则在该文件夹下创建以类名命名的 jsonl 文件。
行为:
- 如果传入的是文件夹路径,则在该文件夹下创建以类名命名的 jsonl 文件。
- 如果传入的是以 .jsonl 结尾的路径,则直接写入该文件(必要时会创建目录)。
- 返回写入的绝对路径字符串。
Examples:
from lazyllm.tools.data import Demo2
# export to a directory (will create DemoClass.jsonl)
op = Demo2.rich_content(input_key='text').set_output('./out_dir')
path = op([{'text': 'sample'}])
print(path) # ./out_dir/RichContent.jsonl or similar
# export to a specific file
op = Demo2.rich_content(input_key='text').set_output('./out_dir/results.jsonl')
path = op([{'text': 'sample'}])
print(path) # ./out_dir/results.jsonl
Source code in lazyllm/tools/data/base_data.py
演示算子
lazyllm.tools.data.operators.demo_ops
AddSuffix
Bases: Demo2
通过类方式实现的算子,为指定字段添加后缀。支持并发配置(通过构造参数)。
Parameters:
-
suffix(str) –要添加的后缀
-
input_key(str, default:'content') –文本字段名
-
_max_workers(int | None) –可选,最大并发数
-
_concurrency_mode(str, default:'process') –可选,并发模式
-
_save_data(bool) –可选,是否保存结果
Examples:
from lazyllm.tools.data import Demo2
op = Demo2.AddSuffix(suffix='!!!', input_key='text', _max_workers=2)
data = [{'text': 'wow'}]
res = op(data)
print(res)
# [{'text': 'wow!!!'}]
Source code in lazyllm/tools/data/operators/demo_ops.py
build_pre_suffix(data, input_key='content', prefix='', suffix='')
对输入列表中每项在指定字段前后添加前缀和后缀。此算子以批处理函数注册(forward_batch_input)。
Parameters:
-
data(list[dict]) –输入列表
-
input_key(str, default:'content') –文本字段名
-
prefix(str, default:'') –要添加的前缀
-
suffix(str, default:'') –要添加的后缀
Examples:
from lazyllm.tools.data import Demo1
op = Demo1.build_pre_suffix(input_key='text', prefix='Hello, ', suffix='!')
data = [{'text': 'world'}]
res = op(data)
print(res)
# [{'text': 'Hello, world!'}]
Source code in lazyllm/tools/data/operators/demo_ops.py
error_prone_op(data, input_key='content')
一个用于测试的算子:在特定输入(content == 'fail')时抛出异常,否则返回处理后的字典结果。用于验证错误收集与跳过逻辑。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'content') –文本字段名
Examples:
from lazyllm.tools.data import Demo2
op = Demo2.error_prone_op(input_key='text', _save_data=True, _concurrency_mode='single')
data = [{'text': 'ok'}, {'text': 'fail'}, {'text': 'ok2'}]
res = op(data)
print(res)
# [{'text': 'Processed: ok'}, {'text': 'Processed: ok2'}]
# valid results skip the failed item; error details written to error file
Source code in lazyllm/tools/data/operators/demo_ops.py
process_uppercase(data, input_key='content')
将输入文本字段转换为大写。适用于单条处理函数注册(forward)。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'content') –文本字段名,默认 'content'
Examples:
from lazyllm.tools.data import Demo1
op = Demo1.process_uppercase(input_key='text')
data = [{'text': 'hello'}]
res = op(data)
print(res)
# [{'text': 'HELLO'}]
Source code in lazyllm/tools/data/operators/demo_ops.py
rich_content(data, input_key='content')
将单条输入拆分为多条输出,生成富内容表示(原始 + 若干派生)。适用于返回 list 的 forward。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'content') –文本字段名
Examples:
from lazyllm.tools.data import Demo2
op = Demo2.rich_content(input_key='text')
data = [{'text': 'This is a test.'}]
res = op(data)
print(res)
# [
# {'text': 'This is a test.'},
# {'text': 'This is a test. - part 1'},
# {'text': 'This is a test. - part 2'}
# ]
Source code in lazyllm/tools/data/operators/demo_ops.py
偏好数据处理算子
lazyllm.tools.data.operators.preference_ops
IntentExtractor
Bases: PreferenceOps
偏好数据处理算子:意图提取器。
从输入数据 dict 的指定字段中提取“核心意图”,并将结果写回到输出字段中,便于后续生成多候选回复与偏好对构造。
注意:
- 该算子内部使用模型 + JSON 格式化器,期望模型输出为 JSON dict;若无法解析为 dict,则输出为 None。
- 默认并发模式为 thread。
Parameters:
-
model–LazyLLM 模型对象(必需),会被 share() 后复用。
-
input_key(str, default:'content') –输入文本字段名,默认 'content'。
-
output_key(str, default:'intent') –输出意图字段名,默认 'intent'。
-
**kwargs–传递给基类算子的其它参数(如 _max_workers、_save_data 等)。
Examples:
from lazyllm.tools.data.operators.preference_ops import IntentExtractor
# model 需要由你的项目环境提供,例如 lazyllm.xxx(...) 得到的模型对象
op = IntentExtractor(model=model, input_key='content', output_key='intent')
print(op({'content': 'I want to stay at a hotel in Beijing.'}))
# [{
# 'content': 'I want to stay at a hotel in Beijing.',
# 'intent': {
# 'intent': 'book_hotel',
# 'entities': [{'entity': 'location', 'value': 'Beijing'}]
# }
# }]
Source code in lazyllm/tools/data/operators/preference_ops.py
PreferencePairConstructor
Bases: PreferenceOps
偏好数据处理算子:偏好对构造器(chosen / rejected)。
根据候选回复列表及其评分列表,构造一对 (chosen, rejected),并输出为偏好数据格式:
- instruction: 指令文本(默认取 intent 字段)
- chosen: 更优的回复
- rejected: 更差的回复
支持两种策略:
- max_min: 选择最高分作为 chosen、最低分作为 rejected(要求最高分 > 最低分)。
- threshold: 从高到低寻找分差 >= threshold 的一对,满足则返回。
注意:若输入为空、长度不一致、或无法构造有效 pair,则返回空列表 [](用于在流水线中过滤无效样本)。
Parameters:
-
strategy(str, default:'max_min') –'max_min' 或 'threshold',默认 'max_min'。
-
threshold(float, default:0.5) –strategy == 'threshold' 时使用的最小分差,默认 0.5。
-
instruction_key(str, default:'intent') –指令字段名,默认 'intent'。
-
response_key(str, default:'responses') –候选回复列表字段名,默认 'responses'。
-
score_key(str, default:'evaluation') –评分列表字段名,默认 'evaluation'。
-
output_chosen_key(str, default:'chosen') –输出 chosen 字段名,默认 'chosen'。
-
output_rejected_key(str, default:'rejected') –输出 rejected 字段名,默认 'rejected'。
-
**kwargs–传递给基类算子的其它参数。
Examples:
from lazyllm.tools.data.operators.preference_ops import PreferencePairConstructor
op = PreferencePairConstructor(strategy='max_min', instruction_key='intent',
response_key='responses', score_key='evaluation')
data = {
'intent': 'book a hotel',
'responses': ['good response', 'bad response'],
'evaluation': [10, 6],
}
print(op(data))
# [{
# 'instruction': 'book a hotel',
# 'chosen': 'good response',
# 'rejected': 'bad response'
# }]
Source code in lazyllm/tools/data/operators/preference_ops.py
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 | |
PreferenceResponseGenerator
Bases: PreferenceOps
偏好数据处理算子:多候选回复生成器。
根据上一步得到的意图(或任意指令文本),生成 n 条候选回复列表写入到输出字段中。
Parameters:
-
model–LazyLLM 模型对象(必需),会被 share() 后复用。
-
n(int, default:3) –生成候选回复条数,默认 3。
-
temperature(float, default:1.0) –采样温度,默认 1.0。
-
system_prompt(str | None, default:None) –可选系统提示词;提供则会对模型调用 .prompt(system_prompt)。
-
input_key(str, default:'intent') –输入字段名,默认 'intent'。
-
output_key(str, default:'responses') –输出字段名,默认 'responses'。
-
**kwargs–传递给基类算子的其它参数。
Examples:
from lazyllm.tools.data.operators.preference_ops import PreferenceResponseGenerator
op = PreferenceResponseGenerator(model=model, n=3, temperature=0.8, input_key='intent', output_key='responses')
print(op({'intent': 'book a hotel'}))
# [{
# 'intent': {'intent': 'book a hotel'},
# 'responses': [
# "<think>Okay, the user wants to book a hotel. ...",
# "<think>Okay, the user wants to book a hotel. ..."
# ]
# }]
Source code in lazyllm/tools/data/operators/preference_ops.py
ResponseEvaluator
Bases: PreferenceOps
偏好数据处理算子:候选回复评测器。
对同一条指令下的多个候选回复逐一打分,输出每条回复的分数列表,便于后续构造 chosen/rejected。
评分维度(总分 10 分):
- 有用性 (Helpfulness) 4 分
- 真实性 (Truthfulness) 3 分
- 流畅度 (Fluency) 3 分
注意:
- 该算子内部使用模型 + JSON 格式化器;每条回复都期望输出包含 total_score 的 dict。
- 如果某条回复无法解析 total_score,会记录 warning,并为该条回复记 0 分。
Parameters:
-
model–LazyLLM 模型对象(必需),会被 share() 后复用。
-
input_key(str, default:'content') –指令/原始内容字段名,默认 'content'。
-
response_key(str, default:'responses') –候选回复列表字段名,默认 'responses'。
-
output_key(str, default:'evaluation') –输出评分列表字段名,默认 'evaluation'。
-
**kwargs–传递给基类算子的其它参数。
Examples:
from lazyllm.tools.data.operators.preference_ops import ResponseEvaluator
op = ResponseEvaluator(model=model, input_key='intent', response_key='responses', output_key='evaluation')
data = {
'intent': {'intent': 'book a hotel'},
'responses': [
'I can help you book a hotel in Beijing.',
'Here are some hotels for you.'
],
}
print(op(data))
# [{
# 'intent': {'intent': 'book a hotel'},
# 'responses': [
# 'I can help you book a hotel in Beijing.',
# 'Here are some hotels for you.'
# ],
# 'evaluation': [10, 8]
# }]
Source code in lazyllm/tools/data/operators/preference_ops.py
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | |
工具调用数据处理算子
lazyllm.tools.data.operators.tool_use_ops
ChainedLogicAssembler
Bases: ToolUseOps
工具调用数据生成算子:顺序任务生成器。
基于原子任务列表,生成“后继任务关系”与对应的组合任务列表,用于构造线性或有依赖关系的任务链。
输出 JSON 典型结构:
- items: 列表,每项为:
- task: 当前原子任务
- next_task: 紧随其后的任务
- composed_task: 由 task + next_task 组合而成的描述
Parameters:
-
model–LazyLLM 模型对象(必需)。
-
input_key(str, default:'atomic_tasks') –输入原子任务字段名,默认 'atomic_tasks'。
-
output_key(str, default:'sequential_tasks') –输出顺序任务列表字段名,默认 'sequential_tasks'。
-
system_prompt(str | None, default:None) –可选系统提示词。
-
**kwargs–传递给基类算子的其它参数。
Examples:
from lazyllm.tools.data.operators.tool_use_ops import ChainedLogicAssembler
atomic_tasks = [
{'task': '获取出发地与目的地'},
{'task': '确认出行日期'},
{'task': '筛选符合条件的车次'},
]
op = ChainedLogicAssembler(model=model, input_key='atomic_tasks', output_key='sequential_tasks')
print(op({'atomic_tasks': atomic_tasks}))
# {
# 'atomic_tasks': [...],
# 'sequential_tasks': [
# {'task': '获取出发地与目的地', 'next_task': '确认出行日期', 'composed_task': '先获取站点再确认日期'},
# {'task': '确认出行日期', 'next_task': '筛选符合条件的车次', 'composed_task': '在已知日期基础上筛选车次'},
# ...
# ]
# }
Source code in lazyllm/tools/data/operators/tool_use_ops.py
ContextualBeacon
Bases: ToolUseOps
工具调用数据生成算子:场景抽取器。
从一段对话文本中抽取可用于后续任务/工具调用数据生成的“场景信息”,并以结构化 JSON 形式写入输出字段。
输出 JSON 典型结构:
- scene: 一句话场景描述
- domain: 领域/主题
- user_profile: 用户角色/背景(可为空)
- assistant_goal: 助手应完成的目标
- constraints: 约束条件列表
- key_entities: 关键实体列表
Parameters:
-
model–LazyLLM 模型对象(必需),会被 share() 后复用并接 JSON 格式化器。
-
input_key(str, default:'content') –输入对话内容字段名,默认 'content'。
-
output_key(str, default:'scenario') –输出场景字段名,默认 'scenario'。
-
system_prompt(str | None, default:None) –可选,自定义系统提示词,不传则使用内置中文提示。
-
**kwargs–传递给基类算子的其它参数(如 _max_workers、_save_data 等)。
Examples:
from lazyllm.tools.data.operators.tool_use_ops import ContextualBeacon
op = ContextualBeacon(model=model, input_key='content', output_key='scenario')
item = {
'content': 'User: 我想订一张从北京到上海的高铁票,下午出发最好。\nAssistant: 好的,请问具体日期?'
}
print(op(item))
# Output Example:
# {
# 'content': 'User: 我想订一张从北京到上海的高铁票,下午出发最好。\nAssistant: 好的,请问具体日期?',
# 'scenario': {
# 'scene': '用户咨询高铁购票服务',
# 'domain': '出行/购票',
# 'user_profile': '普通出行乘客',
# 'assistant_goal': '帮助用户完成车次与时间筛选并完成购票',
# 'constraints': ['出发地为北京', '目的地为上海', '尽量下午出发'],
# 'key_entities': ['北京', '上海', '高铁', '下午']
# }
# }
Source code in lazyllm/tools/data/operators/tool_use_ops.py
DecompositionKernel
Bases: ToolUseOps
工具调用数据生成算子:原子任务生成器。
基于单个场景,生成一组粒度较小、目标单一的“原子任务”列表,用于后续任务编排与工具设计。
输出 JSON 典型结构:
- tasks: 原子任务列表,每项包含:
- task: 任务描述
- input: 任务输入(可为空)
- output: 任务输出(可为空)
- constraints: 相关约束列表
Parameters:
-
model–LazyLLM 模型对象(必需)。
-
input_key(str, default:'scenario') –输入场景字段名,默认 'scenario'。
-
output_key(str, default:'atomic_tasks') –输出原子任务列表字段名,默认 'atomic_tasks'。
-
n(int, default:5) –原子任务数量上限,默认 5。
-
system_prompt(str | None, default:None) –可选系统提示词。
-
**kwargs–传递给基类算子的其它参数。
Examples:
from lazyllm.tools.data.operators.tool_use_ops import DecompositionKernel
scenario = {
'scene': '用户咨询高铁购票服务',
'assistant_goal': '帮助用户完成车次筛选并购票',
}
op = DecompositionKernel(model=model, input_key='scenario', output_key='atomic_tasks', n=4)
print(op({'scenario': scenario}))
# {
# 'scenario': {...},
# 'atomic_tasks': [
# {'task': '获取用户出发地和目的地', 'input': '', 'output': '出发地与目的地', 'constraints': [...]},
# {'task': '确认出行日期与大致时间', ...},
# ...
# ]
# }
Source code in lazyllm/tools/data/operators/tool_use_ops.py
DialogueSimulator
Bases: ToolUseOps
工具调用数据生成算子:多轮对话生成器(含 Tool 调用)。
根据组合任务与可用函数列表,生成带有 User / Assistant / Tool 三种角色的多轮对话 JSON,用于构造工具调用训练数据。
输出 JSON 典型结构:
- messages: 列表,每项为:
- role: 'user' | 'assistant' | 'tool'
- content: 文本内容
- name: 工具名(仅 role == 'tool' 时可选)
Parameters:
-
model–LazyLLM 模型对象(必需)。
-
input_composition_key(str, default:'composition_task') –输入组合任务字段名,默认 'composition_task'。
-
input_functions_key(str, default:'functions') –输入函数列表字段名,默认 'functions'。
-
output_key(str, default:'conversation') –输出多轮对话字段名,默认 'conversation'。
-
n_turns(int, default:6) –期望的轮次数量(提示给模型),默认 6。
-
system_prompt(str | None, default:None) –可选系统提示词。
-
**kwargs–传递给基类算子的其它参数。
Examples:
from lazyllm.tools.data.operators.tool_use_ops import DialogueSimulator
composition_task = '根据用户需求查询并推荐合适的高铁车次'
functions = [
{
'name': 'query_train_tickets',
'description': '查询高铁车次',
'args': [...],
'returns': {...},
}
]
op = DialogueSimulator(model=model,
input_composition_key='composition_task',
input_functions_key='functions',
output_key='conversation',
n_turns=6)
print(op({'composition_task': composition_task, 'functions': functions}))
# {
# 'composition_task': '根据用户需求查询并推荐合适的高铁车次',
# 'functions': [...],
# 'conversation': {
# 'messages': [
# {'role': 'user', 'content': '我想订一张明天下午从北京到上海的高铁票'},
# {'role': 'assistant', 'content': '好的,我先为您确认出发时间与车次。'},
# {'role': 'tool', 'name': 'query_train_tickets', 'content': '{...工具返回...}'},
# ...
# ]
# }
# }
Source code in lazyllm/tools/data/operators/tool_use_ops.py
576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 | |
ProtocolSpecifier
Bases: ToolUseOps
工具调用数据生成算子:函数规格生成器。
根据组合任务及其子任务,生成一组适合用于工具调用(function calling)的函数规格列表。
输出 JSON 典型结构:
- functions: 列表,每项包含:
- name: 函数名称
- description: 函数用途描述
- args: 参数列表,每个参数包含 name/type/description
- returns: 返回值类型与描述
Parameters:
-
model–LazyLLM 模型对象(必需)。
-
input_composition_key(str, default:'composition_task') –输入组合任务字段名,默认 'composition_task'。
-
input_atomic_key(str, default:'atomic_tasks') –输入原子任务字段名,默认 'atomic_tasks'。
-
output_key(str, default:'functions') –输出函数规格列表字段名,默认 'functions'。
-
system_prompt(str | None, default:None) –可选系统提示词。
-
**kwargs–传递给基类算子的其它参数。
Examples:
from lazyllm.tools.data.operators.tool_use_ops import ProtocolSpecifier
composition_task = '根据用户出发地、目的地和日期查询可选高铁车次并返回候选列表'
atomic_tasks = [
{'task': '获取出发地与目的地'},
{'task': '确认出行日期'},
{'task': '调用车次查询接口并过滤结果'},
]
op = ProtocolSpecifier(model=model,
input_composition_key='composition_task',
input_atomic_key='atomic_tasks',
output_key='functions')
print(op({'composition_task': composition_task, 'atomic_tasks': atomic_tasks}))
# {
# 'composition_task': '根据用户出发地、目的地和日期查询可选高铁车次并返回候选列表',
# 'atomic_tasks': [...],
# 'functions': [
# {
# 'name': 'query_train_tickets',
# 'description': '根据出发地、目的地与日期查询高铁车次',
# 'args': [{'name': 'from_city', 'type': 'string', ...}, ...],
# 'returns': {'type': 'TrainList', 'description': '符合条件的车次列表'}
# },
# ...
# ]
# }
Source code in lazyllm/tools/data/operators/tool_use_ops.py
476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 | |
ScenarioDiverger
Bases: ToolUseOps
工具调用数据生成算子:场景扩展器。
在已有基础场景的基础上,生成若干个语义相关但细节不同的替代场景列表,便于扩充数据多样性。
输出 JSON 典型结构:
- scenarios: 场景列表,每项为包含 scene/domain/assistant_goal/constraints/key_entities 等字段的字典。
Parameters:
-
model–LazyLLM 模型对象(必需)。
-
input_key(str, default:'scenario') –输入场景字段名,默认 'scenario'(可为 dict 或 str)。
-
output_key(str, default:'expanded_scenarios') –输出扩展场景列表字段名,默认 'expanded_scenarios'。
-
n(int, default:3) –希望生成的场景数量上限,默认 3。
-
system_prompt(str | None, default:None) –可选系统提示词。
-
**kwargs–传递给基类算子的其它参数。
Examples:
from lazyllm.tools.data.operators.tool_use_ops import ScenarioDiverger
base = {
'scene': '用户咨询高铁购票服务',
'domain': '出行/购票',
'assistant_goal': '帮助用户完成车次筛选并购票',
}
op = ScenarioDiverger(model=model, input_key='scenario', output_key='expanded_scenarios', n=3)
print(op({'scenario': base}))
# {
# 'scenario': {...},
# 'expanded_scenarios': [
# {'scene': '用户预订跨城商务出差火车票', ...},
# {'scene': '用户为家人购买回乡火车票', ...},
# ...
# ]
# }
Source code in lazyllm/tools/data/operators/tool_use_ops.py
TopologyArchitect
Bases: ToolUseOps
工具调用数据生成算子:并行/顺序/混合任务组合生成器。
基于原子任务列表,自动生成三类任务组合:
- parallel_tasks: 可以并行执行的任务组合
- sequential_tasks: 具有明确先后依赖的任务组合
- hybrid_tasks: 同时包含并行与顺序关系的混合任务组合
Parameters:
-
model–LazyLLM 模型对象(必需)。
-
input_key(str, default:'atomic_tasks') –输入原子任务字段名,默认 'atomic_tasks'。
-
output_key(str, default:'para_seq_tasks') –输出任务组合字段名,默认 'para_seq_tasks'。
-
system_prompt(str | None, default:None) –可选系统提示词。
-
**kwargs–传递给基类算子的其它参数。
Examples:
from lazyllm.tools.data.operators.tool_use_ops import TopologyArchitect
atomic_tasks = [
{'task': '收集出行需求'},
{'task': '查询可选车次'},
{'task': '对比价格与时间'},
{'task': '完成下单支付'},
]
op = TopologyArchitect(model=model, input_key='atomic_tasks', output_key='para_seq_tasks')
print(op({'atomic_tasks': atomic_tasks}))
# {
# 'atomic_tasks': [...],
# 'para_seq_tasks': {
# 'parallel_tasks': ['同时查询不同日期/车次方案', ...],
# 'sequential_tasks': ['先确认日期再选车次', ...],
# 'hybrid_tasks': ['并行对比多个方案后统一决策并下单', ...]
# }
# }
Source code in lazyllm/tools/data/operators/tool_use_ops.py
ViabilitySieve
Bases: ToolUseOps
工具调用数据生成算子:组合任务可行性过滤器。
对一组“组合任务”进行可运行性与完备性评审,筛选出被认为合理可行的组合任务列表。
模型内部期望的中间 JSON 结构:
- items: 列表,每项包含 composed_task、is_valid、reason 等字段。
在算子输出中,仅保留 is_valid 为 true 且含有 composed_task 的项;如果模型未按预期输出,则尽量回退返回原 items 或原始 parsed 结果。
Parameters:
-
model–LazyLLM 模型对象(必需)。
-
input_composition_key(str, default:'composition_tasks') –输入组合任务字段名,默认 'composition_tasks'。
-
input_atomic_key(str, default:'atomic_tasks') –输入原子任务字段名(可选),默认 'atomic_tasks'。
-
output_key(str, default:'filtered_composition_tasks') –输出过滤后组合任务字段名,默认 'filtered_composition_tasks'。
-
system_prompt(str | None, default:None) –可选系统提示词。
-
**kwargs–传递给基类算子的其它参数。
Examples:
from lazyllm.tools.data.operators.tool_use_ops import ViabilitySieve
composition_tasks = ['先获取出发地和目的地再筛选车次', '直接随机推荐一个车次']
atomic_tasks = [
{'task': '获取出发地与目的地'}, {'task': '确认出行日期'}, {'task': '筛选符合条件的车次'}
]
op = ViabilitySieve(model=model,
input_composition_key='composition_tasks',
input_atomic_key='atomic_tasks',
output_key='filtered_composition_tasks')
print(op({'composition_tasks': composition_tasks, 'atomic_tasks': atomic_tasks}))
# {
# 'composition_tasks': [...],
# 'atomic_tasks': [...],
# 'filtered_composition_tasks': ['先获取出发地和目的地再筛选车次', ...]
# }
Source code in lazyllm/tools/data/operators/tool_use_ops.py
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 | |
Text2SQL 数据处理算子
lazyllm.tools.data.operators.text2sql_ops
SQLConsensusUnifier
Bases: Text2SQLOps
Text2SQL 数据处理算子:CoT 轨迹投票选择器。
对一组 CoT 轨迹(cot_responses)进行 SQL 解析与执行,基于执行结果的一致性与正确性,从中选出“最佳” CoT 及对应 SQL。
行为:
- 从每条 CoT 中解析 SQL(使用与 SQLForge 相同的解析逻辑)。
- 调用 database_manager.batch_execute_queries 执行 SQL,计算结果 signature 与 success。
- 使用投票策略 _vote_select 选择最终 CoT,并将:
- output_cot_key(默认 'cot_reasoning')设置为最佳 CoT 文本;
- 同时覆盖数据中的 'SQL' 字段为最佳 SQL。
Parameters:
-
database_manager–提供 SQL 执行能力的管理器(必需),需实现: - batch_execute_queries(list[(db_id, sql)])
-
**kwargs–其它传递给基类算子的参数。
Examples:
from lazyllm.tools.data.operators.text2sql_ops import SQLConsensusUnifier
op = SQLConsensusUnifier(database_manager=database_manager)
item = {
'db_id': 'db_1',
'cot_responses': [
'...CoT + ```sql SELECT count(*) FROM orders WHERE status = 'paid'```',
'...CoT + ```sql SELECT count(*) FROM orders```',
]
}
res = op(item)
print(res['cot_reasoning'][:200])
print(res['SQL'])
# "...首先识别需要统计已支付订单数量,其次在 orders 表中过滤 status = 'paid' ... ```sql SELECT count(*) FROM orders WHERE status = 'paid';```"
# "SELECT count(*) FROM orders WHERE status = 'paid';"
Source code in lazyllm/tools/data/operators/text2sql_ops.py
839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 | |
SQLContextAssembler
Bases: Text2SQLOps
Text2SQL 数据生成算子:Prompt 构造器。
根据数据库 Schema、自然语言问题与证据,构造下游 Text2SQL 模型的输入提示词(prompt)。
行为:
- 优先调用 database_manager.get_db_details(db_id) 获取 Schema 文本;若不存在则回退到 get_create_statements_and_insert_statements。
- 支持自定义 prompt_template;否则使用简单英文模板。
Parameters:
-
database_manager–提供 Schema 的管理器(必需),需实现: - get_db_details(db_id)(可选) - get_create_statements_and_insert_statements(db_id)
-
prompt_template–可选,自定义 prompt 构造器。
-
**kwargs–其它传递给基类算子的参数。
Examples:
from lazyllm.tools.data.operators.text2sql_ops import SQLContextAssembler
op = SQLContextAssembler(database_manager=database_manager)
item = {
'db_id': 'db_1',
'question': '有多少已支付的订单?',
'evidence': '订单表中 status 字段标记订单状态。'
}
res = op(item)
print(res['prompt'])
# Database Schema:
# CREATE TABLE orders (id INT, status TEXT, ...);
# ...
#
# Question: 有多少已支付的订单?
# Evidence: 订单表中 status 字段标记订单状态。
# Generate a SQL query for postgres.
Source code in lazyllm/tools/data/operators/text2sql_ops.py
634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 | |
SQLEffortRanker
Bases: Text2SQLOps
Text2SQL 数据分类算子:SQL 执行难度分类器。
基于 SQLContextAssembler 生成的 prompt、多次采样生成 SQL 并与金标 SQL 在数据库上对比执行结果,从“可被模型正确生成的次数”角度对样本执行难度进行分类。
主要流程:
- 使用输入的 prompt,重复调用模型生成 num_generations 条 SQL,并解析出 SQL 文本。
- 对每条 SQL 与金标 SQL 组成比较对 (db_id, predicted_sql, gold_sql),调用 database_manager.batch_compare_queries。
- 根据匹配次数 cnt_true 与难度阈值 difficulty_thresholds,将样本分类为 easy/medium/hard/extra/gold error。
Parameters:
-
model–LazyLLM 模型对象(必需)。
-
database_manager–提供 batch_compare_queries 能力的管理器(必需)。
-
num_generations(int, default:10) –采样生成 SQL 的次数,默认 10;若小于最大阈值会被自动上调为某个 5 的倍数。
-
difficulty_thresholds(list[int] | None, default:None) –难度阈值列表,默认 [2, 5, 9]。
-
difficulty_labels(list[str] | None, default:None) –难度标签列表,默认 ['extra', 'hard', 'medium', 'easy']。
-
system_prompt(str | None, default:None) –可选系统提示词。
-
**kwargs–其它传递给基类算子的参数。
Examples:
from lazyllm.tools.data.operators.text2sql_ops import SQLEffortRanker
op = SQLEffortRanker(model=model, database_manager=database_manager, num_generations=15)
item = {
'db_id': 'db_1',
'prompt': 'Database Schema: ... Question: 有多少已支付的订单?',
'SQL': 'SELECT count(*) FROM orders WHERE status = 'paid';'
}
res = op(item)
print(res)
# {
# 'db_id': 'db_1',
# 'prompt': 'Database Schema: ... Question: 有多少已支付的订单?',
# 'SQL': 'SELECT count(*) FROM orders WHERE status = 'paid';',
# 'sql_execution_difficulty': 'medium'
# }
Source code in lazyllm/tools/data/operators/text2sql_ops.py
994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 | |
SQLForge
Bases: Text2SQLOps
Text2SQL 数据生成算子:SQL 生成器。
基于数据库 Schema 与样例数据,为给定或全部数据库自动生成可执行的 SQL 语句集合,并标注大致复杂度类型。
主要行为:
- 对每个数据库生成 output_num 条 SQL。
- 内置默认提示词(可自定义 prompt_template),控制难度标签(easy/medium/hard 等)。
- 从模型返回中解析出
sql ...代码块中的 SQL 文本。
Parameters:
-
model–LazyLLM 模型对象(必需),会被 share() 后复用。
-
database_manager–提供数据库 Schema 与样例数据的管理器(必需),需实现: - list_databases() - get_create_statements_and_insert_statements(db_name)
-
output_num(int, default:300) –每个数据库生成的 SQL 数量,默认 300。
-
prompt_template–可选,自定义 prompt 构造器对象,需实现 build_prompt(...)。
-
system_prompt(str | None, default:None) –可选系统提示词,不传则使用内置英文提示。
-
**kwargs–传递给基类 Text2SQLOps/LazyLLMDataBase 的其它参数。
Examples:
from lazyllm.tools.data.operators.text2sql_ops import SQLForge
# 假设 database_manager 已封装了你的 SQLite / Postgres 等数据库
op = SQLForge(model=model, database_manager=database_manager, output_num=10)
# 如果 data 中不指定 db_id,则为所有数据库各生成若干条 SQL
res = op({})
print(res[0])
# {
# 'db_id': 'database_1',
# 'SQL': 'SELECT ...',
# 'sql_complexity_type': 'easy'
# }
Source code in lazyllm/tools/data/operators/text2sql_ops.py
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | |
SQLIntentSynthesizer
Bases: Text2SQLOps
Text2SQL 数据生成算子:自然语言问题生成器。
基于给定 SQL + 数据库 Schema 以及列注释信息,生成与 SQL 语义对应的自然语言问题,并可附带“外部知识”提示,以支持 Text2SQL 训练。
主要特性:
- 支持多候选问题生成(input_query_num),并通过 embedding 去重/多样性选择。
- 内置输出格式标记:[QUESTION-START]/[QUESTION-END] 与 [EXTERNAL-KNOWLEDGE-START]/[...-END]。
Parameters:
-
model–LazyLLM 文本生成模型(必需)。
-
embedding_model–可选向量模型,用于对候选问题做多样性选择;需支持: - generate_embedding_from_input(texts) 或直接可调用(texts)。
-
database_manager–提供 Schema 的管理器(必需),需实现: - get_create_statements_and_insert_statements(db_id)
-
input_query_num(int, default:5) –每条 SQL 生成候选问题的数量,默认 5。
-
prompt_template–可选,自定义 prompt 构造器。
-
system_prompt(str | None, default:None) –可选系统提示词,默认简要英文助手提示。
-
**kwargs–其它传递给基类算子的参数。
Examples:
from lazyllm.tools.data.operators.text2sql_ops import SQLIntentSynthesizer
op = SQLIntentSynthesizer(model=model,
embedding_model=embedding_model,
database_manager=database_manager,
input_query_num=5)
item = {'db_id': 'db_1', 'SQL': 'SELECT count(*) FROM orders WHERE status = 'paid';'}
res = op(item)
print(res)
# {
# 'db_id': 'db_1',
# 'SQL': 'SELECT count(*) FROM orders WHERE status = 'paid';',
# 'question_type': 'default',
# 'question': '有多少已支付的订单?',
# 'evidence': '...可选的外部知识...'
# }
Source code in lazyllm/tools/data/operators/text2sql_ops.py
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 | |
SQLReasoningTracer
Bases: Text2SQLOps
Text2SQL 数据生成算子:CoT 轨迹生成器。
针对给定 (问题, SQL, 数据库 Schema, 证据) 生成若干条“从问题到 SQL 的链式思考(Chain-of-Thought)”文本,用于训练/分析。
Parameters:
-
model–LazyLLM 模型对象(必需)。
-
database_manager–提供 Schema 的管理器(必需),需实现: - get_create_statements_and_insert_statements(db_id)
-
prompt_template–可选,自定义 prompt 构造器。
-
output_num(int, default:3) –每条样本生成的 CoT 轨迹数量,默认 3(>=1)。
-
**kwargs–其它传递给基类算子的参数。
Examples:
from lazyllm.tools.data.operators.text2sql_ops import SQLReasoningTracer
op = SQLReasoningTracer(model=model, database_manager=database_manager, output_num=3)
item = {
'db_id': 'db_1',
'question': '有多少已支付的订单?',
'SQL': 'SELECT count(*) FROM orders WHERE status = 'paid';',
'evidence': ''
}
res = op(item)
print(len(res['cot_responses']))
print(res['cot_responses'][0][:200]) # 打印第一条 CoT 的前 200 个字符
# 3
# "Database Schema: ... Question: 有多少已支付的订单? ... 推理步骤1:... 推理步骤2:... ```sql SELECT count(*) FROM orders WHERE status = 'paid';```"
Source code in lazyllm/tools/data/operators/text2sql_ops.py
737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 | |
SQLRuntimeSieve
Bases: Text2SQLOps
Text2SQL 数据过滤算子:SQL 可执行性过滤器。
对每条数据中的 SQL 进行简单语法形态过滤(仅保留 SELECT / WITH 开头的查询),并调用 database_manager 进行 EXPLAIN 校验;只保留可在目标库上成功执行的 SQL。
Parameters:
-
database_manager–提供数据库连接与 explain 能力的管理器(必需),需实现: - database_exists(db_id) - batch_explain_queries(list[(db_id, sql)])
-
**kwargs–传递给基类算子的其它参数。
Examples:
from lazyllm.tools.data.operators.text2sql_ops import SQLRuntimeSieve
op = SQLRuntimeSieve(database_manager=database_manager)
item = {'db_id': 'db_1', 'SQL': 'SELECT * FROM users;'}
res = op(item)
print(res) # 若 SQL 可在 db_1 上 explain 成功,则返回原始 dict;否则返回 None
Source code in lazyllm/tools/data/operators/text2sql_ops.py
SQLSyntaxProfiler
Bases: Text2SQLOps
Text2SQL 数据分类算子:SQL 组件难度分类器。
使用 SQL 结构级别的难度评估器(EvalHardness/EvalHardnessLite),根据 SQL 中涉及的组件复杂度对其进行难度打标(easy/medium/hard/extra 等)。
Parameters:
-
difficulty_thresholds(list[int] | None, default:None) –难度阈值列表,默认 [2, 4, 6]。
-
difficulty_labels(list[str] | None, default:None) –难度标签列表,默认 ['easy', 'medium', 'hard', 'extra']。
-
**kwargs–其它传递给基类算子的参数。
Examples:
from lazyllm.tools.data.operators.text2sql_ops import SQLSyntaxProfiler
op = SQLSyntaxProfiler()
item = {'SQL': 'SELECT count(*) FROM orders WHERE status = 'paid';'}
res = op(item)
print(res)
# {
# 'SQL': 'SELECT count(*) FROM orders WHERE status = 'paid';',
# 'sql_component_difficulty': 'easy'
# }
Source code in lazyllm/tools/data/operators/text2sql_ops.py
TSQLSemanticAuditor
Bases: Text2SQLOps
Text2SQL 数据过滤算子:问句-SQL 一致性过滤器。
给定自然语言问题 + 证据(可选)+ SQL + 数据库 Schema,判断 SQL 是否能够正确回答该问题,保留“正确”的样本。
内部逻辑:
- 调用 database_manager 获取 db_id 对应的 DDL(create_statements)。
- 通过模型生成判断(Yes/No),仅当返回中包含 'yes' 时保留该样本,否则丢弃(返回 None)。
Parameters:
-
model–LazyLLM 模型对象(必需)。
-
database_manager–提供 Schema 的管理器(必需),需实现: - get_create_statements_and_insert_statements(db_id)
-
prompt_template–可选,自定义 prompt 构造器。
-
system_prompt(str | None, default:None) –可选系统提示词,默认英文 Yes/No 判定说明。
-
**kwargs–其它传递给基类算子的参数。
Examples:
from lazyllm.tools.data.operators.text2sql_ops import TSQLSemanticAuditor
op = TSQLSemanticAuditor(model=model, database_manager=database_manager)
item = {
'db_id': 'db_1',
'SQL': 'SELECT count(*) FROM orders WHERE status = 'paid';',
'question': '有多少已支付的订单?',
'evidence': ''
}
res = op(item)
print(res)
# {
# 'db_id': 'db_1',
# 'SQL': 'SELECT count(*) FROM orders WHERE status = 'paid';',
# 'question': '有多少已支付的订单?',
# 'evidence': ''
# }
# 如果模型判断不匹配,则返回 None
Source code in lazyllm/tools/data/operators/text2sql_ops.py
528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 | |
预训练算子
lazyllm.tools.data.operators.pt_op
ContextQualFilter
Bases: PT
使用 VLM 或 LLM 评估 context 是否适合生成 QA 对;仅保留 score=1(适合)的样本。
Parameters:
-
llm–视觉或文本语言模型实例
-
context_key(str, default:'context') –上下文字段名,默认 'context'
-
image_key(str, default:'image_path') –图片路径字段名,默认 'image_path'
-
prompt(str, default:None) –可选,自定义提示词
Examples:
from lazyllm.tools.data import pt
vlm = lazyllm.OnlineChatModule(source='sensenova', model='SenseNova-V6-5-Turbo')
op = pt.ContextQualFilter(vlm)
res = op([{'context': 'Good context for QA.', 'image_path': '/path/to/image.jpg'}])
# only samples with score=1 are kept
Source code in lazyllm/tools/data/operators/pt_op.py
GraphRetriever
Bases: PT_MM
从 context 字段中解析 Markdown 格式的图片链接 ,提取存在磁盘上的图片路径并写入 img_key。
不修改原始 context;若 context.strip() 为空,则 img_key 为 [],样本仍保留。
Parameters:
-
context_key(str, default:'context') –文本上下文字段名,默认 'context'
-
img_key(str, default:'image_path') –图片路径输出字段名,默认 'image_path'
-
images_folder(str, default:None) –可选,图片根目录,用于解析相对路径
Examples:
from lazyllm.tools.data import pt_mm
op = pt_mm.GraphRetriever(context_key='context', img_key='img', _save_data=False)
data = {'context': 'Some content '}
res = op([data])
# res[0]['img'] contains resolved absolute path
# empty context: res[0]['img'] == [], record kept, source context unchanged
empty_res = op([{'context': ' '}])
Source code in lazyllm/tools/data/operators/pt_op.py
ImageDedup
Bases: PT_MM
基于图片文件哈希去重,保留首次出现的图片,跳过重复项。
Parameters:
-
image_key(str, default:'image_path') –图片路径字段名,默认 'image_path'
-
hash_method(str, default:'md5') –哈希算法,默认 'md5'
Examples:
from lazyllm.tools.data import pt_mm
op = pt_mm.ImageDedup()
batch = [{'image_path': 'a.jpg', 'id': 1}, {'image_path': 'a.jpg', 'id': 2}, {'image_path': 'b.jpg', 'id': 3}]
res = op(batch)
# len(res) == 2, duplicate removed
Source code in lazyllm/tools/data/operators/pt_op.py
Phi4QAGenerator
Bases: PT
使用 LLM 将 context(含可选图片)转换为预训练格式的 Phi-4 风格多轮问答对。
Parameters:
-
llm–视觉或文本语言模型实例
-
image_key(str, default:'image_path') –图片路径字段名,默认 'image_path'
-
context_key(str, default:'context') –上下文字段名,默认 'context'
-
num_qa(int, default:5) –生成的问答对数量,默认 5
-
prompt(str, default:None) –可选,自定义提示词
Examples:
from lazyllm.tools.data import pt
vlm = lazyllm.OnlineChatModule(source='sensenova', model='SenseNova-V6-5-Turbo')
op = pt.Phi4QAGenerator(vlm, num_qa=2)
res = op([{'context': 'Some context.', 'image_path': '/path/to/image.jpg'}])
# res[0]['qa_pairs'] contains pretraining-format Q&A
Source code in lazyllm/tools/data/operators/pt_op.py
TextRelevanceFilter
Bases: PT_MM
使用 VLM 判断图文相关性,过滤低于阈值的样本。
Parameters:
-
vlm–视觉语言模型实例
-
image_key(str, default:'image_path') –图片路径字段名,默认 'image_path'
-
text_key(str, default:'text') –文本字段名,默认 'text'
-
threshold(float, default:0.6) –相关性阈值 [0,1],默认 0.6
-
prompt(str, default:None) –可选,自定义提示词
Examples:
from lazyllm.tools.data import pt_mm
vlm = lazyllm.OnlineChatModule(source='sensenova', model='SenseNova-V6-5-Turbo')
op = pt_mm.TextRelevanceFilter(vlm, threshold=0.5)
res = op([{'image_path': '/path/to/image.jpg', 'text': 'a red square'}])
# samples with relevance >= threshold are kept
Source code in lazyllm/tools/data/operators/pt_op.py
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | |
VQAGenerator
Bases: PT_MM
使用 VLM 根据 context 和图片生成视觉问答对(VQA pairs)。
Parameters:
-
vlm–视觉语言模型实例
-
image_key(str, default:'image_path') –图片路径字段名,默认 'image_path'
-
context_key(str, default:'context') –上下文字段名,默认 'context'
-
num_qa(int, default:5) –生成的问答对数量,默认 5
-
prompt(str, default:None) –可选,自定义提示词
Examples:
from lazyllm.tools.data import pt_mm
vlm = lazyllm.OnlineChatModule(source='sensenova', model='SenseNova-V6-5-Turbo')
op = pt_mm.VQAGenerator(vlm, num_qa=3)
res = op([{'image_path': '/path/to/image.jpg', 'context': 'A simple image.'}])
# res[0]['qa_pairs'] contains [{'query': '...', 'answer': '...'}, ...]
Source code in lazyllm/tools/data/operators/pt_op.py
VQAScorer
Bases: PT_MM
使用 VLM 对 VQA 对(query、answer、image_path)进行质量打分,评估图文问答的质量。
Parameters:
-
vlm–视觉语言模型实例
-
image_key(str, default:'image_path') –图片路径字段名,默认 'image_path'
-
query_key(str, default:'query') –问题字段名,默认 'query'
-
answer_key(str, default:'answer') –答案字段名,默认 'answer'
-
prompt(str, default:None) –可选,自定义提示词
Examples:
from lazyllm.tools.data import pt_mm
vlm = lazyllm.OnlineChatModule(source='sensenova', model='SenseNova-V6-5-Turbo')
op = pt_mm.VQAScorer(vlm)
res = op([{
'image_path': '/path/to/image.jpg',
'query': 'What color is it?',
'answer': 'Red',
}])
# res[0]['quality_score'] contains score, relevance, correctness, reason
Source code in lazyllm/tools/data/operators/pt_op.py
398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 | |
integrity_check(data, image_key='image_path', input_key=None)
检查图片文件完整性,过滤损坏或空文件,保留可正常打开的图片路径。
Parameters:
-
data(dict) –单条数据字典
-
image_key(str, default:'image_path') –图片路径字段名,默认 'image_path'
-
input_key(str, default:None) –可选,覆盖 image_key
Examples:
from lazyllm.tools.data import pt_mm
op = pt_mm.integrity_check()
res = op([{'image_path': '/path/to/image.jpg'}, {'image_path': '/nonexistent.png'}])
# only valid images retained
Source code in lazyllm/tools/data/operators/pt_op.py
resolution_filter(data, image_key='image_path', min_width=256, min_height=256, max_width=4096, max_height=4096, input_key=None)
按最小/最大宽高过滤图片,保留尺寸在指定范围内的图片路径。
Parameters:
-
data(dict) –单条数据字典
-
image_key(str, default:'image_path') –图片路径字段名,默认 'image_path'
-
min_width(int, default:256) –最小宽度,默认 256
-
min_height(int, default:256) –最小高度,默认 256
-
max_width(int, default:4096) –最大宽度,默认 4096
-
max_height(int, default:4096) –最大高度,默认 4096
-
input_key(str, default:None) –可选,覆盖 image_key
Examples:
from lazyllm.tools.data import pt_mm
op = pt_mm.resolution_filter(min_width=256, min_height=256, max_width=4096, max_height=4096)
res = op([{'image_path': '/path/to/image.jpg'}])
Source code in lazyllm/tools/data/operators/pt_op.py
resolution_resize(data, image_key='image_path', max_side=1024, input_key=None, inplace=True)
将图片最长边缩放到不超过 max_side,可原位覆盖或生成新文件。
Parameters:
-
data(dict) –单条数据字典
-
image_key(str, default:'image_path') –图片路径字段名,默认 'image_path'
-
max_side(int, default:1024) –最长边上限,默认 1024
-
inplace(bool, default:True) –是否覆盖原文件,默认 True;False 时生成 _resized 后缀新文件
-
input_key(str, default:None) –可选,覆盖 image_key
Examples:
from lazyllm.tools.data import pt_mm
op = pt_mm.resolution_resize(max_side=400, inplace=False)
res = op([{'image_path': '/path/to/image.jpg'}])
# resized file saved as image_resized.jpg in same directory
Source code in lazyllm/tools/data/operators/pt_op.py
精炼算子
lazyllm.tools.data.operators.refine_op
remove_emoji(data, input_key='content')
移除指定字段中的 emoji 字符。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'content') –文本字段名,默认 'content'
Examples:
from lazyllm.tools.data import refine
func = refine.remove_emoji(input_key='content')
inputs = [{'content': 'Hello 😊 World 🌍!'}]
res = func(inputs)
print(res)
# [{'content': 'Hello World !'}]
Source code in lazyllm/tools/data/operators/refine_op.py
remove_extra_spaces(data, input_key='content')
将指定字段中的多余空白(多个空格、换行、制表符)归一化为单个空格。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'content') –文本字段名,默认 'content'
Examples:
from lazyllm.tools.data import refine
func = refine.remove_extra_spaces(input_key='content')
inputs = [{'content': 'hello world\n\n foo\tbar'}]
res = func(inputs)
print(res)
# [{'content': 'hello world foo bar'}]
Source code in lazyllm/tools/data/operators/refine_op.py
remove_html_entity(data, input_key='content')
移除指定字段中的 HTML 实体(如 、<、& 等)。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'content') –文本字段名,默认 'content'
Examples:
from lazyllm.tools.data import refine
func = refine.remove_html_entity(input_key='content')
inputs = [{'content': 'Hello World & <tag>'}]
res = func(inputs)
print(res)
# [{'content': 'HelloWorld tag'}]
Source code in lazyllm/tools/data/operators/refine_op.py
remove_html_url(data, input_key='content')
移除指定字段中的 HTTP/HTTPS 链接和 HTML 标签。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'content') –文本字段名,默认 'content'
Examples:
from lazyllm.tools.data import refine
func = refine.remove_html_url(input_key='content')
inputs = [{'content': 'Check https://example.com and <b>bold</b>'}]
res = func(inputs)
print(res)
# [{'content': 'Check and bold'}]
Source code in lazyllm/tools/data/operators/refine_op.py
过滤算子
lazyllm.tools.data.operators.filter_op
CapitalWordFilter
Bases: Filter
过滤全大写单词占比过高的文本。
Parameters:
-
input_key(str, default:'content') –文本字段名,默认 'content'
-
max_ratio(float, default:0.5) –全大写单词最大占比,默认 0.5
-
use_tokenizer(bool, default:False) –是否使用分词,默认 False
-
_concurrency_mode(str, default:'thread') –可选,并发模式
Examples:
from lazyllm.tools.data import filter
func = filter.CapitalWordFilter(input_key='content', max_ratio=0.5)
inputs = [{'content': 'Normal text with Some Capitals'}, {'content': 'MOSTLY UPPERCASE'}]
res = func(inputs)
print(res)
# [{'content': 'Normal text with Some Capitals'}]
Source code in lazyllm/tools/data/operators/filter_op.py
MinHashDeduplicator
Bases: Filter
使用 MinHash LSH 去除近似重复文本,批处理时保留首次出现的文本。
Parameters:
-
input_key(str, default:'content') –文本字段名,默认 'content'
-
threshold(float, default:0.85) –相似度阈值,默认 0.85
-
num_perm(int, default:128) –MinHash 排列数,默认 128
-
use_n_gram(bool, default:True) –是否使用 n-gram,默认 True
-
ngram(int, default:5) –n-gram 长度,默认 5
Examples:
from lazyllm.tools.data import filter
func = filter.MinHashDeduplicator(input_key='content', threshold=0.85)
inputs = [{'uid': '0', 'content': '这是第一段不同的内容。'}, {'uid': '1', 'content': '这是第一段不同的内容。'}]
res = func(inputs)
print(res)
# [{'uid': '0', 'content': '这是第一段不同的内容。'}]
Source code in lazyllm/tools/data/operators/filter_op.py
StopWordFilter
Bases: Filter
过滤停用词占比过高的文本(如几乎全为「的了呢」的无效内容)。
Parameters:
-
input_key(str, default:'content') –文本字段名,默认 'content'
-
max_ratio(float, default:0.5) –停用词最大占比,超过则过滤,默认 0.5
-
use_tokenizer(bool, default:True) –是否使用分词,默认 True
-
language(str, default:'zh') –语言,'zh' 或 'en',默认 'zh'
-
_concurrency_mode(str, default:'thread') –可选,并发模式
Examples:
from lazyllm.tools.data import filter
func = filter.StopWordFilter(input_key='content', max_ratio=0.5, language='zh')
inputs = [{'content': '这是一段包含实际内容的正常文本。'}, {'content': '的了吗呢吧啊'}]
res = func(inputs)
print(res)
# [{'content': '这是一段包含实际内容的正常文本。'}]
Source code in lazyllm/tools/data/operators/filter_op.py
845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 | |
SymbolRatioFilter
Bases: Filter
过滤指定符号(如 #、...、…)占比过高的文本。
Parameters:
-
input_key(str, default:'content') –文本字段名,默认 'content'
-
max_ratio(float, default:0.3) –符号与词数最大比例,默认 0.3
-
symbols(list | None, default:None) –要统计的符号列表,默认 ['#', '...', '…']
-
_concurrency_mode(str, default:'process') –可选,并发模式
Examples:
from lazyllm.tools.data import filter
func = filter.SymbolRatioFilter(input_key='content', max_ratio=0.3)
inputs = [{'content': 'Normal text without symbols'}, {'content': '### ... … ###'}]
res = func(inputs)
print(res)
# [{'content': 'Normal text without symbols'}]
Source code in lazyllm/tools/data/operators/filter_op.py
TargetLanguageFilter
Bases: Filter
使用 FastText 进行语言识别,仅保留指定语言的文本。
Parameters:
-
input_key(str, default:'content') –文本字段名,默认 'content'
-
target_language(str | list, default:'zho_Hans') –目标语言代码,如 'zho_Hans'、'eng_Latn'
-
threshold(float, default:0.6) –置信度阈值,默认 0.6
-
model_path(str | None, default:None) –FastText 模型路径
-
_concurrency_mode(str, default:'thread') –可选,并发模式
Examples:
from lazyllm.tools.data import filter
func = filter.TargetLanguageFilter(input_key='content', target_language='zho_Hans', threshold=0.3)
inputs = [{'content': '这是一段中文文本。'}, {'content': 'This is English.'}]
res = func(inputs)
print(res)
# [{'content': '这是一段中文文本。'}]
Source code in lazyllm/tools/data/operators/filter_op.py
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 | |
WordBlocklistFilter
Bases: Filter
使用 AC 自动机多模式匹配过滤包含敏感词/违禁词超过阈值的文本。
Parameters:
-
input_key(str, default:'content') –文本字段名,默认 'content'
-
blocklist(list | None, default:None) –违禁词列表
-
blocklist_path(str | None, default:None) –违禁词文件路径
-
language(str, default:'zh') –语言,'zh' 或 'en',默认 'zh'
-
threshold(int, default:1) –允许出现的违禁词最大数量,默认 1
-
_concurrency_mode(str, default:'thread') –可选,并发模式
Examples:
from lazyllm.tools.data import filter
func = filter.WordBlocklistFilter(input_key='content', blocklist=['敏感', '违禁'], threshold=0)
inputs = [{'content': '这是正常的文本内容。'}, {'content': '这里包含敏感词。'}]
res = func(inputs)
print(res)
# [{'content': '这是正常的文本内容。'}]
Source code in lazyllm/tools/data/operators/filter_op.py
320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 | |
bullet_point_filter(data, input_key='content', max_ratio=0.9)
过滤子弹点行占比过高的文本(如目录、纯列表)。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'content') –文本字段名,默认 'content'
-
max_ratio(float, default:0.9) –以子弹点开头的行最大占比,默认 0.9
Examples:
from lazyllm.tools.data import filter
func = filter.bullet_point_filter(input_key='content', max_ratio=0.5)
inputs = [{'content': 'Normal paragraph text'}, {'content': '- Item 1\n- Item 2\n- Item 3'}]
res = func(inputs)
print(res)
# [{'content': 'Normal paragraph text'}]
Source code in lazyllm/tools/data/operators/filter_op.py
char_count_filter(data, input_key='content', min_chars=100, max_chars=100000)
按去除空白后的字符数过滤,保留在 [min_chars, max_chars] 范围内的文本。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'content') –文本字段名,默认 'content'
-
min_chars(int, default:100) –最小字符数,默认 100
-
max_chars(int, default:100000) –最大字符数,默认 100000
Examples:
from lazyllm.tools.data import filter
func = filter.char_count_filter(input_key='content', min_chars=10, max_chars=100)
inputs = [{'content': '短'}, {'content': '这是一段中等长度的文本内容。'}]
res = func(inputs)
print(res)
# [{'content': '这是一段中等长度的文本内容。'}]
Source code in lazyllm/tools/data/operators/filter_op.py
colon_end_filter(data, input_key='content')
过滤以冒号结尾的文本。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'content') –文本字段名,默认 'content'
Examples:
from lazyllm.tools.data import filter
func = filter.colon_end_filter(input_key='content')
inputs = [{'content': '这是正常结尾。'}, {'content': '这是冒号结尾:'}]
res = func(inputs)
print(res)
# [{'content': '这是正常结尾。'}]
Source code in lazyllm/tools/data/operators/filter_op.py
curly_bracket_filter(data, input_key='content', max_ratio=0.08)
过滤花括号 {} 占比过高的文本。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'content') –文本字段名,默认 'content'
-
max_ratio(float, default:0.08) –花括号最大占比,默认 0.08
Examples:
from lazyllm.tools.data import filter
func = filter.curly_bracket_filter(input_key='content', max_ratio=0.08)
inputs = [{'content': 'Normal text'}, {'content': '{{{{{' * 10}]
res = func(inputs)
print(res)
# [{'content': 'Normal text'}]
Source code in lazyllm/tools/data/operators/filter_op.py
ellipsis_end_filter(data, input_key='content', max_ratio=0.3)
过滤以省略号(...、…、……)结尾的行占比过高的文本。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'content') –文本字段名,默认 'content'
-
max_ratio(float, default:0.3) –以省略号结尾的行最大占比,默认 0.3
Examples:
from lazyllm.tools.data import filter
func = filter.ellipsis_end_filter(input_key='content', max_ratio=0.3)
inputs = [{'content': '第一行。\n第二行。\n第三行。'}, {'content': '第一行...\n第二行...'}]
res = func(inputs)
print(res)
# [{'content': '第一行。\n第二行。\n第三行。'}]
Source code in lazyllm/tools/data/operators/filter_op.py
idcard_filter(data, input_key='content', threshold=3)
过滤包含过多身份证/证件相关词汇的文本。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'content') –文本字段名,默认 'content'
-
threshold(int, default:3) –匹配到相关词的最大数量,超过则过滤,默认 3
Examples:
from lazyllm.tools.data import filter
func = filter.idcard_filter(input_key='content', threshold=1)
inputs = [{'content': '这是正常文本'}, {'content': '请提供身份证号码和ID number'}]
res = func(inputs)
print(res)
# [{'content': '这是正常文本'}]
Source code in lazyllm/tools/data/operators/filter_op.py
javascript_filter(data, input_key='content', min_non_script_lines=3)
过滤含大量 JavaScript 相关模式的文本(如代码、脚本片段)。短文本(<=3行)不检测,直接保留,避免误伤正常短句。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'content') –文本字段名,默认 'content'
-
min_non_script_lines(int, default:3) –最少非脚本行数,默认 3
Examples:
from lazyllm.tools.data import filter
func = filter.javascript_filter(input_key='content', min_non_script_lines=2)
inputs = [{'content': 'Short normal text'}, {'content': 'function() { return 1; }
const x = 1;
var y = 2;
let z = 3;'}]
res = func(inputs)
print(res)
# [{'content': 'Short normal text'}]
Source code in lazyllm/tools/data/operators/filter_op.py
lorem_ipsum_filter(data, input_key='content', max_ratio=3e-08)
过滤 Lorem ipsum、占位符等占位文本。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'content') –文本字段名,默认 'content'
-
max_ratio(float, default:3e-08) –占位模式最大出现比例,默认 3e-8
Examples:
from lazyllm.tools.data import filter
func = filter.lorem_ipsum_filter(input_key='content')
inputs = [{'content': 'This is real content'}, {'content': 'Lorem ipsum dolor sit amet'}]
res = func(inputs)
print(res)
# [{'content': 'This is real content'}]
Source code in lazyllm/tools/data/operators/filter_op.py
no_punc_filter(data, input_key='content', max_length_between_punct=112, language='zh')
过滤标点之间段路过长的文本(如无标点超长串)。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'content') –文本字段名,默认 'content'
-
max_length_between_punct(int, default:112) –标点间最大长度,默认 112
-
language(str, default:'zh') –语言,'zh' 或 'en',默认 'zh'
Examples:
from lazyllm.tools.data import filter
func = filter.no_punc_filter(input_key='content', max_length_between_punct=20, language='zh')
inputs = [{'content': '这是。正常。文本。'}, {'content': '这是一段没有标点符号的超长文本' * 10}]
res = func(inputs)
print(res)
# [{'content': '这是。正常。文本。'}]
Source code in lazyllm/tools/data/operators/filter_op.py
null_content_filter(data, input_key='content')
过滤空内容或仅空白字符的文本。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'content') –文本字段名,默认 'content'
Examples:
from lazyllm.tools.data import filter
func = filter.null_content_filter(input_key='content')
inputs = [{'content': 'Valid content'}, {'content': ''}, {'content': ' '}]
res = func(inputs)
print(res)
# [{'content': 'Valid content'}]
Source code in lazyllm/tools/data/operators/filter_op.py
sentence_count_filter(data, input_key='content', min_sentences=3, max_sentences=1000, language='zh')
按句子数量过滤,保留在 [min_sentences, max_sentences] 范围内的文本。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'content') –文本字段名,默认 'content'
-
min_sentences(int, default:3) –最少句子数,默认 3
-
max_sentences(int, default:1000) –最多句子数,默认 1000
-
language(str, default:'zh') –语言,'zh' 或 'en',默认 'zh'
Examples:
from lazyllm.tools.data import filter
func = filter.sentence_count_filter(input_key='content', min_sentences=2, max_sentences=10, language='zh')
inputs = [{'content': '单句。'}, {'content': '第一句。第二句。'}]
res = func(inputs)
print(res)
# [{'content': '第一句。第二句。'}]
Source code in lazyllm/tools/data/operators/filter_op.py
special_char_filter(data, input_key='content')
过滤包含特殊不可见字符的文本(零宽字符、替换字符等)。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'content') –文本字段名,默认 'content'
Examples:
from lazyllm.tools.data import filter
func = filter.special_char_filter(input_key='content')
inputs = [{'content': 'Normal text 正常文本'}, {'content': 'Text with zero width'}]
res = func(inputs)
print(res)
# [{'content': 'Normal text 正常文本'}]
Source code in lazyllm/tools/data/operators/filter_op.py
unique_word_filter(data, input_key='content', min_ratio=0.1, use_tokenizer=True, language='zh')
过滤去重后词数占比过低的文本(重复词过多的无效内容)。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'content') –文本字段名,默认 'content'
-
min_ratio(float, default:0.1) –去重词数最小占比,默认 0.1
-
use_tokenizer(bool, default:True) –是否使用分词,默认 True
-
language(str, default:'zh') –语言,'zh' 或 'en',默认 'zh'
Examples:
from lazyllm.tools.data import filter
func = filter.unique_word_filter(input_key='content', min_ratio=0.4, language='zh')
inputs = [{'content': '这是一段包含多个不同词汇的文本。'}, {'content': '重复重复重复'}]
res = func(inputs)
print(res)
# [{'content': '这是一段包含多个不同词汇的文本。'}]
Source code in lazyllm/tools/data/operators/filter_op.py
watermark_filter(data, input_key='content', watermarks=None)
过滤包含版权/水印相关词汇的文本。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'content') –文本字段名,默认 'content'
-
watermarks(list | None, default:None) –自定义水印词列表,默认使用内置列表
Examples:
from lazyllm.tools.data import filter
func = filter.watermark_filter(input_key='content')
inputs = [{'content': 'Normal content'}, {'content': 'This document contains Copyright notice'}]
res = func(inputs)
print(res)
# [{'content': 'Normal content'}]
Source code in lazyllm/tools/data/operators/filter_op.py
word_count_filter(data, input_key='content', min_words=10, max_words=10000, language='zh')
按词/字符数量过滤:中文按字符数,英文按单词数,保留在 [min_words, max_words) 范围内的文本。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'content') –文本字段名,默认 'content'
-
min_words(int, default:10) –最小词数,默认 10
-
max_words(int, default:10000) –最大词数,默认 10000
-
language(str, default:'zh') –语言,'zh' 或 'en',默认 'zh'
Examples:
from lazyllm.tools.data import filter
func = filter.word_count_filter(input_key='content', min_words=5, max_words=20, language='zh')
inputs = [{'content': '短文本'}, {'content': '这是一段适中长度的中文文本内容。'}]
res = func(inputs)
print(res)
# [{'content': '这是一段适中长度的中文文本内容。'}]
Source code in lazyllm/tools/data/operators/filter_op.py
word_length_filter(data, input_key='content', min_length=3, max_length=20)
按单词平均长度过滤,保留在 [min_length, max_length) 范围内的文本。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'content') –文本字段名,默认 'content'
-
min_length(float, default:3) –单词平均最小长度,默认 3
-
max_length(float, default:20) –单词平均最大长度,默认 20
Examples:
from lazyllm.tools.data import filter
func = filter.word_length_filter(input_key='content', min_length=3, max_length=10)
inputs = [{'content': 'I am ok'}, {'content': 'This is a normal sentence'}]
res = func(inputs)
print(res)
# [{'content': 'This is a normal sentence'}]
Source code in lazyllm/tools/data/operators/filter_op.py
切块算子
lazyllm.tools.data.operators.token_chunker
TokenChunker
Bases: Chunker
按 token 数量将长文本切分为多个块。先按段落分隔,再按句子细切,保证每块不超过 max_tokens,过短块可丢弃。
Parameters:
-
input_key(str, default:'content') –文本字段名,默认 'content'
-
model_path(str | None, default:None) –tokenizer 模型路径,默认使用 Qwen2.5-0.5B-Instruct
-
max_tokens(int, default:1024) –每块最大 token 数,默认 1024
-
min_tokens(int, default:200) –每块最小 token 数,低于此值的块可能被丢弃,默认 200
-
_concurrency_mode(str, default:'process') –可选,并发模式
-
_max_workers(int | None) –可选,最大并发数
Examples:
from lazyllm.tools.data import chunker
func = chunker.TokenChunker(input_key='content', max_tokens=50, min_tokens=10)
inputs = [{'content': '人工智能是计算机科学的一个分支。' * 20, 'meta_data': {'source': 'doc_1'}}]
res = func(inputs)
print(res)
# [{'uid': '...', 'content': '...', 'meta_data': {'source': 'doc_1', 'index': 0, 'total': N, 'length': ...}}, ...]
Source code in lazyllm/tools/data/operators/token_chunker.py
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 | |
代码生成算子
lazyllm.tools.data.operators.codegen_ops
CodeInstructionGenerator
Bases: CodeGenOps
代码生成流水线算子:指令标准化生成器。
从原始对话消息(messages)中抽取用户指令,并将其重写为统一的“代码增强指令”,输出为一条英文描述 + 一个包含完整函数骨架的 Python 代码块。
输出示例结构(默认 input_key='messages', output_key='generated_instruction'):
- messages: 原始多轮对话(保持不变)
- generated_instruction (str): 标准化后的英文指令 + Python 代码块
Parameters:
-
model–LazyLLM 模型对象(必需),会被 share() 后复用。
-
prompt_template(str | None, default:None) –可选,自定义系统提示词(若提供则替换默认 sys_prompt)。
-
input_key(str, default:'messages') –输入对话字段名,默认 'messages'。
-
output_key(str, default:'generated_instruction') –输出标准化指令字段名,默认 'generated_instruction'。
-
**kwargs–传递给基类算子的其它参数(如 _max_workers、_save_data 等)。
Examples:
from lazyllm.tools.data.operators.codegen_ops import CodeInstructionGenerator
op = CodeInstructionGenerator(model=model,
input_key='messages',
output_key='generated_instruction')
item = {
'messages': [
{'role': 'user', 'content': '写一个 Python 函数,打印 hello'}
]
}
res = op(item)
print(res)
# Output Example:
# {
# 'messages': [...],
# 'generated_instruction': "Write a Python function that prints 'hello'.\n"
# "```python\n"
# "def solution():\n"
# " print('hello')\n"
# "```"
# }
Source code in lazyllm/tools/data/operators/codegen_ops.py
LogicIntegrityAuditor
Bases: CodeGenOps
代码生成流水线算子:代码质量评估器。
对单条 (generated_instruction, generated_code) 样本进行自动代码评审,输出一个质量分数(0–10)与一段文字反馈,默认使用 JSON 格式进行解析。
输出示例结构(默认 input_instruction_key='instruction', input_code_key='new_code'):
- instruction: 标准化指令
- new_code: 生成的代码
- quality_score: 质量得分(int/float,取决于 JsonFormatter 解析)
- feedback: 文字反馈
Parameters:
-
model–LazyLLM 模型对象(必需),会被 JsonFormatter 包装为 JSON 输出。
-
prompt_template(str | None, default:None) –可选,自定义系统提示词。
-
input_instruction_key(str, default:'instruction') –输入指令字段名,默认 'instruction'。
-
input_code_key(str, default:'new_code') –输入代码字段名,默认 'new_code'。
-
output_score_key(str, default:'quality_score') –输出分数字段名,默认 'quality_score'。
-
output_feedback_key(str, default:'feedback') –输出反馈字段名,默认 'feedback'。
-
**kwargs–传递给基类算子的其它参数。
Examples:
from lazyllm.tools.data.operators.codegen_ops import LogicIntegrityAuditor
op = LogicIntegrityAuditor(model=model)
item = {
'instruction': "Write a Python function that prints 'hello'.",
'new_code': "def solution():
print('hello')"
}
res = op(item)
print(res)
# {
# 'instruction': "Write a Python function that prints 'hello'.",
# 'new_code': "def solution():
print('hello')",
# 'quality_score': 8,
# 'feedback': 'Good code. The logic is clear and follows PEP8.'
# }
Source code in lazyllm/tools/data/operators/codegen_ops.py
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 | |
ScriptSynthesizer
Bases: CodeGenOps
代码生成流水线算子:指令到代码生成器。
给定自然语言代码指令(通常是上一阶段生成的 generated_instruction 或精简后的 instruction),生成对应的 Python 源代码文本,并尝试自动去掉 Markdown 代码块外壳,只保留代码本身。
输出示例结构(默认 input_key='instruction', output_key='new_code'):
- instruction: 自然语言代码指令
- new_code (str): 生成的 Python 代码字符串
Parameters:
-
model–LazyLLM 模型对象(必需)。
-
prompt_template(str | None, default:None) –可选,自定义系统提示词。
-
input_key(str, default:'instruction') –输入指令字段名,默认 'instruction'。
-
output_key(str, default:'new_code') –输出代码字段名,默认 'new_code'。
-
**kwargs–传递给基类算子的其它参数。
Examples:
from lazyllm.tools.data.operators.codegen_ops import ScriptSynthesizer
op = ScriptSynthesizer(model=model,
input_key='instruction',
output_key='new_code')
item = {
'instruction': 'Write a Python function that prints "hello".'
}
res = op(item)
print(res)
# {
# 'instruction': 'Write a Python function that prints "hello".',
# 'new_code': "def solution():
print('hello')"
# }
Source code in lazyllm/tools/data/operators/codegen_ops.py
ThresholdSieve
Bases: CodeGenOps
代码生成流水线算子:代码质量分数过滤器。
基于 LogicIntegrityAuditor 的打分结果,对样本进行区间过滤:
- 若样本尚未包含 quality_score/feedback,会先自动调用内部 scorer 进行评估;
- 若得分在 [min_score, max_score] 区间内,则为样本打上标签并保留;
- 否则返回空列表 [],表示此样本在流水线中被过滤掉。
输出示例结构(默认 output_key='quality_score_filter_label'):
- instruction: ...
- new_code: ...
- quality_score: 8
- feedback: 'Good code. ...'
- quality_score_filter_label: 1 (通过过滤为 1,未通过则样本被丢弃)
Parameters:
-
model–LazyLLM 模型对象(必需),用于内部评估。
-
min_score(int, default:7) –通过过滤的最小分数(含),默认 7。
-
max_score(int, default:10) –通过过滤的最大分数(含),默认 10。
-
input_instruction_key(str, default:'instruction') –输入指令字段名,默认 'instruction'。
-
input_code_key(str, default:'new_code') –输入代码字段名,默认 'new_code'。
-
output_score_key(str, default:'quality_score') –分数字段名,默认 'quality_score'。
-
output_feedback_key(str, default:'feedback') –反馈字段名,默认 'feedback'。
-
output_key(str, default:'quality_score_filter_label') –过滤标签字段名,默认 'quality_score_filter_label'。
-
**kwargs–传递给基类算子的其它参数。
Examples:
from lazyllm.tools.data.operators.codegen_ops import ThresholdSieve
op = ThresholdSieve(model=model, min_score=7, max_score=10)
item = {
'instruction': "Write a Python function that prints 'hello'.",
'new_code': "def solution():
print('hello')"
}
res = op(item)
print(res)
# {
# 'instruction': '...',
# 'new_code': '...',
# 'quality_score': 8,
# 'feedback': 'Good code. The logic is clear and follows PEP8.',
# 'quality_score_filter_label': 1
# }
Source code in lazyllm/tools/data/operators/codegen_ops.py
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 | |
Agentic rag
lazyllm.tools.data.operators.agentic_rag.agenticrag_atomic_task_generator
AgenticRAGCleanQA
Bases: agenticrag
对生成的问答对进行清洗与答案规范化。调用 LLM 生成 refined_answer,用于后续验证与评分。
Parameters:
-
llm–语言模型服务实例
-
**kwargs(dict, default:{}) –其它可选的参数。
Examples:
from lazyllm.tools.data import agenticrag
op = agenticrag.AgenticRAGCleanQA(llm=my_llm)
result = op({'question': 'What is...', 'answer': 'Raw answer'})
print(result['refined_answer'])
Source code in lazyllm/tools/data/operators/agentic_rag/agenticrag_atomic_task_generator.py
AgenticRAGExpandConclusions
Bases: agenticrag
解析 raw_conclusion 字段中的 JSON 结论列表, 并将其展开为多条候选任务数据。
仅保留包含 'conclusion' 和 'R' 字段的条目, 为每个条目生成独立数据行,并写入 candidate_tasks_str。
Parameters:
-
max_per_task(int, default:10) –每个样本最多展开的候选任务数量
-
**kwargs(dict, default:{}) –其它可选的参数。
Examples:
from lazyllm.tools.data import agenticrag
op = agenticrag.AgenticRAGExpandConclusions(max_per_task=5)
rows = op({
'raw_conclusion': '[{"conclusion":"A","R":"rel"}]',
'identifier': 'doc1'
})
print(rows)
Source code in lazyllm/tools/data/operators/agentic_rag/agenticrag_atomic_task_generator.py
AgenticRAGGenerateQuestion
Bases: agenticrag
根据主要内容标识符(ID), 关系(R), 答案(A) 生成问题(question)与标准答案(answer)的算子。
Parameters:
-
llm–语言模型服务实例
-
**kwargs(dict, default:{}) –其它可选的参数。
Examples:
from lazyllm.tools.data import agenticrag
op = agenticrag.AgenticRAGGenerateQuestion(llm=my_llm)
result = op({
'candidate_tasks_str': '{"conclusion":"Paris","R":"capital_of"}',
'identifier': 'France'
})
print(result['question'], result['answer'])
Source code in lazyllm/tools/data/operators/agentic_rag/agenticrag_atomic_task_generator.py
AgenticRAGGetConclusion
Bases: agenticrag
调用 LLM 进行结论提取和关系生成的算子。
该算子根据输入文本构造提示词,并将模型的原始输出 保存至 data['raw_conclusion'],供后续 JSON 解析与任务展开使用。 若生成失败,则写入空字符串。
Parameters:
-
llm–语言模型服务实例
-
input_key(str, default:'prompts') –输入文本字段名,默认 'prompts'
-
**kwargs(dict, default:{}) –其它可选的参数。
Examples:
from lazyllm.tools.data import agenticrag
op = agenticrag.AgenticRAGGetConclusion(llm=my_llm)
result = op({'prompts': 'Some document content'})
print(result['raw_conclusion'])
Source code in lazyllm/tools/data/operators/agentic_rag/agenticrag_atomic_task_generator.py
AgenticRAGGetIdentifier
Bases: agenticrag
调用 LLM 从输入文本中抽取内容标识符(identifier)的算子。
Parameters:
-
llm–语言模型服务实例
-
input_key(str, default:'prompts') –输入文本字段名,默认 'prompts'
-
**kwargs(dict, default:{}) –其它可选的参数。
Examples:
from lazyllm.tools.data import agenticrag
op = agenticrag.AgenticRAGGetIdentifier(llm=my_llm, input_key='prompts')
result = op({'prompts': 'What is the third movie in the Avatar series?'})
print('identifier:', result['identifier'])
# {'identifier': 'Avatar series'}
Source code in lazyllm/tools/data/operators/agentic_rag/agenticrag_atomic_task_generator.py
AgenticRAGGoldenDocAnswer
Bases: agenticrag
基于黄金文档生成答案并进行评分验证。
使用 golden_doc 与 question 生成答案, 再与 refined_answer 进行评分。 若评分不足则过滤样本。
Parameters:
-
llm–语言模型服务实例
-
input_key(str, default:'prompts') –黄金文档字段名
-
**kwargs(dict, default:{}) –其它可选的参数。
Examples:
from lazyllm.tools.data import agenticrag
op = agenticrag.AgenticRAGGoldenDocAnswer(llm=my_llm)
result = op({
'prompts': 'Golden document text',
'question': 'Q?',
'refined_answer': 'Expected A'
})
print(result)
Source code in lazyllm/tools/data/operators/agentic_rag/agenticrag_atomic_task_generator.py
369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 | |
AgenticRAGGroupAndLimit
Bases: agenticrag
按指定字段分组并限制每组最大问答数量。
对批量数据按 input_key 分组, 每组最多保留 max_question 条, 用于控制同源样本数量。
Parameters:
-
input_key(str, default:'prompts') –分组字段名
-
max_question(int, default:10) –每组最大问答数量
Examples:
from lazyllm.tools.data import agenticrag
op = agenticrag.AgenticRAGGroupAndLimit(input_key='prompts', max_question=2)
result = op([
{'prompts': 'doc1', 'question': 'Q1'},
{'prompts': 'doc1', 'question': 'Q2'},
{'prompts': 'doc1', 'question': 'Q3'}
])
print(result) # only 2 kept for doc1
Source code in lazyllm/tools/data/operators/agentic_rag/agenticrag_atomic_task_generator.py
AgenticRAGLLMVerify
Bases: agenticrag
使用 LLM 对问答进行回答与召回评分验证。
先让模型根据 question 生成 llm_answer, 再对 refined_answer 与 llm_answer 进行评分。 若评分 >= 1,则过滤该样本;否则保留。
Parameters:
-
llm–语言模型服务实例
-
**kwargs(dict, default:{}) –其它可选的参数。
Examples:
from lazyllm.tools.data import agenticrag
op = agenticrag.AgenticRAGLLMVerify(llm=my_llm)
result = op({'question': 'Q?', 'refined_answer': 'A'})
print(result)
Source code in lazyllm/tools/data/operators/agentic_rag/agenticrag_atomic_task_generator.py
AgenticRAGOptionalAnswers
Bases: agenticrag
为标准答案生成多个可选答案。
基于 refined_answer 调用 LLM, 生成语义等价或近似表达的答案列表, 写入 optional_answer 字段。
Parameters:
-
llm–语言模型服务实例
Examples:
from lazyllm.tools.data import agenticrag
op = agenticrag.AgenticRAGOptionalAnswers(llm=my_llm)
result = op({'refined_answer': 'Paris'})
print(result['optional_answer'])
Source code in lazyllm/tools/data/operators/agentic_rag/agenticrag_atomic_task_generator.py
lazyllm.tools.data.operators.agentic_rag.agenticrag_depth_qa_generator
DepthQAGBackwardTask
Bases: agenticrag
根据现有标识符生成反向任务,产生新的标识符和关系。
该算子用于从给定的 identifier 反向推理,生成新的 identifier 和对应的 relation, 用于构建深度问答任务。
Parameters:
-
llm–语言模型服务实例
-
identifier_key(str, default:'identifier') –原始标识符字段名,默认 'identifier'
-
new_identifier_key(str, default:'new_identifier') –新生成的标识符字段名,默认 'new_identifier'
-
relation_key(str, default:'relation') –关系字段名,默认 'relation'
-
**kwargs(dict, default:{}) –其它可选的参数。
Examples:
from lazyllm.tools.data import agenticrag
op = agenticrag.DepthQAGBackwardTask(llm=my_llm)
result = op({'identifier': 'machine learning'})
print(result)
# {'identifier': 'machine learning', 'new_identifier': '...', 'relation': '...'}
Source code in lazyllm/tools/data/operators/agentic_rag/agenticrag_depth_qa_generator.py
DepthQAGCheckSuperset
Bases: agenticrag
检查新生成的查询是否为原始标识符的超集。
验证 new_identifier 和 relation 组合后是否构成对原始 identifier 的有效超集查询, 若验证通过则保留数据,否则返回空列表过滤掉该样本。
Parameters:
-
llm–语言模型服务实例
-
new_identifier_key(str, default:'new_identifier') –新标识符字段名,默认 'new_identifier'
-
relation_key(str, default:'relation') –关系字段名,默认 'relation'
-
identifier_key(str, default:'identifier') –原始标识符字段名,默认 'identifier'
-
**kwargs(dict, default:{}) –其它可选的参数。
Examples:
from lazyllm.tools.data import agenticrag
op = agenticrag.DepthQAGCheckSuperset(llm=my_llm)
result = op({
'identifier': 'Paris',
'new_identifier': 'France',
'relation': 'capital_of'
})
print(result) # returns data if valid, empty list if invalid
Source code in lazyllm/tools/data/operators/agentic_rag/agenticrag_depth_qa_generator.py
DepthQAGGenerateQuestion
Bases: agenticrag
根据新标识符、关系和原始标识符生成深度问题。
使用 LLM 基于 new_identifier、relation 和 identifier 生成深度问答任务中的问题, 存储在指定的 question_key 字段中。
Parameters:
-
llm–语言模型服务实例
-
new_identifier_key(str, default:'new_identifier') –新标识符字段名,默认 'new_identifier'
-
relation_key(str, default:'relation') –关系字段名,默认 'relation'
-
identifier_key(str, default:'identifier') –原始标识符字段名,默认 'identifier'
-
question_key(str, default:'depth_question') –生成问题存储的字段名,默认 'depth_question'
-
**kwargs(dict, default:{}) –其它可选的参数。
Examples:
from lazyllm.tools.data import agenticrag
op = agenticrag.DepthQAGGenerateQuestion(llm=my_llm)
result = op({
'identifier': 'Paris',
'new_identifier': 'France',
'relation': 'capital_of'
})
print(result['depth_question'])
# 'What is the capital of France?'
Source code in lazyllm/tools/data/operators/agentic_rag/agenticrag_depth_qa_generator.py
DepthQAGGetIdentifier
Bases: agenticrag
调用 LLM 从输入文本中抽取内容标识符(identifier)的算子。
如果数据中已存在 identifier 字段,则跳过处理。
Parameters:
-
llm–语言模型服务实例
-
input_key(str, default:'question') –输入文本字段名,默认 'question'
-
**kwargs(dict, default:{}) –其它可选的参数。
Examples:
from lazyllm.tools.data import agenticrag
op = agenticrag.DepthQAGGetIdentifier(llm=my_llm, input_key='question')
result = op({'question': 'What is the capital of France?'})
print('identifier:', result['identifier'])
# {'identifier': 'capital of France'}
Source code in lazyllm/tools/data/operators/agentic_rag/agenticrag_depth_qa_generator.py
DepthQAGVerifyQuestion
Bases: agenticrag
验证生成问题的质量,过滤过于简单的问题。
先让 LLM 回答问题生成 llm_answer,然后与 refined_answer 进行召回评分。 若评分 >= 1(表示问题太简单),则过滤该样本;否则保留数据。
Parameters:
-
llm–语言模型服务实例
-
question_key(str, default:'depth_question') –问题字段名,默认 'depth_question'
-
**kwargs(dict, default:{}) –其它可选的参数。
Examples:
from lazyllm.tools.data import agenticrag
op = agenticrag.DepthQAGVerifyQuestion(llm=my_llm)
result = op({
'depth_question': 'What is the capital of France?',
'refined_answer': 'Paris'
})
# Returns data if question is challenging, empty list if too easy
print(result)
Source code in lazyllm/tools/data/operators/agentic_rag/agenticrag_depth_qa_generator.py
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 | |
lazyllm.tools.data.operators.agentic_rag.agenticrag_qaf1_sample_evaluator
qaf1_calculate_score(data, result_key='F1Score')
计算问答对的 F1 分数的函数。
基于规范化后的预测答案和参考答案计算 F1 分数(综合考虑精确率和召回率)。 支持多个参考答案,取最高 F1 分数作为最终结果。计算完成后清理临时字段。
Parameters:
-
data(dict) –单条数据字典
-
output_key(str) –输出 F1 分数的字段名,默认 'F1Score'
Examples:
from lazyllm.tools.data import agenticrag
op = agenticrag.qaf1_calculate_score(output_key='F1Score')
result = op({
'_normalized_prediction': 'paris is capital',
'_normalized_ground_truths': ['capital is paris', 'paris capital france']
})
print(result['F1Score']) # F1 score value between 0.0 and 1.0
Source code in lazyllm/tools/data/operators/agentic_rag/agenticrag_qaf1_sample_evaluator.py
qaf1_normalize_texts(data, predicted_key='refined_answer', reference_key='golden_doc_answer')
规范化预测答案和参考答案文本的函数。
对预测答案和参考答案进行标准化处理,包括:转换为小写、移除标点符号、 移除冠词(a/an/the)、规范化空白字符。规范化后的结果存储在临时字段中, 供后续 F1 分数计算使用。
Parameters:
-
data(dict) –单条数据字典
-
prediction_key(str) –预测答案字段名,默认 'refined_answer'
-
ground_truth_key(str) –参考答案字段名,默认 'golden_doc_answer'
Examples:
from lazyllm.tools.data import agenticrag
op = agenticrag.qaf1_normalize_texts(prediction_key='refined_answer', ground_truth_key='golden_doc_answer')
result = op({
'refined_answer': 'Paris is the capital.',
'golden_doc_answer': 'The capital is Paris!'
})
print(result['_normalized_prediction']) # 'paris is capital'
print(result['_normalized_ground_truths']) # ['capital is paris']
Source code in lazyllm/tools/data/operators/agentic_rag/agenticrag_qaf1_sample_evaluator.py
lazyllm.tools.data.operators.agentic_rag.agenticrag_width_qa_generator
WidthQAGCheckDecomposition
Bases: agenticrag
验证合并后的问题是否有效分解了原始问题的算子。
该算子检查 LLM 生成的复杂问题是否正确地分解和包含了原始问题, 如果验证通过则保留数据,否则返回空列表过滤掉该样本。
Parameters:
-
llm–语言模型服务实例
-
output_question_key(str, default:'generated_width_task') –输出生成问题的字段名,默认 'generated_width_task'
-
**kwargs(dict, default:{}) –其它可选的参数。
Examples:
from lazyllm.tools.data import agenticrag
op = agenticrag.WidthQAGCheckDecomposition(llm=my_llm)
result = op({
'question': 'What are the capitals of France and UK?',
'original_question': ['What is Paris?', 'What is London?'],
'index': 0
})
print(result) # Returns data if valid, empty list if invalid
Source code in lazyllm/tools/data/operators/agentic_rag/agenticrag_width_qa_generator.py
WidthQAGFilterByScore
Bases: agenticrag
根据召回评分过滤广度问题的算子。
该算子对比 golden_answer 和 llm_answer 计算召回评分, 若评分 >= 1 则过滤该样本(表示问题太简单或 LLM 回答太好); 否则保留数据并清理临时字段。
Parameters:
-
llm–语言模型服务实例
-
**kwargs(dict, default:{}) –其它可选的参数。
Examples:
from lazyllm.tools.data import agenticrag
op = agenticrag.WidthQAGFilterByScore(llm=my_llm)
result = op({
'original_answer': ['Paris', 'London'],
'llm_answer': 'Paris is the capital of France and London is the capital of UK',
'state': 1
})
# Returns data if score < 1, empty list if score >= 1
print(result)
Source code in lazyllm/tools/data/operators/agentic_rag/agenticrag_width_qa_generator.py
WidthQAGMergePairs
Bases: agenticrag
将相邻的问答对合并生成广度问题的算子。
该算子接收批量问答数据,通过 LLM 将相邻的两个问答对合并为一个更复杂的广度问题。 需要至少2条数据才能进行合并操作。
Parameters:
-
llm–语言模型服务实例
-
**kwargs(dict, default:{}) –其它可选的参数。
Examples:
from lazyllm.tools.data import agenticrag
op = agenticrag.WidthQAGMergePairs(llm=my_llm)
result = op([
{'question': 'What is Paris?', 'golden_answer': 'Capital of France'},
{'question': 'What is London?', 'golden_answer': 'Capital of UK'}
])
print(result[0]['question']) # Merged complex question
Source code in lazyllm/tools/data/operators/agentic_rag/agenticrag_width_qa_generator.py
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | |
WidthQAGVerifyQuestion
Bases: agenticrag
验证生成的问题能否被正确回答的算子。
该算子使用 LLM 尝试回答生成的问题,并将答案存储在 llm_answer 字段中, 供后续评分使用。
Parameters:
-
llm–语言模型服务实例
-
output_question_key(str, default:'generated_width_task') –问题字段名,默认 'generated_width_task'
-
**kwargs(dict, default:{}) –其它可选的参数。
Examples:
from lazyllm.tools.data import agenticrag
op = agenticrag.WidthQAGVerifyQuestion(llm=my_llm)
result = op({
'generated_width_task': 'What are the capitals of France and UK?',
'index': 0
})
print(result['llm_answer']) # LLM's answer to the question
Source code in lazyllm/tools/data/operators/agentic_rag/agenticrag_width_qa_generator.py
纯文本生成QA对算子
lazyllm.tools.data.operators.text2qa_ops
ChunkToQA
Bases: Text2qa
基于大模型将每个文本块生成一个 QA 对(问题 + 答案)。使用 JsonFormatter 约束输出格式,可自定义 user_prompt 或使用默认「根据下面文本生成一个 QA 对」。
Parameters:
-
input_key(str, default:'chunk') –输入块字段名,默认 'chunk'
-
query_key(str, default:'query') –生成的问题写入的字段名,默认 'query'
-
answer_key(str, default:'answer') –生成的答案写入的字段名,默认 'answer'
-
model–可选,TrainableModule 或兼容接口;None 时使用默认 Qwen 模型
-
user_prompt(str | None, default:None) –可选,用户提示前缀;None 时使用默认
-
**kwargs–其它基类参数
Examples:
from lazyllm.tools.data import Text2qa
from lazyllm import OnlineChatModule
llm = OnlineChatModule()
op = Text2qa.ChunkToQA(input_key='chunk', query_key='query', answer_key='answer', model=llm)
data = [{'chunk': '今天是晴天!'}]
res = op(data)
print(res)
# [{'chunk': '今天是晴天!', 'query': '今天的天气怎么样?', 'answer': '今天是晴天!'}]
Source code in lazyllm/tools/data/operators/text2qa_ops.py
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 | |
QAScorer
Bases: Text2qa
基于大模型对 QA 对进行打分:判断答案是否严格基于原文,输出 1(基于原文)或 0(否则)。使用 JsonFormatter 约束输出 score 字段。
Parameters:
-
input_key(str, default:'chunk') –原文块字段名,默认 'chunk'
-
output_key(str, default:'score') –分数写入的字段名,默认 'score'
-
query_key(str, default:'query') –问题字段名,默认 'query'
-
answer_key(str, default:'answer') –答案字段名,默认 'answer'
-
model–可选,TrainableModule 或兼容接口;None 时使用默认 Qwen 模型
-
user_prompt(str | None, default:None) –可选,用户提示;None 时使用默认规则(严格基于原文→1,否则→0)
-
**kwargs–其它基类参数
Examples:
from lazyllm.tools.data import Text2qa
from lazyllm import OnlineChatModule
llm = OnlineChatModule()
op = Text2qa.QAScorer(input_key='chunk', output_key='score', query_key='query', answer_key='answer', model=llm)
data = [
{'chunk': '今天是晴天!', 'query': '今天的天气怎么样?', 'answer': '今天是晴天!'},
{'chunk': '1+1=2', 'query': '1+1=?', 'answer': '3'}
]
res = op(data)
print(res)
# [{'chunk': '今天是晴天!', 'query': '今天的天气怎么样?', 'answer': '今天是晴天!', 'score': 1}, {'chunk': '1+1=2', 'query': '1+1=?', 'answer': '3', 'score': 0}]
Source code in lazyllm/tools/data/operators/text2qa_ops.py
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 | |
TextToChunks
Bases: Text2qa
将输入文本按行切分为多个块(chunk),每条输入可展开为多条输出。支持按 token 数或字符数控制块大小,可选用 tokenizer 或按字符计数。
Parameters:
-
input_key(str, default:'content') –输入文本字段名,默认 'content'
-
output_key(str, default:'chunk') –输出块内容写入的字段名,默认 'chunk'
-
chunk_size(int, default:10) –每块的最大长度(token 数或字符数),默认 10
-
tokenize(bool, default:True) –是否按 token 计数;为 True 且未提供 tokenizer 时使用默认 Qwen tokenizer
-
tokenizer–可选,用于计数的 tokenizer;None 时若 tokenize=True 则自动加载默认
-
**kwargs–其它基类参数(如 _concurrency_mode、_max_workers 等)
Examples:
from lazyllm.tools.data import Text2qa
op = Text2qa.TextToChunks(input_key='content', output_key='chunk', chunk_size=10, tokenize=False)
data = [{'content': 'line1
line2
line3
line4'}]
res = op(data)
print(res)
# [{'content': 'line1
line2
line3
line4', 'chunk': 'line1
line2'}, {'content': 'line1
line2
line3
line4', 'chunk': 'line3
line4'}]
Source code in lazyllm/tools/data/operators/text2qa_ops.py
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | |
empty_or_noise_filter(data, input_key='chunk')
过滤空内容或纯噪声数据。若指定字段为空或仅包含非字母/非 CJK 字符则丢弃该条(返回空列表),否则保留原数据。以 forward 单条方式注册。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'chunk') –要检查的字段名,默认 'chunk'
Examples:
from lazyllm.tools.data import Text2qa
op = Text2qa.empty_or_noise_filter(input_key='chunk')
data = [{'chunk': 'hello'}, {'chunk': ''}, {'chunk': '
'}]
res = op(data)
print(res)
# [{'chunk': 'hello'}]
Source code in lazyllm/tools/data/operators/text2qa_ops.py
invalid_unicode_cleaner(data, input_key='chunk')
清除指定文本字段中的无效 Unicode 码位(如 FDD0–FDEF、FFFE/FFFF 及若干 Supplementary Special Purpose 区段),原地修改并返回数据。以 forward 单条方式注册。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'chunk') –要清洗的文本字段名,默认 'chunk'
Examples:
from lazyllm.tools.data import Text2qa
op = Text2qa.invalid_unicode_cleaner(input_key='chunk')
data = {'chunk': 'valid text tail'}
res = op(data) # 剔除乱码
print(res)
[{'chunk': 'valid text tail'}]
Source code in lazyllm/tools/data/operators/text2qa_ops.py
Embedding 数据合成
lazyllm.tools.data.operators.embedding_synthesis
EmbeddingFormatFlagEmbedding
Bases: embedding
将数据格式化为 FlagEmbedding 训练格式的算子。
该算子将输入的 query、pos(正样本)、neg(负样本)格式化为 FlagEmbedding 框架所需的训练数据格式。 支持添加指令(instruction)字段用于有监督的 Embedding 训练。
Parameters:
-
instruction(str, default:None) –指令文本,用于有监督训练场景。默认为 None。
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
dict–包含 query、pos、neg 和可选 prompt 字段的字典。
Examples:
from lazyllm.tools.data import embedding
op = embedding.EmbeddingFormatFlagEmbedding(instruction='Represent this sentence for searching relevant passages:')
result = op({'query': 'machine learning', 'pos': ['ML tutorial'], 'neg': ['cooking recipe']})
# Returns: {'query': 'machine learning', 'pos': ['ML tutorial'], 'neg': ['cooking recipe'], 'prompt': 'Represent this sentence for searching relevant passages:'}
Source code in lazyllm/tools/data/operators/embedding_synthesis/embedding_data_formatter.py
EmbeddingFormatSentenceTransformers
Bases: embedding
将数据格式化为 SentenceTransformers 三元组训练格式的算子。
该算子将输入的 query、pos(正样本)、neg(负样本)转换为 SentenceTransformers 框架所需的 anchor-positive-negative 三元组格式。 适用于 MultipleNegativesRankingLoss 等损失函数的训练。
Parameters:
-
**kwargs(dict, default:{}) –可选的参数,传递给父类。
Returns:
-
–
List[dict]: 包含 anchor、positive、negative 字段的字典列表,每对正负样本生成一个三元组。
Examples:
from lazyllm.tools.data import embedding
op = embedding.EmbeddingFormatSentenceTransformers()
result = op({'query': 'machine learning', 'pos': ['ML basics'], 'neg': ['cooking tips']})
# Returns: [{'anchor': 'machine learning', 'positive': 'ML basics', 'negative': 'cooking tips'}]
Source code in lazyllm/tools/data/operators/embedding_synthesis/embedding_data_formatter.py
EmbeddingFormatTriplet
Bases: embedding
将数据格式化为通用三元组格式的算子。
该算子将输入的 query、pos(正样本)、neg(负样本)转换为标准的三元组格式, 字段名为 query、positive、negative。适用于多种 Embedding 训练框架。
Parameters:
-
**kwargs(dict, default:{}) –可选的参数,传递给父类。
Returns:
-
–
List[dict]: 包含 query、positive、negative 字段的字典列表,每对正负样本生成一个三元组。
Examples:
from lazyllm.tools.data import embedding
op = embedding.EmbeddingFormatTriplet()
result = op({'query': 'deep learning', 'pos': ['neural networks', 'AI'], 'neg': ['history', 'geography']})
# Returns list of triplets combining each positive with each negative
Source code in lazyllm/tools/data/operators/embedding_synthesis/embedding_data_formatter.py
EmbeddingGenerateQueries
Bases: embedding
使用 LLM 生成查询的算子。
该算子调用语言模型服务,基于构建的提示生成查询。返回 JSON 格式的查询响应。
Parameters:
-
llm–LLM 服务实例,用于生成查询。
-
num_queries(int, default:3) –要生成的查询数量,默认为 3。
-
lang(str, default:'zh') –语言,'zh' 表示中文,'en' 表示英文,默认为 'zh'。
-
query_types(List[str], default:None) –查询类型列表,默认为 ['factual', 'semantic', 'inferential']。
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
dict–输入数据,添加了 '_query_response' 字段包含生成的查询响应。
Examples:
from lazyllm.tools.data import embedding
# Assuming llm is an LLM service instance
generator = embedding.EmbeddingGenerateQueries(llm=llm, lang='zh')
data = {'_query_prompt': 'Generate queries for: machine learning tutorial'}
result = generator(data)
# Returns data with '_query_response' field containing JSON queries
Source code in lazyllm/tools/data/operators/embedding_synthesis/embedding_query_generator.py
EmbeddingInitBM25
Bases: embedding
初始化 BM25 索引的算子。
该算子基于语料库构建 BM25 索引,用于后续的关键词检索和困难负样本挖掘。 支持中英文分词,使用 jieba 进行中文分词,Stemmer 进行英文词干提取。
Parameters:
-
language(str, default:'zh') –语言类型,'zh' 表示中文,'en' 表示英文,默认为 'zh'。
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
–
List[dict]: 输入数据,每条数据添加了 BM25 索引和相关配置信息。
Examples:
from lazyllm.tools.data import embedding
# First build corpus, then initialize BM25
corpus_op = embedding.build_embedding_corpus(input_pos_key='pos')
bm25_op = embedding.EmbeddingInitBM25(language='zh')
# Returns data with '_bm25' index and tokenizer configuration
Source code in lazyllm/tools/data/operators/embedding_synthesis/embedding_hard_negative_miner.py
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | |
EmbeddingInitSemantic
Bases: embedding
初始化语义嵌入向量的算子。
该算子使用 Embedding 服务计算语料库中所有文档的向量表示,并保存到文件中。 用于后续的语义相似度计算和困难负样本挖掘。
Parameters:
-
embedding_serving(Callable, default:None) –Embedding 服务调用函数,用于计算文本向量。
-
embeddings_dir(str, default:None) –向量文件保存目录,默认为语料库所在目录。
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
–
List[dict]: 输入数据,每条数据添加了语义向量文件路径和语料库信息。
Examples:
from lazyllm.tools.data import embedding
# Assuming my_embedding_fn is an embedding service
semantic_op = embedding.EmbeddingInitSemantic(embedding_serving=my_embedding_fn)
# Returns data with '_semantic_embeddings_path' pointing to saved embeddings
Source code in lazyllm/tools/data/operators/embedding_synthesis/embedding_hard_negative_miner.py
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 | |
EmbeddingMineSemanticNegatives
Bases: embedding
使用语义相似度挖掘困难负样本的算子。
该算子基于语义向量相似度,找出与查询最相似但不属于正样本的文档作为负样本。 适用于挖掘语义相近但实际不相关的困难负样本,通常比 BM25 方法效果更好。
Parameters:
-
num_negatives(int, default:7) –需要挖掘的负样本数量,默认为 7。
-
embedding_serving(Callable, default:None) –Embedding 服务调用函数,用于计算查询向量。
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
dict–输入数据,添加了基于语义相似度挖掘的负样本列表。
Examples:
from lazyllm.tools.data import embedding
# Assuming embeddings are initialized
semantic_miner = embedding.EmbeddingMineSemanticNegatives(num_negatives=5, embedding_serving=my_embedding_fn)
data = {'query': 'machine learning', 'pos': ['ML tutorial'], '_semantic_embeddings_path': emb_path, '_semantic_corpus': corpus}
result = semantic_miner(data)
# Returns data with 'neg' field containing semantically similar negative samples
Source code in lazyllm/tools/data/operators/embedding_synthesis/embedding_hard_negative_miner.py
426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 | |
EmbeddingParseQueries
Bases: embedding
解析生成的查询的算子。
该算子解析 LLM 生成的查询响应,将每条查询展开为独立的数据记录。
Parameters:
-
input_key(str, default:'passage') –输入字段名,默认为 'passage'。
-
output_query_key(str, default:'query') –输出查询字段名,默认为 'query'。
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
–
List[dict]: 解析后的查询列表,每个查询为一个独立的数据记录。
Examples:
from lazyllm.tools.data import embedding
parser = embedding.EmbeddingParseQueries(input_key='passage', output_query_key='query')
data = {'_query_response': '[{"query": "what is ML?", "type": "factual"}]', 'passage': 'Machine learning is...'}
result = parser(data)
# Returns list of expanded query records with 'query' and 'pos' fields
Source code in lazyllm/tools/data/operators/embedding_synthesis/embedding_query_generator.py
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | |
EmbeddingTrainTestSplitter
Bases: embedding
将数据集分割为训练集和测试集的算子。
该算子对输入数据进行随机打乱,并按指定比例分割为训练集和测试集。 支持保存分割后的数据到 JSONL 文件,并可按指定键进行分层抽样。
Parameters:
-
test_size(float, default:0.1) –测试集比例,默认为 0.1(即 10%)。
-
seed(int, default:42) –随机种子,用于可复现的分割结果,默认为 42。
-
stratify_key(str, default:None) –分层抽样的键名,默认为 None。
-
train_output_file(str, default:None) –训练集输出文件路径,默认为 None。
-
test_output_file(str, default:None) –测试集输出文件路径,默认为 None。
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
–
List[dict]: 包含训练集和测试集的所有样本,每个样本添加了 'split' 字段标记所属集合。
Examples:
from lazyllm.tools.data import embedding
op = embedding.EmbeddingTrainTestSplitter(test_size=0.2, seed=123, train_output_file='train.jsonl', test_output_file='test.jsonl')
data = [{'query': 'q1', 'pos': 'p1'}, {'query': 'q2', 'pos': 'p2'}, {'query': 'q3', 'pos': 'p3'}]
result = op(data)
# Returns all samples with 'split' field ('train' or 'test')
# Saves train data to train.jsonl and test data to test.jsonl
Source code in lazyllm/tools/data/operators/embedding_synthesis/embedding_data_formatter.py
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 | |
知识库清洗
lazyllm.tools.data.operators.knowledge_cleaning.file_or_url_to_markdown_converter_api
FileOrURLNormalizer
Bases: kbc
文件或URL标准化算子。
该算子根据输入类型(文件或URL)自动识别文件格式,进行标准化处理。 支持PDF、HTML/XML、TXT/MD等文件格式,以及网页URL。对于网络PDF,会先下载到本地。
Parameters:
-
intermediate_dir(str, default:'intermediate') –中间文件保存目录,默认为 'intermediate'。
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
dict–标准化后的数据,包含以下字段:
-
_type–文件类型 ('pdf', 'html', 'text', 'invalid', 'unsupported')
-
_raw_path–本地文件路径(如果有)
-
_url–URL地址(如果是网页)
-
_output_path–预期的Markdown输出路径
-
_error–错误信息(如果有)
Examples:
from lazyllm.tools.data import kbc
normalizer = kbc.FileOrURLNormalizer(intermediate_dir='./temp')
# For file input
data = {'source': '/path/to/document.pdf'}
result = normalizer(data)
# Returns: {'source': '/path/to/document.pdf', '_type': 'pdf', '_raw_path': '/path/to/document.pdf', '_output_path': './temp/document.md'}
# For URL input
data = {'source': 'https://example.com/page.html'}
result = normalizer(data)
# Returns: {'source': 'https://example.com/page.html', '_type': 'html', '_url': 'https://example.com/page.html', '_output_path': './temp/url_xxx.md'}
Source code in lazyllm/tools/data/operators/knowledge_cleaning/file_or_url_to_markdown_converter_api.py
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | |
HTMLToMarkdownConverter
Bases: kbc
HTML转Markdown转换器算子。
该算子使用trafilatura库从HTML或XML文件中提取内容并转换为Markdown格式。 支持本地HTML文件和网络URL,会自动处理页面元数据。
Parameters:
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
dict–转换后的数据,包含以下字段:
-
_markdown_path–生成的Markdown文件路径
Examples:
from lazyllm.tools.data import kbc
converter = kbc.HTMLToMarkdownConverter()
# After normalization
data = {'_type': 'html', '_url': 'https://example.com/article', '_output_path': './temp/output.md'}
result = converter(data)
# Returns: {'_type': 'html', '_url': 'https://example.com/article', '_output_path': './temp/output.md', '_markdown_path': './temp/output.md'}
Source code in lazyllm/tools/data/operators/knowledge_cleaning/file_or_url_to_markdown_converter_api.py
PDFToMarkdownConverterAPI
Bases: kbc
PDF转Markdown转换器API算子。
该算子使用MinerU服务将PDF文件(包括扫描件和图片)转换为Markdown格式。 支持通过API调用MinerU进行PDF解析,可配置后端引擎和上传模式。
Parameters:
-
mineru_url(str, default:None) –MinerU服务URL地址。
-
mineru_backend(str, default:'vlm-vllm-async-engine') –MinerU后端引擎类型,默认为 'vlm-vllm-async-engine'。
-
upload_mode(bool, default:True) –是否使用上传模式,默认为 True。
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
dict–转换后的数据,包含以下字段:
-
_markdown_path–生成的Markdown文件路径
Examples:
from lazyllm.tools.data import kbc
converter = kbc.PDFToMarkdownConverterAPI(
mineru_url='your_mineru_url',
mineru_backend='vlm-vllm-async-engine',
upload_mode=True
)
# After normalization
data = {'_type': 'pdf', '_raw_path': '/path/to/doc.pdf', '_output_path': './temp/output.md'}
result = converter(data)
# Returns: {'_type': 'pdf', '_raw_path': '/path/to/doc.pdf', '_output_path': './temp/output.md', '_markdown_path': './temp/output.md'}
Source code in lazyllm/tools/data/operators/knowledge_cleaning/file_or_url_to_markdown_converter_api.py
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 | |
lazyllm.tools.data.operators.knowledge_cleaning.kbc_chunk_generator_batch
KBCChunkText
Bases: kbc
文本分块算子。
该算子将长文本分割成小块(chunks),支持多种分块策略: - token: 基于Token数量分块 - sentence: 基于句子边界分块 - semantic: 基于语义相似度分块 - recursive: 递归分块
Parameters:
-
chunk_size(int, default:512) –每个块的最大大小,默认为 512。
-
chunk_overlap(int, default:50) –块之间的重叠大小,默认为 50。
-
split_method(str, default:'token') –分块方法,可选 'token', 'sentence', 'semantic', 'recursive',默认为 'token'。
-
tokenizer_name(str, default:'bert-base-uncased') –使用的tokenizer名称,默认为 'bert-base-uncased'。
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
dict–包含分块结果的数据:
-
_chunks–分块后的文本列表
-
_chunk_error–分块错误信息(如果有)
Examples:
from lazyllm.tools.data import kbc
chunker = kbc.KBCChunkText(chunk_size=512, chunk_overlap=50, split_method='token')
data = {'_text_content': 'Long text content that needs to be chunked...'}
result = chunker(data)
# Returns: {'_text_content': 'Long text content...', '_chunks': ['chunk1', 'chunk2', ...]}
Source code in lazyllm/tools/data/operators/knowledge_cleaning/kbc_chunk_generator_batch.py
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | |
KBCLoadText
Bases: kbc
加载文本文件内容的算子。
该算子从指定路径加载文本文件内容,支持多种文件格式: - .txt, .md, .xml: 直接读取文本内容 - .json, .jsonl: 从指定的文本字段中提取内容并合并
Parameters:
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
dict–包含加载结果的数据:
-
_text_content–加载的文本内容
-
_load_error–加载错误信息(如果有)
Examples:
from lazyllm.tools.data import kbc
loader = kbc.KBCLoadText()
# Load text file
data = {'text_path': '/path/to/document.txt'}
result = loader(data)
# Returns: {'text_path': '/path/to/document.txt', '_text_content': 'file content...'}
# Load JSON file
data = {'text_path': '/path/to/data.json'}
result = loader(data)
# Returns: {'text_path': '/path/to/data.json', '_text_content': 'extracted text...'}
Source code in lazyllm/tools/data/operators/knowledge_cleaning/kbc_chunk_generator_batch.py
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | |
KBCSaveChunks
Bases: kbc
保存文本分块结果的算子。
该算子将分块后的文本保存为JSON文件,每个分块作为一个JSON对象。 支持指定输出目录,会保留原始文件的相对路径结构。
Parameters:
-
output_dir(str, default:None) –输出目录路径,默认为 None(保存到原文件所在目录的 'extract' 子目录)。
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
dict–包含保存结果的数据:
-
chunk_path–保存的JSON文件路径
Examples:
from lazyllm.tools.data import kbc
saver = kbc.KBCSaveChunks(output_dir='./output')
data = {'text_path': '/path/to/doc.txt', '_chunks': ['chunk1', 'chunk2']}
result = saver(data)
# Returns: {'text_path': '/path/to/doc.txt', 'chunk_path': './output/path/to/doc_chunk.json'}
Source code in lazyllm/tools/data/operators/knowledge_cleaning/kbc_chunk_generator_batch.py
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 | |
lazyllm.tools.data.operators.knowledge_cleaning.kbc_chunk_generator
KBCExpandChunks
Bases: kbc
将分块文本展开为独立记录的算子。
该算子将包含多个文本分块的数据记录展开为多个独立的数据记录,每个记录包含一个分块。 适用于需要将分块后的文本作为独立样本进行后续处理的场景。
Parameters:
-
output_key(str, default:'raw_chunk') –输出字段名,用于存储分块文本,默认为 'raw_chunk'。
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
–
List[dict]: 展开后的独立数据记录列表,每个记录包含一个分块。
Examples:
from lazyllm.tools.data import kbc
expander = kbc.KBCExpandChunks(output_key='raw_chunk')
data = {'text_path': '/path/to/doc.txt', '_chunks': ['chunk1 content', 'chunk2 content', 'chunk3 content']}
result = expander(data)
# Returns: [
# {'text_path': '/path/to/doc.txt', 'raw_chunk': 'chunk1 content'},
# {'text_path': '/path/to/doc.txt', 'raw_chunk': 'chunk2 content'},
# {'text_path': '/path/to/doc.txt', 'raw_chunk': 'chunk3 content'}
# ]
Source code in lazyllm/tools/data/operators/knowledge_cleaning/kbc_chunk_generator.py
lazyllm.tools.data.operators.knowledge_cleaning.kbc_multihop_qa_generator_batch
KBCExtractInfoPairs
Bases: kbc
信息对提取算子。
该算子从预处理后的文本中提取信息对,用于生成多跳问答。 根据语言类型(中文或英文)使用不同的句子分割符, 提取前提-中间-结论三元组和相关上下文。
Parameters:
-
lang(str, default:'en') –语言类型,'en' 表示英文,'zh' 表示中文,默认为 'en'。
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
dict–包含信息对的数据:
-
_info_pairs–信息对列表,每个包含 premise、intermediate、conclusion 和 related_contexts
Examples:
from lazyllm.tools.data import kbc
extractor = kbc.KBCExtractInfoPairs(lang='en')
data = {'_processed_chunks': [{'text': 'First sentence. Second sentence. Third sentence.', 'original_data': {}}]}
result = extractor(data)
# Returns: {'_processed_chunks': [...], '_info_pairs': [{'premise': 'First sentence', 'intermediate': 'Second sentence', 'conclusion': 'Third sentence', 'related_contexts': [], 'original_data': {}}]}
Source code in lazyllm/tools/data/operators/knowledge_cleaning/kbc_multihop_qa_generator_batch.py
KBCGenerateMultiHopQA
Bases: kbc
多跳问答生成算子。
该算子使用LLM根据提取的信息对生成多跳问答对。 多跳问答需要多个推理步骤才能回答,适用于训练复杂的问答模型。
Parameters:
-
llm–LLM服务实例,用于生成问答对。
-
lang(str, default:'en') –语言类型,'en' 表示英文,'zh' 表示中文,默认为 'en'。
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
dict–包含生成的问答结果的数据:
-
_qa_results–问答结果列表,每个包含 response 和 info_pair
Examples:
from lazyllm.tools.data import kbc
# Assuming llm is an LLM service instance
generator = kbc.KBCGenerateMultiHopQA(llm=llm, lang='en')
data = {'_info_pairs': [{'premise': 'A', 'intermediate': 'B', 'conclusion': 'C', 'original_data': {}}]}
result = generator(data)
# Returns: {'_info_pairs': [...], '_qa_results': [{'response': {...}, 'info_pair': {...}}]}
Source code in lazyllm/tools/data/operators/knowledge_cleaning/kbc_multihop_qa_generator_batch.py
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | |
KBCLoadChunkFile
Bases: kbc
加载分块文件算子。
该算子从指定路径加载JSON或JSONL格式的分块文件。 支持从知识库清洗流程中生成的分块结果文件。
Parameters:
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
dict–包含分块数据的数据:
-
_chunks_data–分块数据列表
-
_chunk_path–分块文件路径
Examples:
from lazyllm.tools.data import kbc
loader = kbc.KBCLoadChunkFile()
data = {'chunk_path': '/path/to/chunks.json'}
result = loader(data)
# Returns: {'chunk_path': '/path/to/chunks.json', '_chunks_data': [...], '_chunk_path': '/path/to/chunks.json'}
Source code in lazyllm/tools/data/operators/knowledge_cleaning/kbc_multihop_qa_generator_batch.py
KBCPreprocessText
Bases: kbc
文本预处理算子。
该算子对加载的分块文本进行预处理,根据长度过滤分块。 只保留长度在指定范围内的分块,避免处理过短或过长的文本。
Parameters:
-
min_length(int, default:100) –最小文本长度,默认为 100。
-
max_length(int, default:200000) –最大文本长度,默认为 200000。
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
dict–包含预处理结果的数据:
-
_processed_chunks–预处理后的分块列表
Examples:
from lazyllm.tools.data import kbc
processor = kbc.KBCPreprocessText(min_length=50, max_length=10000)
data = {'_chunks_data': [{'cleaned_chunk': 'Short text.'}, {'cleaned_chunk': 'A much longer text that meets the length requirements and will be processed.'}]}
result = processor(data, text_field='cleaned_chunk')
# Returns: {'_chunks_data': [...], '_processed_chunks': [{'text': 'A much longer text...', 'original_data': {...}}]}
Source code in lazyllm/tools/data/operators/knowledge_cleaning/kbc_multihop_qa_generator_batch.py
KBCSaveEnhanced
Bases: kbc
保存增强数据算子。
该算子将生成的问答对与原始分块数据合并,保存为增强后的分块文件。 支持指定输出目录,会保留原始文件的相对路径结构。
Parameters:
-
output_dir(str, default:None) –输出目录路径,默认为 None(保存到原文件所在目录)。
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
dict–包含保存结果的数据:
-
enhanced_chunk_path–增强后的分块文件路径
Examples:
from lazyllm.tools.data import kbc
saver = kbc.KBCSaveEnhanced(output_dir='./enhanced_output')
data = {'_chunk_path': '/path/to/chunks.json', '_chunks_data': [{'id': 1, 'text': 'chunk1'}], '_qa_pairs': [{'id': 1, 'qa_pairs': {'question': 'Q1', 'answer': 'A1'}}]}
result = saver(data, output_key='enhanced_chunk_path')
# Returns: {'enhanced_chunk_path': './enhanced_output/path/to/chunks_enhanced.json'}
Source code in lazyllm/tools/data/operators/knowledge_cleaning/kbc_multihop_qa_generator_batch.py
parse_qa_pairs(data)
解析问答对函数。
该函数解析LLM生成的问答响应,提取有效的问答对。 支持多种响应格式(字典、列表、字符串),并将解析结果与原始数据合并。
Parameters:
-
data(dict) –包含问答结果的数据。
Returns:
-
dict(dict) –包含解析后的问答对的数据:
-
_qa_pairs(dict) –解析后的问答对列表
Examples:
from lazyllm.tools.data.operators.knowledge_cleaning.kbc_multihop_qa_generator_batch import parse_qa_pairs
data = {'_qa_results': [{'response': {'question': 'What is AI?', 'answer': 'Artificial Intelligence'}, 'info_pair': {'original_data': {'id': 1}}}]}
result = parse_qa_pairs(data)
# Returns: {'_qa_results': [...], '_qa_pairs': [{'id': 1, 'qa_pairs': {'question': 'What is AI?', 'answer': 'Artificial Intelligence'}}]}
Source code in lazyllm/tools/data/operators/knowledge_cleaning/kbc_multihop_qa_generator_batch.py
lazyllm.tools.data.operators.knowledge_cleaning.kbc_text_cleaner_batch
KBCGenerateCleanedText
Bases: kbc
生成清洗后文本的算子。
该算子使用LLM对原始分块文本进行清洗,去除噪声、格式化内容。 支持多语言,当LLM调用失败时会使用原始文本作为回退。
Parameters:
-
llm–LLM服务实例,用于清洗文本。
-
lang(str, default:'en') –语言类型,'en' 表示英文,'zh' 表示中文,默认为 'en'。
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
dict–包含清洗结果的数据:
-
_cleaned_results–清洗结果列表,每个包含 response、raw_chunk 和 original_item
Examples:
from lazyllm.tools.data import kbc
# Assuming llm is an LLM service instance
cleaner = kbc.KBCGenerateCleanedText(llm=llm, lang='en')
data = {'_chunks_data': [{'raw_chunk': 'Noisy text with errors...'}]}
result = cleaner(data)
# Returns: {'_chunks_data': [...], '_cleaned_results': [{'response': 'Cleaned text', 'raw_chunk': '...', 'original_item': {...}}]}
Source code in lazyllm/tools/data/operators/knowledge_cleaning/kbc_text_cleaner_batch.py
KBCLoadRAWChunkFile
Bases: kbc
加载原始分块文件算子。
该算子从指定路径加载包含原始分块(raw_chunk)的JSON或JSONL文件。 用于知识库清洗流程中加载需要清洗的原始分块数据。
Parameters:
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
dict–包含原始分块数据的数据:
-
_chunks_data–原始分块数据列表
-
_chunk_path–分块文件路径
Examples:
from lazyllm.tools.data import kbc
loader = kbc.KBCLoadRAWChunkFile()
data = {'chunk_path': '/path/to/raw_chunks.json'}
result = loader(data)
# Returns: {'chunk_path': '/path/to/raw_chunks.json', '_chunks_data': [{'raw_chunk': '...'}], '_chunk_path': '/path/to/raw_chunks.json'}
Source code in lazyllm/tools/data/operators/knowledge_cleaning/kbc_text_cleaner_batch.py
KBCSaveCleaned
Bases: kbc
保存清洗后数据算子。
该算子将清洗后的分块数据保存为JSON文件,保留原始分块和清洗后分块的对应关系。 支持指定输出目录,会保留原始文件的相对路径结构。
Parameters:
-
output_dir(str, default:None) –输出目录路径,默认为 None(保存到原文件所在目录)。
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
dict–包含保存结果的数据:
-
cleaned_chunk_path–清洗后的分块文件路径
Examples:
from lazyllm.tools.data import kbc
saver = kbc.KBCSaveCleaned(output_dir='./cleaned_output')
data = {'_chunk_path': '/path/to/raw_chunks.json', '_cleaned_chunks': [{'raw_chunk': 'raw', 'cleaned_chunk': 'cleaned'}]}
result = saver(data, output_key='cleaned_chunk_path')
# Returns: {'cleaned_chunk_path': './cleaned_output/path/to/raw_chunks_cleaned.json'}
Source code in lazyllm/tools/data/operators/knowledge_cleaning/kbc_text_cleaner_batch.py
extract_cleaned_content(data)
提取清洗内容函数。
该函数从LLM清洗结果中提取清洗后的文本内容,处理不同的响应格式。
支持从标签
Parameters:
-
data(dict) –包含清洗结果的数据。
Returns:
-
dict(dict) –包含提取后清洗内容的数据:
-
_cleaned_chunks(dict) –清洗后的分块列表,每个包含 raw_chunk、cleaned_chunk 和 original_item
Examples:
from lazyllm.tools.data.operators.knowledge_cleaning.kbc_text_cleaner_batch import extract_cleaned_content
data = {'_cleaned_results': [{'response': '<cleaned_start>Clean text<cleaned_end>', 'raw_chunk': 'raw', 'original_item': {}}]}
result = extract_cleaned_content(data)
# Returns: {'_cleaned_results': [...], '_cleaned_chunks': [{'raw_chunk': 'raw', 'cleaned_chunk': 'Clean text', 'original_item': {}}]}
Source code in lazyllm/tools/data/operators/knowledge_cleaning/kbc_text_cleaner_batch.py
lazyllm.tools.data.operators.knowledge_cleaning.kbc_text_cleaner
KBCGenerateCleanedTextSingle
Bases: kbc
单条文本清洗生成算子。
该算子使用LLM对单条原始文本进行清洗,去除噪声、格式化内容。 适用于单条数据的实时清洗场景,当LLM调用失败时会使用原始文本作为回退。
Parameters:
-
llm–LLM服务实例,用于清洗文本。
-
lang(str, default:'en') –语言类型,'en' 表示英文,'zh' 表示中文,默认为 'en'。
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
dict–包含清洗响应的数据:
-
_cleaned_response–LLM的清洗响应
Examples:
from lazyllm.tools.data import kbc
# Assuming llm is an LLM service instance
cleaner = kbc.KBCGenerateCleanedTextSingle(llm=llm, lang='en')
data = {'raw_chunk': 'Noisy text with errors...'}
result = cleaner(data, input_key='raw_chunk')
# Returns: {'raw_chunk': '...', '_cleaned_response': 'Cleaned text result'}
Source code in lazyllm/tools/data/operators/knowledge_cleaning/kbc_text_cleaner.py
extract_cleaned_content_single(data, output_key='cleaned_chunk')
单条清洗内容提取函数。
该函数从单条LLM清洗响应中提取清洗后的文本内容,处理不同的响应格式。
支持从标签
Parameters:
-
data(dict) –包含清洗响应的数据。
-
output_key(str, default:'cleaned_chunk') –输出字段名,默认为 'cleaned_chunk'。
Returns:
-
dict(dict) –包含提取后清洗内容的数据,添加了 output_key 指定的字段。
Examples:
from lazyllm.tools.data.operators.knowledge_cleaning.kbc_text_cleaner import extract_cleaned_content_single
data = {'_cleaned_response': '<cleaned_start>Clean text<cleaned_end>'}
result = extract_cleaned_content_single(data, output_key='cleaned_chunk')
# Returns: {'cleaned_chunk': 'Clean text'}
Source code in lazyllm/tools/data/operators/knowledge_cleaning/kbc_text_cleaner.py
lazyllm.tools.data.operators.knowledge_cleaning.qa_extract
KBCExtractQAPairs
Bases: kbc
提取问答对的算子。
该算子从加载的问答数据中提取问答对,并将其转换为标准格式。 支持自定义指令、问题和答案的输出字段名。
Parameters:
-
qa_key(str, default:'QA_pairs') –问答数据字段名,默认为 'QA_pairs'。
-
instruction(str, default:'Please answer the following question based on the provided information.') –指令文本,默认为 'Please answer the following question based on the provided information.'。
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
–
List[dict]: 提取的问答对列表,每个包含 instruction、input 和 output 字段。
Examples:
from lazyllm.tools.data import kbc
extractor = kbc.KBCExtractQAPairs(
qa_key='QA_pairs',
instruction='Please answer based on the context.'
)
data = {'_qa_data': {'qa_pairs': [{'question': 'What is AI?', 'answer': 'Artificial Intelligence'}]}}
result = extractor(
data,
output_instruction_key='instruction',
output_question_key='input',
output_answer_key='output'
)
# Returns: [{'instruction': 'Please answer based on the context.', 'input': 'What is AI?', 'output': 'Artificial Intelligence'}]
Source code in lazyllm/tools/data/operators/knowledge_cleaning/qa_extract.py
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | |
KBCLoadQAData
Bases: kbc
加载问答数据的算子。
该算子从输入数据或分块文件中加载问答数据。首先检查输入数据中是否已包含问答数据, 如果没有则尝试从增强分块文件、清洗后分块文件或普通分块文件中加载。
Parameters:
-
qa_key(str, default:'QA_pairs') –问答数据字段名,默认为 'QA_pairs'。
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
dict–包含问答数据的数据:
-
_qa_data–加载的问答数据
-
_source_file–数据来源文件路径(如果从文件加载)
Examples:
from lazyllm.tools.data import kbc
loader = kbc.KBCLoadQAData(qa_key='QA_pairs')
# From existing data
data = {'QA_pairs': [{'question': 'Q1', 'answer': 'A1'}]}
result = loader(data)
# Returns: {'QA_pairs': [...], '_qa_data': [...]}
# From file
data = {'enhanced_chunk_path': '/path/to/enhanced.json'}
result = loader(data)
# Returns: {'enhanced_chunk_path': '...', '_qa_data': [...], '_source_file': '/path/to/enhanced.json'}
Source code in lazyllm/tools/data/operators/knowledge_cleaning/qa_extract.py
思维链生成算子
lazyllm.tools.data.operators.cot_ops
CoTGenerator
Bases: GenCot
使用大模型为问题生成带思维链(CoT)的推理过程,要求最终答案用 \boxed{{ANSWER}} 包裹。输出写入指定字段。
Parameters:
-
input_key(str, default:'query') –输入问题字段名,默认 'query'
-
output_key(str, default:'cot_answer') –输出 CoT 答案字段名,默认 'cot_answer'
-
model–可选,TrainableModule 或兼容接口;None 时使用默认 Qwen 模型
-
user_prompt(str | None, default:None) –可选,用户提示前缀;None 时使用默认
-
**kwargs–其它基类参数
Examples:
from lazyllm.tools.data import genCot
from lazyllm import OnlineChatModule
llm = OnlineChatModule()
op = genCot.CoTGenerator(input_key='query', output_key='cot_answer', model=llm)
data = {'query': 'What is 2+2?'}
res = op(data) # each item gets 'cot_answer' with CoT and \boxed{{4}}
print(res)
# {'query': 'What is 2+2?', 'cot_answer': '首先,我们需要理解加法的基本概念,即两个或多个数值的总和。在这个问题中,我们需要计算 2 和另一个 2 的和。
第一步,我们识别出第一个数值是 2。
第二步,我们识别出第二个数值也是 2。
第三步,我们将这两个数值相加:2 + 2。
第四步,我们进行计算:2 + 2 = 4。
因此,最终答案是 4,使用规定的格式包裹答案。
最终答案:oxed{4}'}
Source code in lazyllm/tools/data/operators/cot_ops.py
SelfConsistencyCoTGenerator
Bases: GenCot
对同一问题采样多次 CoT,从 \boxed{{}} 中提取答案并做多数投票,最终保留与多数答案一致的一条 CoT 输出。
Parameters:
-
input_key(str, default:'query') –输入问题字段名,默认 'query'
-
output_key(str, default:'cot_answer') –输出 CoT 答案字段名,默认 'cot_answer'
-
num_samples(int, default:5) –采样次数,默认 5
-
model–可选;None 时使用默认 Qwen 模型
-
user_prompt(str | None, default:None) –可选用户提示
-
**kwargs–其它基类参数
Examples:
from lazyllm.tools.data import genCot
from lazyllm import OnlineChatModule
llm = OnlineChatModule()
op = genCot.SelfConsistencyCoTGenerator(
input_key='query',
output_key='cot_answer',
num_samples=3,
model=llm
)
data = {'query': 'What is 3*4?'}
res = op(data)
print(res)
# {'query': 'What is 3*4?', 'candidates': ['12', '12', '12'], 'cot_answer': '首先,我们需要理解问题的核心,即计算3乘以4的结果。
1. 确定操作:这是一个乘法问题,我们需要将两个数相乘。
2. 识别数字:问题中给出的两个数字是3和4。
3. 执行乘法:将3乘以4,计算过程如下:
- 3 * 4 = 12
因此,3乘以4的结果是12。
最终答案为:oxed{12}'}
Source code in lazyllm/tools/data/operators/cot_ops.py
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | |
answer_verify(data, answer_key='reference', infer_key='llm_extracted', output_key='is_equal')
比较参考答案与模型提取答案是否(数学意义下)相等。使用 math_verify 解析并验证,结果写入指定字段。以 forward 单条方式注册。
Parameters:
-
data(dict) –单条数据字典
-
answer_key(str, default:'reference') –参考答案字段名,默认 'reference'
-
infer_key(str, default:'llm_extracted') –模型提取答案字段名,默认 'llm_extracted'
-
output_key(str, default:'is_equal') –是否相等写入的字段名,默认 'is_equal'
Examples:
from lazyllm.tools.data import genCot
data = {'reference': '1/2', 'llm_extracted': '0.5'}
op = genCot.answer_verify(answer_key='reference', infer_key='llm_extracted', output_key='is_equal')
print(op(data)) # Add key/value: 'is_equal': True
# {'reference': '1/2', 'llm_extracted': '0.5', 'is_equal': True}
Source code in lazyllm/tools/data/operators/cot_ops.py
多样性强化算子
lazyllm.tools.data.operators.enQa_ops
DiversityScorer
Bases: EnQA
对问题列表进行多样性打分,输出与输入顺序一致的列表,每项含 rewritten_query 与 diversity_score(0 相似/1 差异明显)。
Parameters:
-
input_key(str, default:'rewrite_querys') –问题列表字段名,默认 'rewrite_querys'
-
output_key(str, default:'diversity_querys') –带多样性分数的列表写入的字段名,默认 'diversity_querys'
-
model–可选;None 时使用默认 Qwen 模型
-
user_prompt(str | None, default:None) –可选用户提示
-
**kwargs–其它基类参数
Examples:
from lazyllm.tools.data import EnQA
from lazyllm import OnlineChatModule
llm = OnlineChatModule()
op = EnQA.DiversityScorer(input_key='rewrite_querys', output_key='diversity_querys', model=llm)
data = {'rewrite_querys': ['今天是个好天气', '今天天气不错', 'It is a nice day!']}
res = op(data)
print(data)
# {'rewrite_querys': ['今天是个好天气', '今天天气不错', 'It is a nice day!'], 'diversity_querys': [{'rewritten_query': '今天是个好天气', 'diversity_score': 1}, {'rewritten_query': '今天天气不错', 'diversity_score': 1}, {'rewritten_query': 'It is a nice day!', 'diversity_score': 1}]}
Source code in lazyllm/tools/data/operators/enQa_ops.py
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | |
QueryRewriter
Bases: EnQA
使用大模型将原问题重写为多个语义一致、表达不同的问法,输出列表写入指定字段。
Parameters:
-
input_key(str, default:'query') –输入问题字段名,默认 'query'
-
output_key(str, default:'rewrite_querys') –重写问题列表写入的字段名,默认 'rewrite_querys'
-
rewrite_num(int, default:3) –生成的重写数量,默认 3
-
model–可选;None 时使用默认 Qwen 模型
-
user_prompt(str | None, default:None) –可选用户提示
-
**kwargs–其它基类参数
Examples:
from lazyllm.tools.data import EnQA
from lazyllm import OnlineChatModule
llm = OnlineChatModule()
op = EnQA.QueryRewriter(input_key='query', output_key='rewrite_querys', rewrite_num=2, model=llm)
data = {'query': 'What is machine learning?'}
res = op(data) # data gets 'rewrite_querys': [str, str, ...]
print(res)
# [{'query': 'What is machine learning?', 'rewrite_querys': ['Could you explain what machine learning is?', 'What does the term machine learning refer to?']}]
Source code in lazyllm/tools/data/operators/enQa_ops.py
diversity_filter(data, input_key, min_score)
按多样性分数过滤:若 data 中指定字段(分数)小于 min_score 则丢弃该条(返回 []),否则保留(返回 None 表示保留原 data)。以 forward 单条方式注册。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str) –分数所在字段名
-
min_score–最小分数阈值
Examples:
from lazyllm.tools.data import EnQA
data = {'query': 'a and b', 'rewritten_query': 'b', 'diversity_score': 0}
op = EnQA.diversity_filter(input_key='diversity_score', min_score=1)
print(op(data)) # [None] (drop)
# []
Source code in lazyllm/tools/data/operators/enQa_ops.py
post_processor(data, input_key)
将指定字段(列表 of dict)展开为多行:每项 dict 与原始 data 合并为一行,原列表字段移除。返回多行时以 list 形式;无数据返回 None。以 forward 单条方式注册。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str) –要展开的列表字段名(列表中每项为 dict)
Examples:
from lazyllm.tools.data import EnQA
data = {'rewrite_querys': ['今天是个好天气', '今天天气不错', 'It is a nice day!'], 'diversity_querys': [{'rewritten_query': '今天是个好天气', 'diversity_score': 1}, {'rewritten_query': '今天天气不错', 'diversity_score': 1}, {'rewritten_query': 'It is a nice day!', 'diversity_score': 1}]}
op = EnQA.post_processor(input_key='diversity_querys')
print(op(data))
# [{'rewrite_querys': ['今天是个好天气', '今天天气不错', 'It is a nice day!'], 'rewritten_query': '今天是个好天气', 'diversity_score': 1}, {'rewrite_querys': ['今天是个好天气', '今天天气不错', 'It is a nice day!'], 'rewritten_query': '今天天气不错', 'diversity_score': 1}, {'rewrite_querys': ['今天是个好天气', '今天天气不错', 'It is a nice day!'], 'rewritten_query': 'It is a nice day!', 'diversity_score': 1}]
Source code in lazyllm/tools/data/operators/enQa_ops.py
数学问题算子
lazyllm.tools.data.operators.math_ops
DifficultyEvaluator
Bases: MathQA
使用大模型判断数学问题难度,输出 Easy | Medium | Hard(小学/初中高中/大学及以上)。若已有 difficulty 则跳过。
Parameters:
-
input_key(str, default:'question') –问题字段名,默认 'question'
-
output_key(str, default:'difficulty') –难度写入的字段名,默认 'difficulty'
-
model–可选;None 时使用默认 Qwen 模型
-
user_prompt(str | None, default:None) –可选用户提示
-
**kwargs–其它基类参数
Examples:
from lazyllm.tools.data.operators.math_ops import DifficultyEvaluator
from lazyllm.tools.data import MathQA
from lazyllm import OnlineChatModule
llm = OnlineChatModule()
op = MathQA.DifficultyEvaluator(input_key='question', output_key='difficulty', model=llm)
data = {'question': '1+1=?'}
res = op(data) # each item gets 'difficulty': 'Easy'|'Medium'|'Hard'
print(res)
# [{'question': '1+1=?', 'difficulty': 'Easy'}]
Source code in lazyllm/tools/data/operators/math_ops.py
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | |
DuplicateAnswerDetector
Bases: MathQA
检测答案是否存在重复/周期/长片段重复:周期重复、句子级重复、或合并问题+答案后的长子串重复则标记为 True。不调用模型。
Parameters:
-
question_key(str, default:'question') –问题字段名,默认 'question'
-
answer_key(str, default:'answer') –答案字段名,默认 'answer'
-
output_key(str, default:'duplicate') –是否重复写入的字段名,默认 'duplicate'
-
min_repeat_len(int, default:15) –判定长重复的最小子串长度,默认 15
-
repeat_threshold(int, default:2) –子串出现次数阈值,默认 2
-
periodic_min_repeat(int, default:3) –周期重复的最小周期重复次数,默认 3
-
**kwargs–其它基类参数
Examples:
from lazyllm.tools.data import MathQA
op = MathQA.DuplicateAnswerDetector(question_key='question', answer_key='answer', output_key='duplicate')
data = {'question': 'Q', 'answer': 'A' * 50}
res = op(data) # data['duplicate'] True
print(res)
# [{'question': 'Q', 'answer': 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', 'duplicate': True}]
Source code in lazyllm/tools/data/operators/math_ops.py
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 | |
MathAnswerGenerator
Bases: MathQA
使用大模型为数学问题生成推理与答案,要求最终结果用 \boxed{{ANSWER}} 包裹。若已有 answer 且未设置 regenerate 则跳过。
Parameters:
-
input_key(str, default:'question') –问题字段名,默认 'question'
-
output_key(str, default:'answer') –答案写入的字段名,默认 'answer'
-
regenerate_key(str, default:'regenerate') –是否强制重新生成的标志字段,默认 'regenerate'
-
model–可选;None 时使用默认 Qwen 模型
-
user_prompt(str | None, default:None) –可选用户提示
-
**kwargs–其它基类参数
Examples:
from lazyllm.tools.data.operators.math_ops import MathAnswerGenerator
from lazyllm.tools.data import MathQA
from lazyllm import OnlineChatModule
llm = OnlineChatModule()
op = MathQA.MathAnswerGenerator(input_key='question', output_key='answer', model=llm)
data = [{'question': 'Solve 10 * 10'}]
res = op(data)
print(res)
# [{'question': 'Solve 10 * 10', 'answer': '首先,我们需要计算 \(10 imes 10\)。这是一个简单的乘法运算,其中两个乘数都是10。
步骤1:写下乘数10和另一个乘数10。
步骤2:将两个10相乘。
计算过程如下:
\[ 10 imes 10 = 100 \]
因此,最终结果是 \(oxed{100}\)。', 'regenerate': False}]
Source code in lazyllm/tools/data/operators/math_ops.py
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | |
QualityEvaluator
Bases: MathQA
使用大模型对问题-答案对做质量打分:0 表示需重新生成,1 表示合格。若已有 output_key 则跳过。
Parameters:
-
question_key(str, default:'question') –问题字段名,默认 'question'
-
answer_key(str, default:'answer') –答案字段名,默认 'answer'
-
output_key(str, default:'score') –分数写入的字段名,默认 'score'
-
model–可选;None 时使用默认 Qwen 模型
-
user_prompt(str | None, default:None) –可选用户提示
-
**kwargs–其它基类参数
Examples:
from lazyllm.tools.data import MathQA
from lazyllm import OnlineChatModule
llm = OnlineChatModule()
op = MathQA.QualityEvaluator(question_key='question', answer_key='answer', output_key='score', model=llm)
data = {'question': '今天天气如何', 'answer': '大家好~'}
res = op(data) # 质量低的会被打 0 分
print(res)
# [{'question': '今天天气如何', 'answer': '大家好~', 'score': 0}]
Source code in lazyllm/tools/data/operators/math_ops.py
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 | |
QuestionFusionGenerator
Bases: MathQA
使用大模型将多条问题融合为一个新问题并生成推理与 \boxed{{}} 答案。需要 list_key 下至少 2 个问题。
Parameters:
-
input_key(str, default:'question') –融合后问题字段名,默认 'question'
-
output_key(str, default:'answer') –推理结果/答案写入的字段名,默认 'answer'
-
list_key(str, default:'question_list') –问题列表字段名,默认 'question_list'
-
model–可选;None 时使用默认 Qwen 模型
-
user_prompt(str | None, default:None) –可选用户提示
-
**kwargs–其它基类参数
Examples:
from lazyllm.tools.data import MathQA
from lazyllm import OnlineChatModule
llm = OnlineChatModule()
op = MathQA.QuestionFusionGenerator(input_key='new_question', list_key='question_list', output_key='new_answer', model=llm)
data = {'question_list': [
{'question': '1加1等于几?', 'answer': '1+1 = 2'},
{'question': '2的平方等于几?', 'answer': '2*2 = 4'}]}
res = op(data)
print(res)
# [{'question_list': [{'question': '1加1等于几?', 'answer': '1+1 = 2'}, {'question': '2的平方等于几?', 'answer': '2*2 = 4'}],
# 'new_question': '如果1加1的结果与2的平方相比较,哪个更大?',
# 'new_answer': '首先,我们解决第一个问题:1加1等于几?计算得到 1+1 = 2。然后,解决第二个问题:2的平方等于几?计算得到 2*2 = 4。最后,我们比较这两个结果,2和4。显然,4大于2。所以,2的平方更大。'}]
Source code in lazyllm/tools/data/operators/math_ops.py
551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 | |
ReasoningAnswerTokenLengthFilter
Bases: MathQA
按 token 或字符长度过滤答案:超过 max_answer_token_length 时清空该字段并返回修改后的 data;未超过时返回 None 保留原样;无内容时返回 []。支持 tokenizer 或字符计数。
Parameters:
-
input_key(str, default:'answer') –答案字段名,默认 'answer'
-
max_answer_token_length(int, default:300) –最大允许长度,默认 300
-
tokenize(bool, default:True) –是否按 token 计数;True 且未提供 tokenizer 时使用默认 Qwen tokenizer
-
tokenizer–可选
-
**kwargs–其它基类参数
Examples:
from lazyllm.tools.data import MathQA
op = MathQA.ReasoningAnswerTokenLengthFilter(input_key='answer', max_answer_token_length=100, tokenize=False)
data = [{'answer': 'short'}]
print(op(data)) # less than the max_length, keep the original input
# [{'answer': 'short'}]
Source code in lazyllm/tools/data/operators/math_ops.py
458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 | |
DifficultyEvaluatorBatch(data, input_key='difficulty')
批处理:统计输入列表中指定字段(难度)的分布,返回包含各难度计数的单元素列表 [{{难度: 数量}}]。以 forward_batch_input 注册。
Parameters:
-
data(list[dict]) –输入数据列表
-
input_key(str, default:'difficulty') –难度字段名,默认 'difficulty'
Examples:
from lazyllm.tools.data import MathQA
op = MathQA.DifficultyEvaluatorBatch(input_key='difficulty')
data = [{'difficulty': 'Easy'}, {'difficulty': 'Hard'}, {'difficulty': 'Easy'}]
print(op(data))
# [{'Easy': 2, 'Hard': 1}]
Source code in lazyllm/tools/data/operators/math_ops.py
math_answer_extractor(data, input_key='answer', output_key='math_answer')
从文本中提取 \boxed{{}} 内的数学答案,写入指定输出字段。以 forward 单条方式注册。
Parameters:
-
data(dict) –单条数据字典
-
input_key(str, default:'answer') –含答案文本的字段名,默认 'answer'
-
output_key(str, default:'math_answer') –提取结果写入的字段名,默认 'math_answer'
Examples:
from lazyllm.tools.data import MathQA
data = {'answer': 'So the answer is \boxed{{42}}.'}
op = MathQA.math_answer_extractor(input_key='answer', output_key='math_answer')
print(op(data)) # data['math_answer'] == '42'
# [{'answer': 'So the answer is \boxed{{42}}.', 'math_answer': '{42}'}]
Source code in lazyllm/tools/data/operators/math_ops.py
Pdf处理算子
lazyllm.tools.data.operators.pdf_ops
Pdf2Md
Bases: Pdf2Qa
将 PDF 转为 Markdown 文档列表。通过 MineruPDFReader(需配置 reader_url)调用后端服务,支持缓存。
Parameters:
-
input_key(str, default:'pdf_path') –PDF 路径字段名,默认 'pdf_path'
-
output_key(str, default:'docs') –转换得到的文档列表写入的字段名,默认 'docs'
-
reader_url–必填,Mineru 阅读器服务 URL
-
backend(str, default:'vlm-vllm-async-engine') –后端类型,默认 'vlm-vllm-async-engine'
-
upload_mode(bool, default:True) –是否上传模式,默认 True
-
use_cache(bool, default:False) –是否使用缓存,默认 False
-
**kwargs–其它基类参数
Examples:
from lazyllm.tools.data import Pdf2Qa
from lazyllm.tools.data.operators.pdf_ops import Pdf2Md
op = Pdf2Qa.Pdf2Md(input_key='pdf_path', output_key='docs', reader_url='http://...')
data = [{'pdf_path': '/path/to/file.pdf'}]
res = op(data) # each item gets 'docs' (list of doc content)
Source code in lazyllm/tools/data/operators/pdf_ops.py
Reranker 数据合成
lazyllm.tools.data.operators.reranker_synthesis
RerankerAdjustNegatives
Bases: reranker
调整重排序负样本数量的算子。
该算子调整负样本数量以匹配目标数量。如果负样本过多则截断,如果不足则通过随机采样进行填充。 使用基于查询内容的确定性随机种子以保证可复现性。
Parameters:
-
adjust_neg_count(int, default:7) –目标负样本数量,默认为 7。
-
seed(int, default:42) –随机种子,用于填充时的随机选择,默认为 42。
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
dict–调整后的数据,包含更新后的 _neg 字段。
Examples:
from lazyllm.tools.data import reranker
adjuster = reranker.RerankerAdjustNegatives(adjust_neg_count=5, seed=123)
# Too many negatives
data = {'_is_valid': True, '_query': 'ML', '_neg': ['n1', 'n2', 'n3', 'n4', 'n5', 'n6', 'n7', 'n8']}
result = adjuster(data)
# Returns: {'_is_valid': True, '_query': 'ML', '_neg': ['n1', 'n2', 'n3', 'n4', 'n5']}
# Too few negatives
data = {'_is_valid': True, '_query': 'ML', '_neg': ['n1', 'n2']}
result = adjuster(data)
# Returns: {'_is_valid': True, '_query': 'ML', '_neg': ['n1', 'n2', 'n1', 'n2', 'n1']}
Source code in lazyllm/tools/data/operators/reranker_synthesis/reranker_from_embedding_converter.py
RerankerBuildFormat
Bases: reranker
构建重排序格式的算子。
该算子将验证后的数据转换为标准的重排序训练格式。输出包含 query、pos 和 neg 字段的字典, 不包含提示或指令字段。
Parameters:
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
dict–重排序格式的数据,包含 query、pos 和 neg 字段。如果数据无效则返回空字典。
Examples:
from lazyllm.tools.data import reranker
builder = reranker.RerankerBuildFormat()
data = {'_is_valid': True, '_query': 'machine learning', '_pos': ['ML tutorial'], '_neg': ['cooking']}
result = builder(data)
# Returns: {'query': 'machine learning', 'pos': ['ML tutorial'], 'neg': ['cooking']}
Source code in lazyllm/tools/data/operators/reranker_synthesis/reranker_from_embedding_converter.py
RerankerFormatCrossEncoder
Bases: reranker
CrossEncoder格式转换算子。
该算子将验证后的数据转换为CrossEncoder训练格式。每个查询-文档对作为一个独立样本, 正样本标记为1,负样本标记为0。
Parameters:
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
–
List[dict]: 转换后的数据列表,每个包含 query、document 和 label 字段。
Examples:
from lazyllm.tools.data import reranker
formatter = reranker.RerankerFormatCrossEncoder()
data = {'_is_valid': True, '_query': 'machine learning', '_pos': ['ML tutorial'], '_neg': ['cooking']}
result = formatter(data)
# Returns: [{'query': 'machine learning', 'document': 'ML tutorial', 'label': 1}, {'query': 'machine learning', 'document': 'cooking', 'label': 0}]
Source code in lazyllm/tools/data/operators/reranker_synthesis/reranker_data_formatter.py
RerankerFormatFlagReranker
Bases: reranker
FlagReranker格式转换算子。
该算子将验证后的数据转换为FlagReranker训练格式。确保负样本数量符合训练组大小要求, 如果负样本不足会复制填充,如果过多会截断。
Parameters:
-
train_group_size(int, default:8) –训练组大小(包含1个正样本),默认为 8。
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
–
List[dict]: 转换后的数据列表,每个包含 query、pos 和 neg 字段。
Examples:
from lazyllm.tools.data import reranker
formatter = reranker.RerankerFormatFlagReranker(train_group_size=8)
data = {'_is_valid': True, '_query': 'machine learning', '_pos': ['ML tutorial'], '_neg': ['cooking', 'history']}
result = formatter(data)
# Returns: [{'query': 'machine learning', 'pos': ['ML tutorial'], 'neg': ['cooking', 'history', ...]}]
Source code in lazyllm/tools/data/operators/reranker_synthesis/reranker_data_formatter.py
RerankerFormatPairwise
Bases: reranker
Pairwise格式转换算子。
该算子将验证后的数据转换为Pairwise训练格式。创建正样本和负样本的成对组合, 用于训练排序模型区分相关和不相关文档。
Parameters:
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
–
List[dict]: 转换后的数据列表,每个包含 query、doc_pos 和 doc_neg 字段。
Examples:
from lazyllm.tools.data import reranker
formatter = reranker.RerankerFormatPairwise()
data = {'_is_valid': True, '_query': 'machine learning', '_pos': ['ML tutorial'], '_neg': ['cooking']}
result = formatter(data)
# Returns: [{'query': 'machine learning', 'doc_pos': 'ML tutorial', 'doc_neg': 'cooking'}]
Source code in lazyllm/tools/data/operators/reranker_synthesis/reranker_data_formatter.py
RerankerGenerateQueries
Bases: reranker
基于给定文本生成多条检索查询(query)的算子。
该算子使用 RerankerQueryGeneratorPrompt 构造提示词, 调用 LLM 生成不同难度等级的查询语句。 生成结果通过 JsonFormatter 解析后, 以 JSON 字符串形式保存在 '_query_response' 字段中。
若输入 passage 为空或生成失败,则返回空响应字段。
Parameters:
-
llm_serving–语言模型服务实例
-
lang(str, default:'zh') –查询生成语言,默认 'zh'
-
num_queries(int, default:3) –生成查询数量,默认 3
-
difficulty_levels(List[str], default:None) –查询难度等级列表,默认 ['easy', 'medium', 'hard']
-
**kwargs(dict, default:{}) –其他可选参数,传递给父类。
Examples:
op = RerankerGenerateQueries(
llm_serving=my_llm,
lang='en',
num_queries=5,
difficulty_levels=['easy', 'hard']
)
result = op({'passage': 'Large language models are widely used in NLP.'})
print(result['_query_response'])
Source code in lazyllm/tools/data/operators/reranker_synthesis/reranker_query_generator.py
RerankerInitBM25
Bases: reranker
初始化BM25索引的算子。
该算子基于语料库构建BM25索引,用于基于关键词的负样本挖掘。 支持中英文分词,中文使用jieba,英文使用Stemmer词干提取。
Parameters:
-
language(str, default:'zh') –语言类型,'zh'表示中文,'en'表示英文,默认为'zh'。
-
**kwargs(dict, default:{}) –其他可选参数,传递给父类。
Returns:
-
–
List[dict]: 输入数据列表,每个数据添加了BM25索引和分词器配置。
Examples:
from lazyllm.tools.data import reranker
init_bm25 = reranker.RerankerInitBM25(language='zh')
# 先构建语料库
data_with_corpus = reranker.build_reranker_corpus(inputs)
# 然后初始化BM25
result = init_bm25(data_with_corpus)
Source code in lazyllm/tools/data/operators/reranker_synthesis/reranker_hard_negative_miner.py
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | |
RerankerInitSemantic
Bases: reranker
初始化语义向量的算子。
该算子使用embedding服务计算语料库中所有文档的向量表示,并保存到文件中。 用于后续的语义相似度计算和负样本挖掘。
Parameters:
-
embedding_serving(Callable, default:None) –embedding服务调用函数。
-
embeddings_dir(str, default:None) –向量文件保存目录,默认为语料库所在目录。
-
**kwargs(dict, default:{}) –其他可选参数,传递给父类。
Returns:
-
–
List[dict]: 输入数据列表,每个数据添加了向量文件路径和语料库信息。
Examples:
from lazyllm.tools.data import reranker
# 假设 embedding_fn 是embedding服务
init_semantic = reranker.RerankerInitSemantic(embedding_serving=embedding_fn)
# 先构建语料库
data_with_corpus = reranker.build_reranker_corpus(inputs)
# 然后计算语义向量
result = init_semantic(data_with_corpus)
Source code in lazyllm/tools/data/operators/reranker_synthesis/reranker_hard_negative_miner.py
RerankerMineBM25Negatives
Bases: reranker
BM25负样本挖掘算子。
该算子基于BM25索引,检索与查询最相关但不属于正样本的文档作为负样本。 适用于挖掘与查询有词汇重叠但语义不同的困难负样本。
Parameters:
-
num_negatives(int, default:7) –需要挖掘的负样本数量,默认为 7。
-
**kwargs(dict, default:{}) –其他可选参数,传递给父类。
Returns:
-
dict–输入数据,添加了挖掘到的负样本列表。
Examples:
from lazyllm.tools.data import reranker
miner = reranker.RerankerMineBM25Negatives(num_negatives=5)
data = {'query': 'machine learning', 'pos': ['ML tutorial'], '_bm25': bm25_index, '_bm25_corpus': corpus}
result = miner(data)
# Returns: {'query': '...', 'pos': [...], 'neg': ['bm25_neg1', 'bm25_neg2', ...]}
Source code in lazyllm/tools/data/operators/reranker_synthesis/reranker_hard_negative_miner.py
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 | |
RerankerMineMixedNegatives
Bases: reranker
混合策略负样本挖掘算子。
该算子结合BM25和语义相似度两种方法挖掘负样本。按指定比例分别使用两种方法, 可以获得更多样化的困难负样本。
Parameters:
-
embedding_serving(Callable, default:None) –embedding服务调用函数。
-
num_negatives(int, default:7) –需要挖掘的负样本数量,默认为 7。
-
bm25_ratio(float, default:0.5) –BM25方法占比,剩余部分使用语义方法,默认为 0.5。
-
**kwargs(dict, default:{}) –其他可选参数,传递给父类。
Returns:
-
dict–输入数据,添加了混合策略挖掘的负样本列表。
Examples:
from lazyllm.tools.data import reranker
# 假设 embedding_fn 是embedding服务
miner = reranker.RerankerMineMixedNegatives(
embedding_serving=embedding_fn,
num_negatives=6,
bm25_ratio=0.5 # 3个BM25负样本 + 3个语义负样本
)
data = {
'query': 'machine learning',
'pos': ['ML tutorial'],
'_bm25': bm25_index,
'_bm25_corpus': corpus,
'_semantic_embeddings_path': emb_path,
'_semantic_corpus': corpus
}
result = miner(data)
# Returns: {'query': '...', 'pos': [...], 'neg': [...]} 包含3个BM25负样本和3个语义负样本
Source code in lazyllm/tools/data/operators/reranker_synthesis/reranker_hard_negative_miner.py
496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 | |
RerankerMineRandomNegatives
Bases: reranker
随机负样本挖掘算子。
该算子从语料库中随机选择不属于正样本的文档作为负样本。 适用于基线对比或需要随机负样本的场景。
Parameters:
-
num_negatives(int, default:7) –需要挖掘的负样本数量,默认为 7。
-
seed(int, default:42) –随机种子,用于可复现的随机选择,默认为 42。
-
**kwargs(dict, default:{}) –其他可选参数,传递给父类。
Returns:
-
dict–输入数据,添加了挖掘到的负样本列表。
Examples:
from lazyllm.tools.data import reranker
miner = reranker.RerankerMineRandomNegatives(num_negatives=5, seed=123)
data = {'query': 'machine learning', 'pos': ['ML tutorial'], '_corpus': corpus_path}
result = miner(data)
# Returns: {'query': '...', 'pos': [...], '_corpus': '...', 'neg': ['random_neg1', 'random_neg2', ...]}
Source code in lazyllm/tools/data/operators/reranker_synthesis/reranker_hard_negative_miner.py
RerankerMineSemanticNegatives
Bases: reranker
语义相似度负样本挖掘算子。
该算子基于语义向量相似度,找出与查询最相似但不属于正样本的文档作为负样本。 适用于挖掘语义相近但实际不相关的困难负样本,通常比BM25方法效果更好。
Parameters:
-
num_negatives(int, default:7) –需要挖掘的负样本数量,默认为 7。
-
embedding_serving(Callable, default:None) –embedding服务调用函数,用于计算查询向量。
-
**kwargs(dict, default:{}) –其他可选参数,传递给父类。
Returns:
-
dict–输入数据,添加了基于语义相似度挖掘的负样本列表。
Examples:
from lazyllm.tools.data import reranker
# 假设 embedding_fn 是embedding服务
miner = reranker.RerankerMineSemanticNegatives(num_negatives=5, embedding_serving=embedding_fn)
data = {'query': 'machine learning', 'pos': ['ML tutorial'], '_semantic_embeddings_path': emb_path, '_semantic_corpus': corpus}
result = miner(data)
# Returns: {'query': '...', 'pos': [...], 'neg': ['semantic_neg1', 'semantic_neg2', ...]}
Source code in lazyllm/tools/data/operators/reranker_synthesis/reranker_hard_negative_miner.py
RerankerParseQueries
Bases: reranker
解析 LLM 生成的查询结果,并展开为多条训练样本数据。
该算子读取 '_query_response' 字段中的 JSON 内容, 解析得到查询列表(支持 list 或 {'queries': [...]} 结构)。 每条查询会生成一条新的数据记录,包含:
- query: 查询文本
- difficulty: 难度等级(默认 'medium')
- pos: 正样本文本列表(原始 passage)
同时会清理中间字段 '_query_response' 等。
Parameters:
-
input_key(str, default:'passage') –原始文本字段名,默认 'passage'
-
output_query_key(str, default:'query') –输出查询字段名,默认 'query'
-
**kwargs(dict, default:{}) –其他可选参数,传递给父类。
Examples:
op = RerankerParseQueries(input_key='passage', output_query_key='query')
data = {
'passage': 'Large language models are widely used in NLP.',
'_query_response': '[{"query": "What are LLMs used for?", "difficulty": "easy"}]'
}
rows = op(data)
for row in rows:
print(row['query'], row['difficulty'], row['pos'])
Source code in lazyllm/tools/data/operators/reranker_synthesis/reranker_query_generator.py
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | |
RerankerTrainTestSplitter
Bases: reranker
重排序训练集/测试集分割算子。
该算子将数据集随机分割为训练集和测试集,支持指定分割比例和随机种子。 可以保存训练集和测试集到指定文件,测试集会转换格式以兼容评估需求。
Parameters:
-
test_size(float, default:0.1) –测试集比例,默认为 0.1(即10%)。
-
seed(int, default:42) –随机种子,用于可复现的分割,默认为 42。
-
train_output_file(str, default:None) –训练集输出文件路径,默认为 None。
-
test_output_file(str, default:None) –测试集输出文件路径,默认为 None。
-
**kwargs(dict, default:{}) –其它可选的参数,传递给父类。
Returns:
-
–
List[dict]: 分割后的数据列表,每个样本包含 split 字段标记所属集合('train' 或 'test')。
Examples:
from lazyllm.tools.data import reranker
splitter = reranker.RerankerTrainTestSplitter(
test_size=0.2,
seed=123,
train_output_file='train.jsonl',
test_output_file='test.jsonl'
)
data = [
{'query': 'q1', 'pos': ['p1'], 'neg': ['n1']},
{'query': 'q2', 'pos': ['p2'], 'neg': ['n2']}
]
result = splitter(data)
# Returns: [{'query': 'q1', 'pos': ['p1'], 'neg': ['n1'], 'split': 'train'}, {'query': 'q2', 'pos': ['p2'], 'neg': ['n2'], 'split': 'test'}]
Source code in lazyllm/tools/data/operators/reranker_synthesis/reranker_data_formatter.py
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 | |
LLM JSON 算子
lazyllm.tools.data.operators.llm_base_ops
LLMDataJson
基于 LLM 的 JSON 数据处理算子基类。提供结构化输出的基础逻辑,包括自动配置 JsonFormatter、重试机制以及预处理/验证/后处理生命周期。
构造函数参数:
- model: LazyLLM 模型实例。
- prompt: 可选,用于引导 LLM 的 Prompt(ChatPrompter 或字符串)。
- max_retries: 最大重试次数,默认 3。
- **kwargs: 其它传递给基类的并发或持久化参数。
Source code in lazyllm/tools/data/operators/llm_base_ops.py
lazyllm.tools.data.operators.llm_json_ops
FieldExtractor
Bases: LLMDataJson, LLMJsonBase
字段提取器。利用 LLM 根据提供的字段列表从输入文本中提取特定信息。
Parameters:
-
model–LazyLLM 模型实例。
-
prompt–可选,自定义提取 Prompt。
-
input_keys–字段列表,默认为 ['persona', 'text', 'fields']。
-
output_key–结果存储在数据字典中的键名,默认 'structured_data'。
Examples:
from lazyllm import OnlineChatModule
from lazyllm.tools.data.operators.llm_json_ops import FieldExtractor
model = OnlineChatModule(source='sensenova')
op = FieldExtractor(model=model)
inputs = [{
'text': '张三,28岁,目前在上海',
'fields': ['name', 'age', 'location']
}]
res = op(inputs)
print(res[0]['structured_data']) # {'name': '张三', 'age': '28', 'location': '上海'}
Source code in lazyllm/tools/data/operators/llm_json_ops.py
SchemaExtractor
Bases: LLMDataJson, LLMJsonBase
架构提取器。利用 LLM 根据指定的 Schema(字典或 Pydantic 模型)从文本中提取结构化数据。
Parameters:
-
model–LazyLLM 模型实例。
-
prompt–可选,自定义提取 Prompt。
-
input_key–输入文本的键名,默认 'text'。
-
output_key–结果存储在数据字典中的键名,默认 'structured_data'。
Examples:
from lazyllm import OnlineChatModule
from lazyllm.tools.data.operators.llm_json_ops import SchemaExtractor
model = OnlineChatModule(source='sensenova')
op = SchemaExtractor(model=model)
inputs = [{'text': 'Math score is 95', 'schema': {'subject': 'str', 'score': 'int'}}]
res = op(inputs)
print(res[0]['structured_data']) # {'subject': 'Math', 'score': 95}
Source code in lazyllm/tools/data/operators/llm_json_ops.py
数据处理 Pipeline
演示Pipeline
lazyllm.tools.data.pipelines.demo_pipelines
build_demo_pipeline(input_key='text')
构建演示用数据处理流水线(Pipeline),包含若干示例算子并展示如何在 pipeline 上组合使用这些算子。
Parameters:
-
input_key(str, default:'text') –要处理的文本字段名,默认 'text'
Returns:
一个可调用的 pipeline 对象,调用时会按顺序执行其中注册的算子。
Examples:
from lazyllm.tools.data.pipelines.demo_pipelines import build_demo_pipeline
ppl = build_demo_pipeline(input_key='text')
data = [{'text': 'lazyLLM'}]
res = ppl(data)
print(res) # demonstrates how operators are combined and applied