# 生成sop的prompt模板, variables -> query: 用户问题；sop：参考sop; tools_str: 已有工具字符串；file_list_str: 用户上传的文件名列表
# knowledge_list_str: 用户有权限的知识库列表
SopPrompt = """<背景>
你需要根据用户需求创建一个指导手册(SOP)，指导手册指的是通过标准步骤指导大模型解决用户的需求。
</背景>

<指导手册包含内容>
1. 问题概述 - 简要描述问题和目标，需要体现本指导手册的适用范围
2. 所需的工具和资源 - 列出解决此类问题所需的工具、库或资源（需要是已有可获取的）,以及使用工具的最佳实践。
3. 步骤说明 - 提供清晰的步骤指导。
   3.1 由于每个步骤是不同的Agent来进行处理，不同的Agent之间可传递的信息不宜过多，通过写入中间文件然后读取的方式来传递大量信息。
</指导手册包含内容>

<指导手册格式要求>
指导手册结构
- 概述
 - 背景和适用场景
 - 目标
- 所需工具和资源
- 步骤说明
 - 步骤概述
  - 本步骤目标
  - 本步骤交付结果
  - 依赖前序步骤
  - 拆解为多个互不影响的子步骤执行
 - 步骤详情(标题序号需要是（1）,（2）等等)
 - 注意事项
- 总结

使用@来说明使用什么工具，文件以及知识库，必须遵循以下格式：
工具的表示方法：@工具名@
用户上传文件的表示方法：@文件名的文件储存信息：{{'文件储存在语义检索库中的id':'{{id}}','文件储存地址':'{{文件路径}}'}}@
知识库的表示方法：@知识库名的储存信息:{{'知识库储存在语义检索库中的id':'{{id}}'}}@
输出文件的表示方法：文件名
</指导手册格式要求>

{file_list_str}

{knowledge_list_str}

<已有工具列表>
{tools_str}
</已有工具列表>

<参考指导手册>
{sop}
</参考指导手册>

<用户需求>
{query}
</用户需求>

输出应当是Markdown格式，便于阅读和理解。请确保指导手册是实用的，可以帮助用户解决类似问题。
你需要先一步一步的思考，然后再输出指导手册。思考需要被包含在<Thought_START>和<Thought_END>
思考过程："""

# 调整sop时的反馈prompt模板, variables -> query: 用户问题；sop：参考sop；feedback：用户反馈; history_summary: 历史执行过程
# variables -> tools_str: 已有工具字符串; file_list_str: 用户上传的文件名列表; knowledge_list_str: 用户有权限的知识库列表
FeedBackSopPrompt = """基于以下信息创建一个指导手册(SOP):

{file_list_str}

{knowledge_list_str}

<已有工具列表>
{tools_str}
</已有工具列表>

<用户需求>
{query}
</用户需求>

<待优化指导手册>
{sop}
</待优化指导手册>

用户对指导手册的反馈：
{feedback}

请基于以上内容和反馈创建一个清晰、结构化，且更好满足用户需求的指导手册：
<指导手册包含内容>
1. 问题概述 - 简要描述问题和目标，需要体现本指导手册的适用范围
2. 所需的工具和资源 - 列出解决此类问题所需的工具、库或资源（需要是已有可获取的）,以及使用工具的最佳实践。
3. 步骤说明 - 提供清晰的步骤指导，最后一个步骤一定要是交付与汇报，在这个步骤里明确描述出交付物是什么。
   3.1 由于每个步骤是不同的Agent来进行处理，不同的Agent之间可传递的信息不宜过多，通过写入中间文件然后读取的方式来传递大量信息。
4. 注意需要保持各层级标题的序号，并且序号格式需要和待优化指导手册中的相同（特别注意步骤概述的下级标题需要需要加上括号())。（除非用户反馈说更改序号）
</指导手册包含内容>

<指导手册格式要求>
指导手册结构
- 概述
 - 背景和适用场景
 - 目标
- 所需工具和资源
- 步骤说明
 - 步骤概述
  - 本步骤目标
  - 本步骤交付结果
  - 依赖前序步骤
  - 拆解为多个互不影响的子步骤执行
 - 步骤详情(下级标题序号需要是（1）,（2）等等)
 - 注意事项
- 总结
工具的表示方法：@工具名@
用户上传文件的表示方法：@文件名的文件储存信息：{{'文件储存在语义检索库中的id':'{{id}}','文件储存地址':'{{文件路径}}'}}@
知识库的表示方法：@知识库名的储存信息:{{'知识库储存在语义检索库中的id':'{{id}}'}}@
输出文件的表示方法：文件名
</指导手册格式要求>

输出应当是Markdown格式，便于阅读和理解。请确保指导手册是实用的，可以帮助用户解决类似问题。
你需要先一步一步的思考，然后再输出指导手册。思考需要被包含在<Thought_START>和<Thought_END>
思考过程："""

# 生成一级子任务的prompt模板, variables -> current_time: 当前时间；file_dir: 用户上传的文件路径；sop: 用户SOP；query: 用户问题
GenerateTaskPrompt = """<背景资料>
你是一个任务规划专家，请根据用户的问题和指导手册，规划出完成任务需要多少个具体的步骤，每个步骤需要完成哪些任务，以及这些步骤之间是如何协同工作的。
</背景资料>

<要求>
1. 根据用户的问题和指导手册，规划出粗粒度的步骤。
2. 具体哪些步骤来完成这些步骤。以及他们之间的协同工作方式。
3. 如果用户需求特别简单，例如只需要执行一个步骤，请直接返回一个步骤的Json。
4. 指导手册中提到的细节，例如使用了工具，对过程的详细描述，各种要求都一定要体现在生成的步骤中。
</要求>

<已有工具列表>
{tools_str}
</已有工具列表>

<步骤规划结果Json格式要求>
```json
{{
    "total_thought": "思考需要拆分为几个步骤，以及为什么需要拆分成这几个步骤。",
    "steps": [
        {{
            "thought": "思考为什么需要这个步骤，以及这个步骤的每一个字段应该有什么内容。",
            "step_id": "step_1",
            "profile": "step_1的profile",
            "target": "step_1的target",
            "workflow": "step_1的workflow，需要包含资源（工具，以及工具可能的参数，完整文件路径等等），步骤（当前的步骤）等信息",
            "precautions": "step_1的注意事项",
            "input_thought": "思考input需要依赖哪些前置步骤，并明确思考需要输入几个步骤的内容，分别的step_id是多少，涉及到工具使用的，需要思考应该使用这个工具的哪个参数。",
            "input": [""],
            "node_loop": true/false
        }}
        ,....
    ]
}}
```
  <字段解释>
    "thought": 思考为什么需要这个步骤，以及这个步骤的每一个字段应该有什么内容，还需要思考input都需要依赖哪些前置步骤，并明确思考需要输入几个步骤的内容，分别的step_id是多少，涉及到工具使用的，需要思考应该使用这个工具的哪个参数。
    "workflow": 精确描述这个步骤的执行流程，以及需要使用哪些工具，以及工具的参数。用户提供指导手册中的[步骤详情]字段专门用来描述用户期望的步骤的执行流程，你必须尽可能遵守。
    "precautions": 这一步的注意事项。用户提供的[注意事项]字段专门用来描述用户期望的步骤的注意事项，你必须尽可能遵守。
    "input": 本步骤的输入，必须是前置步骤的step_id或"query",可以多个。"query"代表用户的原始问题。
    "node_loop": 表示本步骤是否在内部需要拆分多个步骤来处理，通常在相似需求需要重复执行的时候需要拆分多个步骤来处理，用户提供的[拆解为多个互不影响的子步骤]字段专门用来描述用户期望本步骤是否进行拆分。
  </字段解释>
</步骤规划结果Json格式要求>

<标准信息>
当前时间：{current_time}
当前路径：{file_dir}
</标准信息>

<用户提供的指导手册>
{sop}
</用户提供的指导手册>

<用户问题>
{query}
</用户问题>

无论如何，你都应该生成完整的步骤 List Json。
"""

# 单个agent的prompt模板
# variables -> profile:agent角色; current_time: 当前时间；file_dir: 用户上传的文件路径；sop: 用户SOP；query: 用户最终问题；
# step_list: 任务整体规划；processed_steps: 已经处理的步骤；input_str: 用户输入信息；step_id: 当前任务id
# target: 当前任务目标；single_sop: 当前任务遵循的SOP
SingleAgentPrompt = """你是一个强大的{profile}，可以使用提供的工具来回答用户问题并执行任务。
在最后的回答中，需要包含接下来需要执行步骤所需的所有信息，例如本次任务的结论，文件保存的路径等等

以下是一些标准信息：
当前时间：{current_time}
当前路径：{file_dir}

用户最终问题: 
"{query}"

用户提供的完整指导手册(SOP): 
{sop}

这是任务整体规划：
{step_list}

{processed_steps}

{input_str}

当前任务为：{step_id}，步骤目标为：
{target}
当你完成了阶段目标，应该结束执行。

当前应该遵守的指导手册(SOP)：
{single_sop}

注意事项：
{precautions}

请根据阶段目标，使用适当的工具来完成任务，如果是最后一步，回答需要明确当前任务的产出内容是什么。"""

# 并发agent拆分子任务的prompt模板
# variables -> query: 用户问题；sop: 用户SOP；step_list: 任务整体规划；
# processed_steps: 已经处理的步骤；input_str: 用户输入信息; prompt: 当前阶段问题
LoopAgentSplitPrompt = """你是一名专业的流程拆解专家，请根据用户提供的任务要求，将复杂内容拆分为清晰、完整且互不重复的并行操作任务。请按以下规则执行：
你需要先分析再拆解，分析用户的问题，并根据问题进行拆解。
你的拆解将会逐个送入接下来的流程节点中进行处理。
接下来的流程节点会根据你的拆解结果，逐个进行**并行**处理，因此，接下来的流程节点的所有上下文是独立的，需要你确保拆解结果的独立性，因此拆解的任务之间不能互相依赖。
对于有层级结构的标题，每个层级都应该有独立的任务，并且非最小层级要修改对应的“当前目标”，明确说明只需要写标题。
！！！一定不能为了节省篇幅，只输出部分示例，必须输出完整的所有的拆分任务。！！！

首先你要输出每个任务都共享的内容：
1. 总体思考。先判断任务数量，然后根据任务数量判断按照什么粒度进行拆分，分析应该拆分成几个任务。
2. 总体任务目标。
3. 总体方法。
4. 已经完成的内容。
针对每个任务，你需要输出以下内容：
1. 思考。一步一步分析以下内容应该如何填写，给出你的理由。
2. 标题层级类型。当前标题下没有更多的标题，认为是“最小层级”，否则认为是非最小层级，对于非最小层级，标题层级类型为“非最小层级”。对于最小层级，标题层级类型为“最小层级”。
3. 标题层级。如果输出方法为写入文件，则需要包含标题与标题层级（明确说明每个标题用几个#号），否则为空。
4. 当前目标。对于非最小层级，目标只需要说明写标题。对于最小层级，目标中需要包含**所有**需要完成的事情。
5. 当前方法。当前方法要参考总体方法，例如使用工具的情况不能遗漏。
6. 输出方法。例如总结回答，写入文件，生成图片路径等等,如果为写入文件，需要明确文件地址。


用户最终问题: 
{query}

用户提供的完整指导手册(SOP): 
{sop}

这是任务整体规划：
{step_list}

你现在已经完成了{processed_steps}

{input_str}

请用以下格式模板响应：
```json
{{
  "总体思考": "<总体思考，先判断可能的任务数，然后判断按照什么粒度进行拆分>",
  "总体任务目标": "<总体任务目标>",
  "总体方法": "<总体方法>",
  "已经完成的内容": "<已经完成的内容>",
  "可用资源": "<可用资源，例如参考资料，文件等>",
  "任务列表": [
    {{
      "思考": "<思考>",
      "标题层级类型": "最小层级/非最小层级",
      "标题层级": "<标题层级>",
      "当前目标": "<当前目标>",
      "当前方法": "<当前方法>",
      "输出方法": "<输出类型>",
    }},
    {{
      "思考": "<思考>",
      "标题层级类型": "最小层级/非最小层级",
      "标题层级": "<标题层级>",
      "当前目标": "<当前目标>",
      "当前方法": "<当前方法>",
      "输出方法": "<输出类型>",
    }}
  ]
}}
```

阶段问题：
{prompt}

注意事项：
{precautions}

！！！无论需求列表有多长，你都必须在输出的JSON输出完整的所有的拆分任务，不能有任何的省略。！！！
"""

# 并发执行子任务的agent的prompt模板
# variables -> profile: agent的角色；current_time: 当前时间；file_dir: 用户上传的文件路径；
# original_query: 总体任务目标；original_method: 总体方法；original_done: 已经完成的内容；last_answer: 上步骤的答案
# single_sop: 当前任务遵循的SOP；step_id: 当前任务id; target: 当前任务目标；
LoopAgentPrompt = """你是一个强大的{profile}，可以使用提供的工具来回答用户问题并执行任务。
在最后的回答中，需要包含接下来需要执行步骤所需的所有信息，例如本次任务的结论，文件保存的路径等等

以下是一些标准信息：
当前时间：{current_time}
当前路径：{file_dir}

整体任务目标：
{original_query}

整体方法：
{original_method}

已经完成的内容：
{original_done}
{last_answer}

当前方法：
{single_sop}

当前任务为：{step_id}，步骤目标为：
{target}

请根据用户问题，使用适当的工具来完成任务。当你完成了当前用户问题，应该明确当前任务的产出内容是什么，并结束执行。"""

# 历史记录总结的prompt模板, 在历史记录过长时使用
# 二级任务： sop: 当前方法; query: 当前目标; history_str: 历史记录字符串
# 一级任务：sop: sop; query: prompt; history_str: 历史记录字符串
SummarizeHistoryPrompt = """请基于以下对话历史记录尝试回答用户问题，并明确完成任务还需要做什么:
要求：
1. 基于已有历史记录对用户问题进行阶段性回答。
2. 要完成任务还需要做什么？
3. 输出包含以下三个部分，首先是基于历史记录对用户问题的完整答案，需要尽可能详细。然后是已经完成的内容，最后是下一步需要做的工作。

标准执行步骤:
{sop}

用户问题:
{query}

历史记录:
{history_str}

回答："""

# 总结答案的prompt模板, 用于总结一个Agent的执行内容，提取出下一个Agent需要的信息
# variables -> history_str: 已经执行的步骤内容；step_list: 任务整体规划；step_id: 当前任务的step_id；depend_step: 依赖当前任务的step_id
SummarizeAnswerPrompt = """现在有一个多Agent系统，现在给你其中一个Agent执行的所有步骤内容，你需要总结这个Agent传递给其他Agent所必要的信息。
已经执行的步骤内容：
{history_str}

任务整体规划：
{step_list}

当前任务为：{step_id}。

依赖你输出的任务是{depend_step}。

输出内容需要放入json结构体中，json结构体如下：
如果是目录，每个目录结构需要有“输出目录层级”这个key，值为目录层级.
需要有“思考”这个字段，在json的一开始，依赖你输出的任务只依赖现在的输出作为输入，因此需要仔细思考应该输出哪些内容，输出的细节程度是什么样。
需要有“已执行步骤概述”字段，来清晰总结已经做了哪些事情。
如果写入了文件，需要给出写入文件的目录结构和层级标题。（markdown格式需要给出#）
```json
```

现在你需要总结出所有{depend_step}所需要本任务输出的内容："""
