自我发现工作流程¶
本笔记本展示如何实现SELF-DISCOVER。
对于给定的任务,它分为两个阶段:
阶段一:
a. 选择:选取推理模块的子集。
b. 适配:将选中的推理模块适配到任务中。
c. 实现:为任务提供推理结构。
阶段2:使用为任务生成的推理结构来生成答案。
该实现灵感来源于代码库
In [ ]:
Copied!
%pip install -U llama-index
%pip install -U llama-index
In [ ]:
Copied!
import os
os.environ["OPENAI_API_KEY"] = "<Your OpenAI API Key>"
import os
os.environ["OPENAI_API_KEY"] = ""
由于工作流默认采用异步优先设计,这一切在笔记本环境中都能顺畅运行。若您在自己的代码中执行,当不存在已激活的异步事件循环时,您需要使用asyncio.run()
来启动一个异步事件循环。
async def main():
<async code>
if __name__ == "__main__":
import asyncio
asyncio.run(main())
设置¶
设置推理模块和提示模板。
In [ ]:
Copied!
from llama_index.core.prompts import PromptTemplate
_REASONING_MODULES = [
"1. How could I devise an experiment to help solve that problem?",
"2. Make a list of ideas for solving this problem, and apply them one by one to the problem to see if any progress can be made.",
"3. How could I measure progress on this problem?",
"4. How can I simplify the problem so that it is easier to solve?",
"5. What are the key assumptions underlying this problem?",
"6. What are the potential risks and drawbacks of each solution?",
"7. What are the alternative perspectives or viewpoints on this problem?",
"8. What are the long-term implications of this problem and its solutions?",
"9. How can I break down this problem into smaller, more manageable parts?",
"10. Critical Thinking: This style involves analyzing the problem from different perspectives, questioning assumptions, and evaluating the evidence or information available. It focuses on logical reasoning, evidence-based decision-making, and identifying potential biases or flaws in thinking.",
"11. Try creative thinking, generate innovative and out-of-the-box ideas to solve the problem. Explore unconventional solutions, thinking beyond traditional boundaries, and encouraging imagination and originality.",
"12. Seek input and collaboration from others to solve the problem. Emphasize teamwork, open communication, and leveraging the diverse perspectives and expertise of a group to come up with effective solutions.",
"13. Use systems thinking: Consider the problem as part of a larger system and understanding the interconnectedness of various elements. Focuses on identifying the underlying causes, feedback loops, and interdependencies that influence the problem, and developing holistic solutions that address the system as a whole.",
"14. Use Risk Analysis: Evaluate potential risks, uncertainties, and tradeoffs associated with different solutions or approaches to a problem. Emphasize assessing the potential consequences and likelihood of success or failure, and making informed decisions based on a balanced analysis of risks and benefits.",
"15. Use Reflective Thinking: Step back from the problem, take the time for introspection and self-reflection. Examine personal biases, assumptions, and mental models that may influence problem-solving, and being open to learning from past experiences to improve future approaches.",
"16. What is the core issue or problem that needs to be addressed?",
"17. What are the underlying causes or factors contributing to the problem?",
"18. Are there any potential solutions or strategies that have been tried before? If yes, what were the outcomes and lessons learned?",
"19. What are the potential obstacles or challenges that might arise in solving this problem?",
"20. Are there any relevant data or information that can provide insights into the problem? If yes, what data sources are available, and how can they be analyzed?",
"21. Are there any stakeholders or individuals who are directly affected by the problem? What are their perspectives and needs?",
"22. What resources (financial, human, technological, etc.) are needed to tackle the problem effectively?",
"23. How can progress or success in solving the problem be measured or evaluated?",
"24. What indicators or metrics can be used?",
"25. Is the problem a technical or practical one that requires a specific expertise or skill set? Or is it more of a conceptual or theoretical problem?",
"26. Does the problem involve a physical constraint, such as limited resources, infrastructure, or space?",
"27. Is the problem related to human behavior, such as a social, cultural, or psychological issue?",
"28. Does the problem involve decision-making or planning, where choices need to be made under uncertainty or with competing objectives?",
"29. Is the problem an analytical one that requires data analysis, modeling, or optimization techniques?",
"30. Is the problem a design challenge that requires creative solutions and innovation?",
"31. Does the problem require addressing systemic or structural issues rather than just individual instances?",
"32. Is the problem time-sensitive or urgent, requiring immediate attention and action?",
"33. What kinds of solution typically are produced for this kind of problem specification?",
"34. Given the problem specification and the current best solution, have a guess about other possible solutions."
"35. Let’s imagine the current best solution is totally wrong, what other ways are there to think about the problem specification?"
"36. What is the best way to modify this current best solution, given what you know about these kinds of problem specification?"
"37. Ignoring the current best solution, create an entirely new solution to the problem."
"38. Let’s think step by step ."
"39. Let’s make a step by step plan and implement it with good notation and explanation.",
]
_REASONING_MODULES = "\n".join(_REASONING_MODULES)
SELECT_PRMOPT_TEMPLATE = PromptTemplate(
"Given the task: {task}, which of the following reasoning modules are relevant? Do not elaborate on why.\n\n {reasoning_modules}"
)
ADAPT_PROMPT_TEMPLATE = PromptTemplate(
"Without working out the full solution, adapt the following reasoning modules to be specific to our task:\n{selected_modules}\n\nOur task:\n{task}"
)
IMPLEMENT_PROMPT_TEMPLATE = PromptTemplate(
"Without working out the full solution, create an actionable reasoning structure for the task using these adapted reasoning modules:\n{adapted_modules}\n\nTask Description:\n{task}"
)
REASONING_PROMPT_TEMPLATE = PromptTemplate(
"Using the following reasoning structure: {reasoning_structure}\n\nSolve this task, providing your final answer: {task}"
)
from llama_index.core.prompts import PromptTemplate
_REASONING_MODULES = [
"1. How could I devise an experiment to help solve that problem?",
"2. Make a list of ideas for solving this problem, and apply them one by one to the problem to see if any progress can be made.",
"3. How could I measure progress on this problem?",
"4. How can I simplify the problem so that it is easier to solve?",
"5. What are the key assumptions underlying this problem?",
"6. What are the potential risks and drawbacks of each solution?",
"7. What are the alternative perspectives or viewpoints on this problem?",
"8. What are the long-term implications of this problem and its solutions?",
"9. How can I break down this problem into smaller, more manageable parts?",
"10. Critical Thinking: This style involves analyzing the problem from different perspectives, questioning assumptions, and evaluating the evidence or information available. It focuses on logical reasoning, evidence-based decision-making, and identifying potential biases or flaws in thinking.",
"11. Try creative thinking, generate innovative and out-of-the-box ideas to solve the problem. Explore unconventional solutions, thinking beyond traditional boundaries, and encouraging imagination and originality.",
"12. Seek input and collaboration from others to solve the problem. Emphasize teamwork, open communication, and leveraging the diverse perspectives and expertise of a group to come up with effective solutions.",
"13. Use systems thinking: Consider the problem as part of a larger system and understanding the interconnectedness of various elements. Focuses on identifying the underlying causes, feedback loops, and interdependencies that influence the problem, and developing holistic solutions that address the system as a whole.",
"14. Use Risk Analysis: Evaluate potential risks, uncertainties, and tradeoffs associated with different solutions or approaches to a problem. Emphasize assessing the potential consequences and likelihood of success or failure, and making informed decisions based on a balanced analysis of risks and benefits.",
"15. Use Reflective Thinking: Step back from the problem, take the time for introspection and self-reflection. Examine personal biases, assumptions, and mental models that may influence problem-solving, and being open to learning from past experiences to improve future approaches.",
"16. What is the core issue or problem that needs to be addressed?",
"17. What are the underlying causes or factors contributing to the problem?",
"18. Are there any potential solutions or strategies that have been tried before? If yes, what were the outcomes and lessons learned?",
"19. What are the potential obstacles or challenges that might arise in solving this problem?",
"20. Are there any relevant data or information that can provide insights into the problem? If yes, what data sources are available, and how can they be analyzed?",
"21. Are there any stakeholders or individuals who are directly affected by the problem? What are their perspectives and needs?",
"22. What resources (financial, human, technological, etc.) are needed to tackle the problem effectively?",
"23. How can progress or success in solving the problem be measured or evaluated?",
"24. What indicators or metrics can be used?",
"25. Is the problem a technical or practical one that requires a specific expertise or skill set? Or is it more of a conceptual or theoretical problem?",
"26. Does the problem involve a physical constraint, such as limited resources, infrastructure, or space?",
"27. Is the problem related to human behavior, such as a social, cultural, or psychological issue?",
"28. Does the problem involve decision-making or planning, where choices need to be made under uncertainty or with competing objectives?",
"29. Is the problem an analytical one that requires data analysis, modeling, or optimization techniques?",
"30. Is the problem a design challenge that requires creative solutions and innovation?",
"31. Does the problem require addressing systemic or structural issues rather than just individual instances?",
"32. Is the problem time-sensitive or urgent, requiring immediate attention and action?",
"33. What kinds of solution typically are produced for this kind of problem specification?",
"34. Given the problem specification and the current best solution, have a guess about other possible solutions."
"35. Let’s imagine the current best solution is totally wrong, what other ways are there to think about the problem specification?"
"36. What is the best way to modify this current best solution, given what you know about these kinds of problem specification?"
"37. Ignoring the current best solution, create an entirely new solution to the problem."
"38. Let’s think step by step ."
"39. Let’s make a step by step plan and implement it with good notation and explanation.",
]
_REASONING_MODULES = "\n".join(_REASONING_MODULES)
SELECT_PRMOPT_TEMPLATE = PromptTemplate(
"Given the task: {task}, which of the following reasoning modules are relevant? Do not elaborate on why.\n\n {reasoning_modules}"
)
ADAPT_PROMPT_TEMPLATE = PromptTemplate(
"Without working out the full solution, adapt the following reasoning modules to be specific to our task:\n{selected_modules}\n\nOur task:\n{task}"
)
IMPLEMENT_PROMPT_TEMPLATE = PromptTemplate(
"Without working out the full solution, create an actionable reasoning structure for the task using these adapted reasoning modules:\n{adapted_modules}\n\nTask Description:\n{task}"
)
REASONING_PROMPT_TEMPLATE = PromptTemplate(
"Using the following reasoning structure: {reasoning_structure}\n\nSolve this task, providing your final answer: {task}"
)
设计工作流程¶
SELF-DISCOVER包含以下步骤:
- 从给定的推理模块中选择一个子集。
- 根据任务优化和调整给定的推理模块子集。
- 根据适配的推理模块为给定任务创建推理结构。
- 根据推理结构为任务生成最终答案。
需要以下事件:
GetModulesEvent
: 在检索到部分模块后触发。RefineModulesEvent
: 在模块经过优化调整以适应任务后触发。ReasoningStructureEvent
: 在推理结构生成后触发。
In [ ]:
Copied!
from llama_index.core.workflow import Event
class GetModulesEvent(Event):
"""Event to get modules."""
task: str
modules: str
class RefineModulesEvent(Event):
"""Event to refine modules."""
task: str
refined_modules: str
class ReasoningStructureEvent(Event):
"""Event to create reasoning structure."""
task: str
reasoning_structure: str
from llama_index.core.workflow import Event
class GetModulesEvent(Event):
"""获取模块的事件。"""
task: str
modules: str
class RefineModulesEvent(Event):
"""优化模块的事件。"""
task: str
refined_modules: str
class ReasoningStructureEvent(Event):
"""创建推理结构的事件。"""
task: str
reasoning_structure: str
以下是SELF-DISCOVER工作流程的代码:
In [ ]:
Copied!
from llama_index.core.workflow import (
Workflow,
Context,
StartEvent,
StopEvent,
step,
)
from llama_index.core.llms import LLM
class SelfDiscoverWorkflow(Workflow):
"""Self discover workflow."""
@step
async def get_modules(
self, ctx: Context, ev: StartEvent
) -> GetModulesEvent:
"""Get modules step."""
# get input data, store llm into ctx
task = ev.get("task")
llm: LLM = ev.get("llm")
if task is None or llm is None:
raise ValueError("'task' and 'llm' arguments are required.")
await ctx.set("llm", llm)
# format prompt and get result from LLM
prompt = SELECT_PRMOPT_TEMPLATE.format(
task=task, reasoning_modules=_REASONING_MODULES
)
result = llm.complete(prompt)
return GetModulesEvent(task=task, modules=str(result))
@step
async def refine_modules(
self, ctx: Context, ev: GetModulesEvent
) -> RefineModulesEvent:
"""Refine modules step."""
task = ev.task
modules = ev.modules
llm: LLM = await ctx.get("llm")
# format prompt and get result
prompt = ADAPT_PROMPT_TEMPLATE.format(
task=task, selected_modules=modules
)
result = llm.complete(prompt)
return RefineModulesEvent(task=task, refined_modules=str(result))
@step
async def create_reasoning_structure(
self, ctx: Context, ev: RefineModulesEvent
) -> ReasoningStructureEvent:
"""Create reasoning structures step."""
task = ev.task
refined_modules = ev.refined_modules
llm: LLM = await ctx.get("llm")
# format prompt, get result
prompt = IMPLEMENT_PROMPT_TEMPLATE.format(
task=task, adapted_modules=refined_modules
)
result = llm.complete(prompt)
return ReasoningStructureEvent(
task=task, reasoning_structure=str(result)
)
@step
async def get_final_result(
self, ctx: Context, ev: ReasoningStructureEvent
) -> StopEvent:
"""Gets final result from reasoning structure event."""
task = ev.task
reasoning_structure = ev.reasoning_structure
llm: LLM = await ctx.get("llm")
# format prompt, get res
prompt = REASONING_PROMPT_TEMPLATE.format(
task=task, reasoning_structure=reasoning_structure
)
result = llm.complete(prompt)
return StopEvent(result=result)
from llama_index.core.workflow import (
Workflow,
Context,
StartEvent,
StopEvent,
step,
)
from llama_index.core.llms import LLM
class SelfDiscoverWorkflow(Workflow):
"""自我发现工作流"""
@step
async def get_modules(
self, ctx: Context, ev: StartEvent
) -> GetModulesEvent:
"""获取模块步骤"""
# 获取输入数据,将llm存储到ctx中
task = ev.get("task")
llm: LLM = ev.get("llm")
if task is None or llm is None:
raise ValueError("'task'和'llm'参数是必需的")
await ctx.set("llm", llm)
# 格式化提示并从LLM获取结果
prompt = SELECT_PRMOPT_TEMPLATE.format(
task=task, reasoning_modules=_REASONING_MODULES
)
result = llm.complete(prompt)
return GetModulesEvent(task=task, modules=str(result))
@step
async def refine_modules(
self, ctx: Context, ev: GetModulesEvent
) -> RefineModulesEvent:
"""优化模块步骤"""
task = ev.task
modules = ev.modules
llm: LLM = await ctx.get("llm")
# 格式化提示并获取结果
prompt = ADAPT_PROMPT_TEMPLATE.format(
task=task, selected_modules=modules
)
result = llm.complete(prompt)
return RefineModulesEvent(task=task, refined_modules=str(result))
@step
async def create_reasoning_structure(
self, ctx: Context, ev: RefineModulesEvent
) -> ReasoningStructureEvent:
"""创建推理结构步骤"""
task = ev.task
refined_modules = ev.refined_modules
llm: LLM = await ctx.get("llm")
# 格式化提示,获取结果
prompt = IMPLEMENT_PROMPT_TEMPLATE.format(
task=task, adapted_modules=refined_modules
)
result = llm.complete(prompt)
return ReasoningStructureEvent(
task=task, reasoning_structure=str(result)
)
@step
async def get_final_result(
self, ctx: Context, ev: ReasoningStructureEvent
) -> StopEvent:
"""从推理结构事件中获取最终结果"""
task = ev.task
reasoning_structure = ev.reasoning_structure
llm: LLM = await ctx.get("llm")
# 格式化提示,获取结果
prompt = REASONING_PROMPT_TEMPLATE.format(
task=task, reasoning_structure=reasoning_structure
)
result = llm.complete(prompt)
return StopEvent(result=result)
运行工作流¶
In [ ]:
Copied!
from llama_index.llms.openai import OpenAI
workflow = SelfDiscoverWorkflow()
llm = OpenAI("gpt-4o")
from llama_index.llms.openai import OpenAI
workflow = SelfDiscoverWorkflow()
llm = OpenAI("gpt-4o")
In [ ]:
Copied!
from IPython.display import display, Markdown
task = "Michael has 15 oranges. He gives 4 oranges to his brother and trades 3 oranges for 6 apples with his neighbor. Later in the day, he realizes some of his oranges are spoiled, so he discards 2 of them. Then, Michael goes to the market and buys 12 more oranges and 5 more apples. If Michael decides to give 2 apples to his friend, how many oranges and apples does Michael have now?"
result = await workflow.run(task=task, llm=llm)
display(Markdown(str(result)))
from IPython.display import display, Markdown
task = "迈克尔有15个橙子。他给弟弟4个橙子,并用3个橙子与邻居换了6个苹果。当天晚些时候,他发现有些橙子坏了,于是扔掉了2个。然后,迈克尔去市场又买了12个橙子和5个苹果。如果迈克尔决定给朋友2个苹果,那么他现在有多少个橙子和苹果?"
result = await workflow.run(task=task, llm=llm)
display(Markdown(str(result)))
为了解决确定迈克尔现在有多少个橙子和苹果的任务,我们将采用结构化推理方法,将问题分解为更小、更易管理的部分。我们将逐步更新橙子和苹果的数量。
分步计划:¶
橙子的初始数量:
- 迈克尔一开始有15个橙子。
- ( \text{Oranges} = 15 )
给他兄弟的橙子:
- 迈克尔给了他兄弟4个橙子。
- ( \text{Oranges} = 15 - 4 = 11 )
用橙子交换苹果:
- 迈克尔用3个橙子换了6个苹果。
- ( \text{Oranges} = 11 - 3 = 8 )
- ( \text{Apples} = 0 + 6 = 6 )
腐烂橙子已丢弃:
- 迈克尔丢弃了2个坏掉的橙子。
- ( \text{Oranges} = 8 - 2 = 6 )
在市场上购买的橙子:
- 迈克尔又买了12个橙子。
- ( \text{Oranges} = 6 + 12 = 18 )
苹果的初始数量:
- 迈克尔最初没有苹果。
- ( \text{Apples} = 6 ) (来自交易)
在市场上购买的苹果:
- 迈克尔多买了5个苹果。
- ( \text{Apples} = 6 + 5 = 11 )
送给朋友的苹果:
- 迈克尔给他的朋友2个苹果。
- ( \text{Apples} = 11 - 2 = 9 )
最终计数:¶
- 橙子: 18
- 苹果: 9
因此,Michael现在有18个橙子和9个苹果。