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对数量。
  • 异常处理:如果某个种子失败,记录错误并继续下一个。
  • 停止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. 在合成流程中的具体流程

  1. 加载种子:通过 load_seeds() 函数从 .jsonl 文件读取
  2. 生成 Source ID:为每个种子创建唯一标识符
  3. 启动采样:TrajectorySampler 使用种子作为初始查询,开始 LLM 驱动的工具探索
  4. 轨迹生成:代理在沙盒环境中执行多步操作,记录完整轨迹
  5. 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代码逻辑):

  1. 初始化采样器:

    • 创建TrajectorySampler实例,传入SandboxWorker和SynthesisConfig配置。
    • 初始化OpenAI客户端、节点存储字典(self.nodes)、根节点ID(self.root_id)、可用工具列表(self.available_tools)。
    • 加载工具模式(通过get_tool_schemas从本地工具模块获取)。
  2. 开始采样轨迹树(sample_trajectory_tree方法):

    • 重置树结构、清空已用动作签名集合。
    • 创建根节点(TrajectoryNode),观察内容为种子数据,意图为“Initialize exploration”,深度为0,无父节点。
    • 调用_explore_node开始异步探索。
  3. 节点探索(_explore_node方法,递归广度优先):

    • 检查当前节点深度是否超过配置的最大深度(max_depth),若超过则停止探索。
    • 根据当前深度决定分支因子:若深度小于depth_threshold,则使用branching_factor(默认多个子节点);否则为1(单分支)。
    • 并发创建并探索所有子节点(使用asyncio.gather)。
  4. 创建并探索子节点(_create_and_explore_child方法):

    • 生成下一个动作(_generate_next_action):构建上下文、已用动作列表和探索提示,调用LLM生成动作(XML格式),解析响应,检查动作签名是否重复(避免相同种子下的重复动作)。
    • 执行动作(_execute_action):通过SandboxWorker异步执行工具调用,格式化结果。
    • 创建子节点:记录观察结果、意图、动作、父节点ID、深度+1。
    • 打印节点信息(包括节点索引、ID、深度、工具名、参数、输出预览)。
    • 递归调用_explore_node继续探索该子节点。
  5. 上下文构建(_build_context方法):

    • 从当前节点回溯到根节点,构建路径字符串:包括起始点、每一步的意图、动作、参数和观察结果预览。
  6. 探索提示构建(_build_exploration_prompt方法):

    • 生成工具描述(名称、参数、类型、是否必需)。
    • 包含起始点信息、探索目标(收集信息用于后续合成)、已探索动作列表(避免重复)、探索策略提示、当前历史轨迹。
  7. 动作去重:

    • 使用_action_signature生成动作签名(工具名+规范化参数JSON),在种子级别避免重复。
    • _format_used_actions_for_prompt格式化已用动作列表,限制长度以控制提示大小。

整个流程通过异步并发实现高效探索,形成一棵以根节点为起点的树状结构,每个节点代表一个状态(观察、意图、动作),边代表动作执行。探索停止于最大深度或无新动作生成。

QA

Q:为什么不允许有相同的动作?Agent多次调用同一个工具很合理吧?
在agentflow_sandbox仓库的采样轨迹树实现中(具体见sampler.py),确实有动作去重机制,但它并非完全禁止Agent多次调用同一个工具。让我详细解释一下这个设计的逻辑和原因:

  1. 去重机制的具体规则

    • 去重是基于动作签名(action signature)实现的:tool_name + canonicalized JSON(parameters)。
    • 这意味着:
      • 允许在不同上下文中调用同一个工具,只要参数不同(例如,搜索不同关键词、查询不同URL等)。
      • 禁止的是完全相同的工具调用(工具名 + 参数完全一致),即使在同一个种子(seed)的不同分支或节点中。
    • 去重范围是每个种子级别(per-seed),即每个独立的种子数据有自己的去重集合。不同种子之间可以重复动作。
  2. 为什么设计成这样?(不允许完全相同的动作)
    这个设计是为了提高探索的多样性和效率,避免无意义的重复,符合合成(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应该像人类一样“学习并前进”:基于已有的观察,提出新颖的下一步,而不是机械重复。
      • 多次调用同一个工具确实合理(例如,在不同分支中调用相同工具但参数不同),但完全相同的调用通常是低效的,因为它不会改变状态或提供新信息。
  3. 如果需要多次调用相同工具怎么办?

    • 如果业务逻辑确实需要重复相同动作(例如,参数相同但在不同上下文中),可以调整配置或代码:
      • 修改_action_signature逻辑,移除去重或放松条件(例如,只基于工具名去重,而不考虑参数)。
      • 或者在SynthesisConfig中添加选项,允许重复。
    • 但在当前实现中,这是为了优化合成流程而设计的权衡:优先多样性而非绝对灵活性。

Q:采样数最后决定停止的条件的是什么?
A:
image
在日志里面经常看到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)。
  • 排序:按总分降序排序候选路径。
  • 选择前k个,但考虑相似度避免冗余:
    • 对于每个候选路径,计算其节点ID集合与已选路径的Jaccard相似度(交集/并集)。
    • 如果相似度 > path_similarity_threshold(默认0.7),则跳过该路径(避免选择高度相似的轨迹)。
    • 否则,选择该路径,记录其节点ID集合。
  • 输出选定轨迹数量和详情(ID、深度、分数)。

6. 输出

  • 返回选定的 Trajectory 对象列表,每个包含轨迹ID、节点序列、种子数据、源ID和总深度。
  • 如果无轨迹被选择,返回空列表。

关键逻辑和优化

  • 相似度控制:通过Jaccard相似度防止选择过于相似的路径,提高多样性。
  • 标准化:信息分数使用全局最小/最大观察长度进行相对标准化,确保公平比较。
  • 可配置性:阈值和权重可在 SynthesisConfig 中调整。
  • 集成上下文:此步骤位于合成管道的步骤2(见 pipeline.py),紧跟轨迹采样(步骤1),并在QA合成(步骤3)之前。

如果您需要更详细的代码示例、配置调整或运行测试,请提供更多具体要求!

合成QA对

基于我对仓库的分析,合成QA对的具体流程如下(已排除采样轨迹树和选择最佳轨迹的步骤):

  1. 初始化合成器:使用配置创建QASynthesizer实例,初始化OpenAI客户端。

  2. 格式化轨迹描述:将给定的轨迹(Trajectory)转换为可读的文本格式,包括每个步骤的意图、动作、参数和观察结果。

  3. 构建合成提示:

    • 包含种子数据(seed data)和描述。
    • 附加完整的探索轨迹描述。
    • 添加数据合成指导(synthesis tips)和QA示例(如果配置中提供)。
    • 指定问题要求:目标答案为具体事实,要求多跳推理(至少3跳),问题简洁、自然,不泄露答案。
    • 指定答案要求:极度简洁(≤1句),无赘述,直接 grounded 在轨迹观察中。
    • 要求返回JSON格式:包含question、answer和reasoning_steps(每个步骤有hop、fact、evidence、output)。
  4. 调用LLM生成:使用chat_completion调用模型,设置温度为0.7(失败时递增),要求JSON对象格式响应。

  5. 解析和验证响应:

    • 解析JSON响应,提取question、answer和reasoning_steps。
    • 验证:响应格式正确、问题和答案非空、答案未泄露到问题中、问题不冗长(≤85词、≤500字符)、推理步骤至少3步。
  6. 重试机制:如果验证失败,最多重试3次,每次记录失败原因并调整温度。失败后返回None。

  7. 创建QA对象:验证通过后,生成SynthesizedQA对象,包含问题、答案、轨迹ID、来源ID、推理步骤和元数据(如种子数据、合成日期)。

  8. 输出结果:返回合成的QA对,用于后续保存。

QA

Q:最后生成的qa对的推理步骤的步骤数由什么决定?
A:只规定了最少为3步,如果少于3步会要求LLM重新生成;具体的步骤由LLM决定

Q:最后得到的qa对的fact,evidence和output分别是什么意思?
A:
image

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

posted @ 2026-03-08 23:37  最爱丁珰  阅读(76)  评论(0)    收藏  举报