agentflow 合成数据大致流程
运行过程
运行 quick_synthesize.py 的详细过程
基于对仓库代码的分析,quick_synthesize.py 是一个简单的脚本,用于启动RAG(Retrieval-Augmented Generation)数据合成管道。以下是假设运行该脚本时的详细执行流程(同步模拟,不实际运行代码)。整个过程涉及加载配置、初始化沙盒环境、处理种子数据、采样轨迹、选择和合成QA对,最终输出结果。
1. 脚本初始化
- 设置环境变量:
OPENAI_API_KEY设置为指定的API密钥(用于调用OpenAI模型)。OPENAI_API_BASE设置为 "https://openrouter.ai/api/v1"(API基础URL,可能用于路由到不同的模型提供商)。
- 调用
synthesize函数:- 传入配置文件路径:web_rag_config.json(注意:此路径可能需要根据实际环境调整;在仓库中,对应文件位于 web_rag_config.json)。
- 该函数位于 api.py,负责加载配置、种子数据,并启动合成管道。
2. 加载配置
- 使用
load_config函数读取 web_rag_config.json 文件,创建SynthesisConfig对象。 - 配置关键参数包括:
- 模型名称:
openai/gpt-oss-120b(用于生成轨迹和QA)。 - 轨迹采样参数:最大深度50、最小深度3、分支因子2、深度阈值2、相似度阈值0.7。
- 可用工具:
["rag:search", "web:search", "web:visit"](用于检索和网页访问)。 - 沙盒服务器URL:
http://127.0.0.1:18890(假设沙盒服务已运行)。 - 种子文件:seeds.jsonl(在仓库中为 seeds.jsonl,包含如"Python programming language"等种子)。
- 输出目录:
/home/a1/sdb/tzw/Synthesis/results(默认或环境变量指定)。
- 模型名称:
- 如果环境变量
LLM_MODEL_NAME或SEEDS_FILE设置,会覆盖配置中的相应值。
3. 加载种子数据
- 使用
load_seeds函数读取种子文件(JSONL格式,每行一个JSON对象)。 - 示例种子:
{"content": "Python programming language", "kwargs": {}}等。 - 如果配置中指定
number_of_seed,则限制种子数量。
4. 初始化合成管道
- 创建
SynthesisPipeline对象:- 验证配置(检查必填字段,如模型名称、工具列表)。
- 创建输出目录(如果不存在)。
- 初始化输出文件:
synthesized_qa.jsonl(QA对)和trajectories.jsonl(轨迹数据)。
- 打印输出文件路径和基本信息(总种子数、模型名称等)。
5. 启动异步运行(run_async 方法)
- 创建并启动沙盒Worker:
- 初始化
SandboxWorker,连接到沙盒服务器(http://127.0.0.1:18890)。 - 为每个资源类型(基于配置中的
resource_types,如RAG、Web等)创建或重新初始化会话。每个种子使用独立的会话(如rag_src_0001_xxx),确保隔离。
- 初始化
- 处理每个种子(循环执行):
- 步骤1:采样轨迹树(
TrajectorySampler):- 从种子内容开始,使用模型生成多分支轨迹(树状结构)。
- 每个轨迹节点代表一个推理步骤,使用可用工具(如RAG搜索、网页搜索/访问)扩展。
- 参数控制:最大深度50、最小深度3、分支因子2(每次扩展2个分支)、相似度阈值0.7(避免重复路径)。
- 输出:轨迹树(节点列表),根节点ID。
- 步骤2:选择最佳轨迹(
TrajectorySelector):- 从轨迹树中选择最多
max_selected_traj(默认2)个高质量轨迹。 - 基于相似度、深度和质量评分过滤。
- 从轨迹树中选择最多
- 步骤3:合成QA对(
QASynthesizer):- 对每个选定轨迹,使用模型生成问题-答案对。
- 提示包括:多跳推理(>=3跳)、简洁问题、基于轨迹证据的具体答案、结合RAG和Web证据。
- 示例QA:问题如"What year was the company founded that developed the framework used in the project?",答案如"2004"。
- 步骤4:保存结果:
- 将QA对追加到
synthesized_qa.jsonl(JSONL格式,每行一个QA字典)。 - 将轨迹数据追加到
trajectories.jsonl。 - 打印进度:每个种子的QA对数量。
- 将QA对追加到
- 步骤1:采样轨迹树(
- 异常处理:如果某个种子失败,记录错误并继续下一个。
- 停止Worker:清理沙盒会话。
6. 完成与输出
- 打印总结:处理种子总数、输出目录。
- 输出文件位于指定目录,包含生成的QA对和轨迹数据,可用于训练或评估RAG模型。
注意事项
- 依赖:需要沙盒服务器运行(端口18890)、有效的API密钥、网络访问(用于Web工具)。
- 潜在问题:路径硬编码(如种子文件和输出目录),可能需要调整;异步操作依赖
asyncio。 - 运行时间:取决于种子数量、轨迹深度和模型响应时间,可能较长(分钟到小时)。
- 如果实际运行失败,可检查沙盒日志、API连接或配置错误。
采样参数
轨迹采样参数主要定义在 config.py 的 SynthesisConfig 类中
1. 采样深度和广度控制参数
这些参数决定轨迹树的结构和探索范围。
-
max_depth(默认值: 5)
轨迹树的最大深度。表示从根节点开始,最多允许探索多少层。
作用:防止无限递归或过度探索。当节点的深度(从根节点算起)达到或超过此值时,停止进一步探索子节点。在_explore_node方法中,如果node.depth >= self.config.max_depth,则直接返回,不再生成子节点。 -
branching_factor(默认值: 2)
分支因子,表示每个节点最多可以生成多少个子节点。
作用:控制树的广度,决定探索的多样性。较高的值会产生更多分支,增加探索空间,但也增加计算成本。 -
depth_threshold(默认值: 3)
深度阈值,用于动态调整分支因子。
作用:在早期深度(节点深度 < depth_threshold)时,使用branching_factor生成多个子节点;在后期深度(节点深度 >= depth_threshold)时,每个节点只生成1个子节点。这有助于在浅层进行广泛探索,在深层进行聚焦探索,避免指数级增长。
2. 轨迹选择和过滤参数
这些参数用于从生成的轨迹树中筛选出高质量的轨迹。
-
min_depth(默认值: 2)
最小深度要求。
作用:在选择轨迹时,只有叶子节点的深度大于等于此值的轨迹才被视为有效候选。深度过浅的轨迹(如只有1-2步)可能缺乏足够的信息或多样性,因此被过滤掉。这确保选择的轨迹有一定的探索深度。 -
max_selected_traj(默认值: 3)
最大选择的轨迹数量。
作用:从候选轨迹中最多选择多少条轨迹返回。选择过程基于评分和相似度过滤,确保返回的轨迹数量不超过此限制。 -
path_similarity_threshold(默认值: 0.7)
路径相似度阈值,用于避免选择过于相似的轨迹。
作用:使用Jaccard相似度(节点集合的交集/并集)来衡量两条轨迹的相似性。如果两条轨迹的相似度超过此阈值,则跳过选择,以提高轨迹的多样性。这防止返回重复或冗余的探索路径。
3. 其他相关参数(间接影响采样)
虽然不是直接的“轨迹采样参数”,但这些参数也会影响采样过程:
-
model_name(默认值: "gpt-4.1-2025-04-14")
用于生成下一步动作的LLM模型名称。影响动作生成的质量和多样性。 -
available_tools(默认值: [])
可用的工具列表。采样时,LLM会基于这些工具生成动作,工具的丰富度直接影响轨迹的多样性。 -
sampling_tips(默认值: "")
采样提示,用于指导LLM在探索时的行为(如鼓励多样性或特定策略)。
参数使用逻辑示例
在 sampler.py 的 _explore_node 方法中:
- 首先检查
max_depth,决定是否继续探索。 - 根据
depth_threshold和branching_factor决定生成多少子节点(并发执行以提高效率)。 - 在 selector.py 的
select_trajectories方法中:- 使用
min_depth过滤候选叶子节点。 - 使用
max_selected_traj限制最终选择数量。 - 使用
path_similarity_threshold通过Jaccard相似度避免相似轨迹。
- 使用
建议调参
- 如果想更深入探索:增加
max_depth。 - 如果想更广泛探索:增加
branching_factor或降低depth_threshold。 - 如果轨迹质量不高:降低
min_depth或调整path_similarity_threshold以允许更多候选。 - 这些参数在
SynthesisConfig中有验证逻辑(如max_depth >= 1),确保配置合理。
如果您需要查看具体代码实现或有其他问题,请随时告诉我!
种子文件
读取 [](file:///workspace/agentflow_sandbox/README.md#1-1),行 1 到 50
读取 [](file:///workspace/agentflow_sandbox/examples/README.md#1-1),行 1 到 50
读取 [](file:///workspace/agentflow_sandbox/examples/README.md#51-51),行 51 到 100
读取 [](file:///workspace/agentflow_sandbox/examples/seeds.jsonl)
读取 [](file:///workspace/agentflow_sandbox/examples/seeds-vm.jsonl)
读取 [](file:///workspace/agentflow_sandbox/synthesis/core/synthesizer.py#1-1),行 1 到 50
读取 [](file:///workspace/agentflow_sandbox/synthesis/pipeline.py#1-1),行 1 到 50
读取 [](file:///workspace/agentflow_sandbox/synthesis/core/sampler.py#1-1),行 1 到 50
读取 [](file:///workspace/agentflow_sandbox/synthesis/api.py#1-1),行 1 到 50
读取 [](file:///workspace/agentflow_sandbox/quick_synthesize.py)
搜索文本 def synthesize (**/def synthesize),无结果
读取 [](file:///workspace/agentflow_sandbox/synthesis/api.py#51-51),行 51 到 92
种子文件(Seeds Files)的具体作用
根据对仓库代码和文档的深入分析,种子文件(seeds.jsonl 和 seeds-vm.jsonl)在 AgentFlow 项目中扮演着数据合成管道的起点和驱动器的角色。以下是详细介绍:
1. 基本概念与格式
- 文件位置:位于
examples/目录下 - 格式:JSON Lines(
.jsonl)格式,每行一个 JSON 对象 - 结构:每个种子对象包含两个核心字段:
content:种子内容的文本描述(通常是任务、查询或主题)kwargs:额外的参数配置(目前多为空字典{})
2. 在合成管道中的作用
种子文件是 AgentFlow 数据合成框架 的初始输入源,具体作用如下:
a) 作为轨迹生成的起点
- 每个种子代表一个初始任务或查询,用于启动代理的探索过程
- 代理从种子内容开始,通过 LLM + 工具的交互生成轨迹树(Trajectory Tree)
- 轨迹包含:代理状态、工具调用、观察结果、多步推理、环境反馈等
b) 驱动多样化数据生成
- seeds.jsonl:包含通用主题种子,如 "Python programming language"、"Machine learning" 等,用于生成 RAG(检索增强生成)相关的轨迹和 Q&A 数据
- seeds-vm.jsonl:包含 VM GUI 操作任务,如 "Explore the VM desktop GUI: open file manager, create a folder...",用于生成 GUI/工具使用代理的轨迹
c) 支持大规模合成
- 框架可以处理数百万条种子,生成对应的训练数据
- 每个种子生成唯一的
source_id(基于内容哈希),确保数据可追溯
3. 在合成流程中的具体流程
- 加载种子:通过
load_seeds()函数从.jsonl文件读取 - 生成 Source ID:为每个种子创建唯一标识符
- 启动采样:
TrajectorySampler使用种子作为初始查询,开始 LLM 驱动的工具探索 - 轨迹生成:代理在沙盒环境中执行多步操作,记录完整轨迹
- Q&A 合成:
QASynthesizer从轨迹中提取高质量的问答对,用于训练数据
4. 不同类型种子的应用场景
- RAG 种子(seeds.jsonl):用于生成知识检索、问答等场景的训练数据
- VM 种子(seeds-vm.jsonl):用于生成 GUI 操作、工具使用等复杂代理行为的训练数据
5. 配置与使用
- 在配置文件(如
web_rag_config.json)中指定seeds_file路径 - 可以通过环境变量
SEEDS_FILE或 API 参数覆盖 - 示例调用:
synthesize(config_path="config.json")会自动加载配置中指定的种子文件
种子文件本质上是将现实世界的任务和查询抽象化为结构化输入,驱动整个合成管道生成多样化的代理训练数据,从而实现跨异构环境的统一数据合成。
QA
Q:可是种子文件的内容不会太宽泛了吗?比如说Python既可以介绍其历史也可以介绍其用法啊
A:这其实是可以的,比如说我们想要去大规模生成Agent的训练数据,就像LLM的预训练一样,我们就可以这么做
会话
为每个资源类型创建或重新初始化会话的解释
在 quick_synthesize.py 的运行过程中,“为每个资源类型创建或重新初始化会话”是指以下操作:
什么是“会话”?
- 会话(Session):在沙盒架构中,会话是沙盒服务器(
http://127.0.0.1:18890)为特定资源类型创建的独立实例或上下文环境。- 例如:
rag资源类型:对应一个RAG(检索增强生成)工具的会话,可能包括索引数据、检索配置等。web资源类型:对应网页搜索或访问工具的会话,可能涉及浏览器实例或API客户端。- 其他类型如
vm(虚拟机)、code_executor等,每个都有自己的状态和配置。
- 会话通过沙盒API管理,具有唯一名称(如
rag_src_0001_xxx),并维护工具的执行状态、缓存或历史记录。
- 例如:
具体操作过程
- 检查现有会话:脚本首先列出沙盒中的现有会话,检查是否已有该资源类型的会话。
- 创建或重新初始化:
- 如果该资源类型没有现有会话,则调用
worker.sandbox.create_session(resource_type, res_config)创建新会话。res_config包含初始化参数(如自定义名称、工具配置)。 - 如果已有会话,则调用
worker.sandbox.reinitialize(resource_type, res_config)重新初始化,确保会话重置为干净状态。
- 如果该资源类型没有现有会话,则调用
- 每个种子独立:为每个种子(seed)生成唯一源ID(如
src_0001_xxx),并为每个资源类型附加此ID作为会话名称(如rag_src_0001_xxx)。这意味着不同种子使用不同的会话实例。
为什么要这么做?
- 隔离性(Isolation):每个种子处理时,使用独立的会话实例,避免不同种子间的状态干扰。例如,一个种子的RAG检索结果不会影响另一个种子的缓存或上下文。
- 状态重置:重新初始化确保会话从干净状态开始,防止累积的副作用(如工具缓存过期、会话变量污染)。这对于多轮推理(轨迹采样)至关重要,因为轨迹可能涉及多次工具调用。
- 资源管理:沙盒架构允许多个并发会话,但脚本通过按种子隔离,确保高效利用资源,同时避免冲突。配置中的
resource_init_configs允许自定义每个资源类型的初始化参数(如RAG的索引路径、Web的超时设置)。 - 错误恢复:如果会话失败,可以重新初始化而不影响整个管道。代码中还处理了会话列表失败的情况,会强制重新创建。
这种设计基于沙盒的模块化架构,确保合成过程稳定、可重复,且适合大规模数据生成。如果沙盒服务器未运行或配置错误,此步骤会失败,导致管道停止。
注意事项
所有种子共用一个沙盒,这个沙盒为每种资源分别创建了一个会话,但是不同种子有自己的独特的会话实例
采样轨迹树
采样轨迹树的具体流程如下(基于仓库中的sampler.py代码逻辑):
-
初始化采样器:
- 创建
TrajectorySampler实例,传入SandboxWorker和SynthesisConfig配置。 - 初始化OpenAI客户端、节点存储字典(
self.nodes)、根节点ID(self.root_id)、可用工具列表(self.available_tools)。 - 加载工具模式(通过
get_tool_schemas从本地工具模块获取)。
- 创建
-
开始采样轨迹树(
sample_trajectory_tree方法):- 重置树结构、清空已用动作签名集合。
- 创建根节点(
TrajectoryNode),观察内容为种子数据,意图为“Initialize exploration”,深度为0,无父节点。 - 调用
_explore_node开始异步探索。
-
节点探索(
_explore_node方法,递归广度优先):- 检查当前节点深度是否超过配置的最大深度(
max_depth),若超过则停止探索。 - 根据当前深度决定分支因子:若深度小于
depth_threshold,则使用branching_factor(默认多个子节点);否则为1(单分支)。 - 并发创建并探索所有子节点(使用
asyncio.gather)。
- 检查当前节点深度是否超过配置的最大深度(
-
创建并探索子节点(
_create_and_explore_child方法):- 生成下一个动作(
_generate_next_action):构建上下文、已用动作列表和探索提示,调用LLM生成动作(XML格式),解析响应,检查动作签名是否重复(避免相同种子下的重复动作)。 - 执行动作(
_execute_action):通过SandboxWorker异步执行工具调用,格式化结果。 - 创建子节点:记录观察结果、意图、动作、父节点ID、深度+1。
- 打印节点信息(包括节点索引、ID、深度、工具名、参数、输出预览)。
- 递归调用
_explore_node继续探索该子节点。
- 生成下一个动作(
-
上下文构建(
_build_context方法):- 从当前节点回溯到根节点,构建路径字符串:包括起始点、每一步的意图、动作、参数和观察结果预览。
-
探索提示构建(
_build_exploration_prompt方法):- 生成工具描述(名称、参数、类型、是否必需)。
- 包含起始点信息、探索目标(收集信息用于后续合成)、已探索动作列表(避免重复)、探索策略提示、当前历史轨迹。
-
动作去重:
- 使用
_action_signature生成动作签名(工具名+规范化参数JSON),在种子级别避免重复。 _format_used_actions_for_prompt格式化已用动作列表,限制长度以控制提示大小。
- 使用
整个流程通过异步并发实现高效探索,形成一棵以根节点为起点的树状结构,每个节点代表一个状态(观察、意图、动作),边代表动作执行。探索停止于最大深度或无新动作生成。
QA
Q:为什么不允许有相同的动作?Agent多次调用同一个工具很合理吧?
在agentflow_sandbox仓库的采样轨迹树实现中(具体见sampler.py),确实有动作去重机制,但它并非完全禁止Agent多次调用同一个工具。让我详细解释一下这个设计的逻辑和原因:
-
去重机制的具体规则
- 去重是基于动作签名(action signature)实现的:
tool_name + canonicalized JSON(parameters)。 - 这意味着:
- 允许在不同上下文中调用同一个工具,只要参数不同(例如,搜索不同关键词、查询不同URL等)。
- 禁止的是完全相同的工具调用(工具名 + 参数完全一致),即使在同一个种子(seed)的不同分支或节点中。
- 去重范围是每个种子级别(per-seed),即每个独立的种子数据有自己的去重集合。不同种子之间可以重复动作。
- 去重是基于动作签名(action signature)实现的:
-
为什么设计成这样?(不允许完全相同的动作)
这个设计是为了提高探索的多样性和效率,避免无意义的重复,符合合成(synthesis)场景的需求。理由如下:-
避免信息冗余和循环:
- 在轨迹采样中,目标是系统性地探索多样化的信息,为后续的轨迹选择和QA对合成提供丰富素材。如果允许重复相同动作(例如,反复调用同一个搜索工具查询相同关键词),会导致轨迹树中出现大量冗余节点,不会带来新观察(observation)或洞见。
- 这可能造成“循环探索”:Agent陷入重复调用,浪费计算资源和深度限制,而无法深入探索新路径。
-
鼓励多样化探索:
- 提示(prompt)中明确强调:“You MUST propose a NEW action that is NOT in this list or similar to them to increase the diversity of the exploration. Repeating any of them is strictly forbidden.”
- 在RAG(Retrieval-Augmented Generation)或工具合成场景中,采样是为了生成多样化的轨迹,然后从中选择高质量的路径合成QA对。重复动作不会增加多样性,反而可能降低合成质量。
-
符合Agent的“智能探索”理念:
- Agent应该像人类一样“学习并前进”:基于已有的观察,提出新颖的下一步,而不是机械重复。
- 多次调用同一个工具确实合理(例如,在不同分支中调用相同工具但参数不同),但完全相同的调用通常是低效的,因为它不会改变状态或提供新信息。
-
-
如果需要多次调用相同工具怎么办?
- 如果业务逻辑确实需要重复相同动作(例如,参数相同但在不同上下文中),可以调整配置或代码:
- 修改
_action_signature逻辑,移除去重或放松条件(例如,只基于工具名去重,而不考虑参数)。 - 或者在
SynthesisConfig中添加选项,允许重复。
- 修改
- 但在当前实现中,这是为了优化合成流程而设计的权衡:优先多样性而非绝对灵活性。
- 如果业务逻辑确实需要重复相同动作(例如,参数相同但在不同上下文中),可以调整配置或代码:
Q:采样数最后决定停止的条件的是什么?
A:

在日志里面经常看到Duplicate action detected, skipping就是检测到了重复动作,此时这一条轨迹就会停止采样
选择最佳轨迹
根据我对仓库的仔细阅读和理解,AgentFlow 是一个统一的代理数据合成框架,用于生成高质量的训练和评估数据。该项目涉及从种子数据(如问题或查询)出发,通过代理工具交互生成轨迹(trajectories),然后选择最佳轨迹,并最终合成Q&A对。
“选择最佳轨迹”是指在合成管道中,从采样生成的轨迹树(一个探索树结构)中选择高质量的轨迹。具体流程位于 selector.py 中的 TrajectorySelector 类,其 select_trajectories 方法实现了这一逻辑。以下是选择最佳轨迹的具体流程:
1. 输入准备
- 输入参数:
nodes: 轨迹树中的所有节点(字典形式,键为节点ID,值为TrajectoryNode对象)。root_id: 根节点ID(轨迹树的起点,通常是初始种子查询)。seed_data: 种子数据(原始查询或内容)。source_id: 源ID(用于标识轨迹来源)。max_selected_traj: 最大选择轨迹数量(默认为配置中的max_selected_traj)。
- 配置依赖:
min_depth: 最小轨迹深度(叶子节点深度必须 >= 此值)。path_similarity_threshold: 路径相似度阈值(默认0.7,用于避免选择高度相似的轨迹)。available_tools: 可用工具列表(用于计算多样性分数)。
2. 步骤1: 找到所有叶子节点
- 遍历所有节点,筛选出没有子节点(
children_ids为空)的节点,这些是轨迹的终点。 - 输出叶子节点数量。
3. 步骤2: 过滤有效叶子
- 从叶子节点中筛选出深度 >=
min_depth的节点。 - 如果没有有效叶子,返回空列表(表示无符合要求的轨迹)。
4. 步骤3: 构建候选路径
- 对于每个有效叶子,从叶子节点回溯到根节点,构建路径(列表形式,从根到叶子的节点序列)。
- 使用
_build_path_to_root方法:从叶子开始,沿着parent_id向上遍历,直到根节点,然后反转路径。 - 输出候选路径数量。
5. 步骤4: 评分和选择
- 评分每个路径(使用
_score_path方法):- 深度分数(40% 权重):
min(len(path) / 5.0, 1.0) * 40,鼓励更长的轨迹(但上限为5)。 - 信息分数(30% 权重):基于平均观察长度(observation)的相对标准化值,鼓励信息丰富的轨迹。
- 多样性分数(30% 权重):
len(tool_names) / max(total_tools, 1) * 30,鼓励使用更多不同工具的轨迹。 - 总分 = 深度分数 + 信息分数 + 多样性分数(满分100)。
- 深度分数(40% 权重):
- 排序:按总分降序排序候选路径。
- 选择前k个,但考虑相似度避免冗余:
- 对于每个候选路径,计算其节点ID集合与已选路径的Jaccard相似度(交集/并集)。
- 如果相似度 >
path_similarity_threshold(默认0.7),则跳过该路径(避免选择高度相似的轨迹)。 - 否则,选择该路径,记录其节点ID集合。
- 输出选定轨迹数量和详情(ID、深度、分数)。
6. 输出
- 返回选定的
Trajectory对象列表,每个包含轨迹ID、节点序列、种子数据、源ID和总深度。 - 如果无轨迹被选择,返回空列表。
关键逻辑和优化
- 相似度控制:通过Jaccard相似度防止选择过于相似的路径,提高多样性。
- 标准化:信息分数使用全局最小/最大观察长度进行相对标准化,确保公平比较。
- 可配置性:阈值和权重可在
SynthesisConfig中调整。 - 集成上下文:此步骤位于合成管道的步骤2(见 pipeline.py),紧跟轨迹采样(步骤1),并在QA合成(步骤3)之前。
如果您需要更详细的代码示例、配置调整或运行测试,请提供更多具体要求!
合成QA对
基于我对仓库的分析,合成QA对的具体流程如下(已排除采样轨迹树和选择最佳轨迹的步骤):
-
初始化合成器:使用配置创建QASynthesizer实例,初始化OpenAI客户端。
-
格式化轨迹描述:将给定的轨迹(Trajectory)转换为可读的文本格式,包括每个步骤的意图、动作、参数和观察结果。
-
构建合成提示:
- 包含种子数据(seed data)和描述。
- 附加完整的探索轨迹描述。
- 添加数据合成指导(synthesis tips)和QA示例(如果配置中提供)。
- 指定问题要求:目标答案为具体事实,要求多跳推理(至少3跳),问题简洁、自然,不泄露答案。
- 指定答案要求:极度简洁(≤1句),无赘述,直接 grounded 在轨迹观察中。
- 要求返回JSON格式:包含question、answer和reasoning_steps(每个步骤有hop、fact、evidence、output)。
-
调用LLM生成:使用chat_completion调用模型,设置温度为0.7(失败时递增),要求JSON对象格式响应。
-
解析和验证响应:
- 解析JSON响应,提取question、answer和reasoning_steps。
- 验证:响应格式正确、问题和答案非空、答案未泄露到问题中、问题不冗长(≤85词、≤500字符)、推理步骤至少3步。
-
重试机制:如果验证失败,最多重试3次,每次记录失败原因并调整温度。失败后返回None。
-
创建QA对象:验证通过后,生成SynthesizedQA对象,包含问题、答案、轨迹ID、来源ID、推理步骤和元数据(如种子数据、合成日期)。
-
输出结果:返回合成的QA对,用于后续保存。
QA
Q:最后生成的qa对的推理步骤的步骤数由什么决定?
A:只规定了最少为3步,如果少于3步会要求LLM重新生成;具体的步骤由LLM决定
Q:最后得到的qa对的fact,evidence和output分别是什么意思?
A:

Q:最后得到的训练数据是如何去训练大模型的?
A:
当然这里说是这么说,实际上question就是指令,最后期望Agent输出answer

浙公网安备 33010602011771号