wow-agent---Day3 Zigent 智能代理开发框架

打印 上一主题 下一主题

主题 1010|帖子 1010|积分 3030

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
这个框架是课程讲解的,但资料比较少,觉得框架比较小众,所以这里只分析代码,计划把更多的精力放在metagpt的学习上,毕竟还是要学教为主流的框架,这对后续维护升级都有资助,当然感爱好作为研究,可以研究下这个小框架。
代码目的是要生成一个一个教程编写智能体,其主要功能是输入教程主题,然后自动生成完备的教程内容,首先定义WriteDirectoryAction类,用于生成教程的目次,然后再定义生成教程的类,最后是执行层的代码。
  1. Python复制
  2. class WriteDirectoryAction(BaseAction):
  3.     """
  4.     生成教程目录结构的动作类。
  5.     该类用于根据给定的主题和语言,生成教程的目录结构。目录结构以字典格式输出,包含主目录和子目录,每个目录标题都有实际意义。
  6.     Attributes:
  7.         action_name (str): 动作名称,固定为"WriteDirectory"。
  8.         action_desc (str): 动作描述,固定为"Generate tutorial directory structure"。
  9.         params_doc (dict): 参数文档,包含主题(topic)和语言(language)两个参数的类型和说明。
  10.     Methods:
  11.         __call__(**kwargs): 根据给定的主题和语言生成教程目录结构。
  12.     Example:
  13.         >>> action = WriteDirectoryAction()
  14.         >>> result = action(topic="Python编程", language="Chinese")
  15.         >>> print(result)
  16.         {'topic': 'Python编程', 'language': 'Chinese', 'directory_data': {'title': 'Python编程', 'directory': [{'基础概念': ['变量', '数据类型']}, {'进阶应用': ['函数', '模块']}]}}
  17.     Note:
  18.         该类依赖于LLM模型来生成目录结构,如果LLM模型返回的数据不符合预期格式,将返回默认的目录数据。
  19.     """
  20.     def __init__(self) -> None:
  21.         """
  22.         初始化WriteDirectoryAction类。
  23.         初始化时设置动作名称、描述和参数文档。
  24.         """
  25.         action_name = "WriteDirectory"
  26.         action_desc = "Generate tutorial directory structure"
  27.         params_doc = {
  28.             "topic": "(Type: string): The tutorial topic name",
  29.             "language": "(Type: string): Output language (default: 'Chinese')"
  30.         }
  31.         super().__init__(action_name, action_desc, params_doc)
  32.     def __call__(self, **kwargs):
  33.         """
  34.         根据给定的主题和语言生成教程目录结构。
  35.         Args:
  36.             **kwargs: 关键字参数,包含主题(topic)和语言(language)两个参数。
  37.                 topic (str): 教程主题名称,默认为空字符串。
  38.                 language (str): 输出语言,默认为"Chinese"。
  39.         Returns:
  40.             dict: 包含主题、语言和目录数据的字典。
  41.         Raises:
  42.             json.JSONDecodeError: 如果LLM模型返回的数据不符合JSON格式。
  43.         """
  44.         topic = kwargs.get("topic", "")
  45.         language = kwargs.get("language", "Chinese")
  46.         directory_prompt = f"""
  47.         请为主题"{topic}"生成教程目录结构,要求:
  48.         1. 输出语言必须是{language}
  49.         2. 严格按照以下字典格式输出: {
  50.   
  51.   {"title": "xxx", "directory": [{
  52.   
  53.   {"章节1": ["小节1", "小节2"]}}, {
  54.   
  55.   {"章节2": ["小节3", "小节4"]}}]}}
  56.         3. 目录层次要合理,包含主目录和子目录
  57.         4. 每个目录标题要有实际意义
  58.         5. 不要有多余的空格或换行
  59.         """
  60.         # 调用 LLM 生成目录
  61.         directory_data = llm.llm_chain.invoke({"prompt": directory_prompt})
  62.         try:
  63.             directory_data = json.loads(directory_data)
  64.         except:
  65.             directory_data = {"title": topic, "directory": []}
  66.         return {
  67.             "topic": topic,
  68.             "language": language,
  69.             "directory_data": directory_data
  70.         }
复制代码
  1. class WriteContentAction(BaseAction):
  2.     """
  3.     生成教程详细内容的动作类。
  4.     该类用于根据给定的教程标题、章节、小节标题、目录结构和语言,生成教程的详细内容。内容以Markdown格式输出,包含代码示例(如有),长度适中。
  5.     Attributes:
  6.         action_name (str): 动作名称,固定为"WriteContent"。
  7.         action_desc (str): 动作描述,固定为"Generate detailed tutorial content based on directory structure"。
  8.         params_doc (dict): 参数文档,包含标题(title)、章节(chapter)、目录数据(directory_data)和语言(language)四个参数的类型和说明。
  9.     Methods:
  10.         __call__(**kwargs): 根据给定的参数生成教程详细内容。
  11.     Example:
  12.         >>> action = WriteContentAction()
  13.         >>> directory_data = {'title': 'Python编程', 'directory': [{'基础概念': ['变量', '数据类型']}, {'进阶应用': ['函数', '模块']}]}
  14.         >>> content = action(title="变量", chapter="基础概念", language="Chinese", directory_data=directory_data)
  15.         >>> print(content)
  16.         # 变量
  17.         在Python中,变量是用来存储数据的容器...
  18.     Note:
  19.         该类依赖于LLM模型来生成内容,如果LLM模型返回的数据不符合预期,可能需要手动调整。
  20.     """
  21.     def __init__(self) -> None:
  22.         """
  23.         初始化WriteContentAction类。
  24.         初始化时设置动作名称、描述和参数文档。
  25.         """
  26.         action_name = "WriteContent"
  27.         action_desc = "Generate detailed tutorial content based on directory structure"
  28.         params_doc = {
  29.             "title": "(Type: string): The section title",
  30.             "chapter": "(Type: string): The chapter title",
  31.             "directory_data": "(Type: dict): The complete directory structure",
  32.             "language": "(Type: string): Output language (default: 'Chinese')"
  33.         }
  34.         super().__init__(action_name, action_desc, params_doc)
  35.     def __call__(self, **kwargs):
  36.         """
  37.         根据给定的参数生成教程详细内容。
  38.         Args:
  39.             **kwargs: 关键字参数,包含标题(title)、章节(chapter)、语言(language)和目录数据(directory_data)四个参数。
  40.                 title (str): 小节标题,默认为空字符串。
  41.                 chapter (str): 章节标题,默认为空字符串。
  42.                 language (str): 输出语言,默认为"Chinese"。
  43.                 directory_data (dict): 完整的目录结构,默认为空字典。
  44.         Returns:
  45.             str: 生成的教程详细内容。
  46.         Raises:
  47.             Exception: 如果LLM模型调用失败。
  48.         """
  49.         title = kwargs.get("title", "")
  50.         chapter = kwargs.get("chapter", "")
  51.         language = kwargs.get("language", "Chinese")
  52.         directory_data = kwargs.get("directory_data", {})
  53.         content_prompt = f"""
  54.         请为教程章节生成详细内容:
  55.         教程标题: {directory_data.get('title', '')}
  56.         章节: {chapter}
  57.         小节: {title}
  58.         
  59.         要求:
  60.         1. 内容要详细且准确
  61.         2. 如果需要代码示例,请按标准规范提供
  62.         3. 使用 Markdown 格式
  63.         4. 输出语言必须是{language}
  64.         5. 内容长度适中,通常在500-1000字之间
  65.         """
  66.         # 调用 LLM 生成内容
  67.         content = llm.llm_chain.invoke({"prompt": content_prompt})
  68.         return content
复制代码
  1. class TutorialAssistant(BaseAgent):
  2.     """
  3.     教程生成助手类,管理目录和内容创建。
  4.     该类用于生成完整教程,包括目录结构和详细内容。它依赖于WriteDirectoryAction和WriteContentAction两个动作类来分别生成目录结构和详细内容。
  5.     Attributes:
  6.         name (str): 助手名称,固定为"TutorialAssistant"。
  7.         role (str): 助手角色描述,说明其专业领域和能力。
  8.         llm (BaseLLM): 语言模型实例,用于生成目录结构和详细内容。
  9.         language (str): 输出语言,默认为"Chinese"。
  10.         directory_action (WriteDirectoryAction): 生成目录结构的动作实例。
  11.         content_action (WriteContentAction): 生成详细内容的动作实例。
  12.     Methods:
  13.         _generate_tutorial(directory_data): 根据目录结构生成完整教程内容。
  14.         __call__(task): 处理教程生成任务,生成目录结构和详细内容,并保存结果。
  15.         _add_tutorial_example(): 添加教程生成助手的示例用例。
  16.     Example:
  17.         >>> assistant = TutorialAssistant(llm)
  18.         >>> task = TaskPackage(instruction="Create a Python tutorial for beginners")
  19.         >>> result = assistant(task)
  20.         >>> print(result.answer)
  21.         # Python基础教程
  22.         ## 目录
  23.         1. 第一章:Python介绍
  24.            1.1 什么是Python
  25.            1.2 环境搭建
  26.         ...
  27.     Note:
  28.         该类假设语言模型能够正常工作,如果语言模型返回的数据不符合预期,可能需要手动调整。
  29.     """
  30.     def __init__(
  31.         self,
  32.         llm: BaseLLM,
  33.         language: str = "Chinese"
  34.     ):
  35.         """
  36.         初始化TutorialAssistant类。
  37.         初始化时设置助手名称、角色描述、语言模型实例、输出语言、目录动作实例和内容动作实例。
  38.         Args:
  39.             llm (BaseLLM): 语言模型实例。
  40.             language (str, optional): 输出语言,默认为"Chinese"。
  41.         """
  42.         name = "TutorialAssistant"
  43.         role = """You are a professional tutorial writer. You can create well-structured,
  44.         comprehensive tutorials on various topics. You excel at organizing content logically
  45.         and explaining complex concepts clearly."""
  46.         
  47.         super().__init__(
  48.             name=name,
  49.             role=role,
  50.             llm=llm,
  51.         )
  52.         
  53.         self.language = language
  54.         self.directory_action = WriteDirectoryAction()
  55.         self.content_action = WriteContentAction()
  56.    
  57.         # Add example for the tutorial assistant
  58.         self._add_tutorial_example()
  59.         
  60.     def _generate_tutorial(self, directory_data: Dict) -> str:
  61.         """
  62.         根据目录结构生成完整教程内容。
  63.         Args:
  64.             directory_data (Dict): 目录结构数据,包含教程标题和章节信息。
  65.         Returns:
  66.             str: 生成的完整教程内容。
  67.         Raises:
  68.             Exception: 如果目录结构数据不符合预期格式。
  69.         """
  70.         full_content = []
  71.         title = directory_data["title"]
  72.         full_content.append(f"# {title}\n")
  73.         
  74.         # Generate table of contents
  75.         full_content.append("## 目录\n")
  76.         for idx, chapter in enumerate(directory_data["directory"], 1):
  77.             for chapter_title, sections in chapter.items():
  78.                 full_content.append(f"{idx}. {chapter_title}")
  79.                 for section_idx, section in enumerate(sections, 1):
  80.                     full_content.append(f"   {idx}.{section_idx}. {section}")
  81.         full_content.append("\n---\n")
  82.         
  83.         # Generate content for each section
  84.         for chapter in directory_data["directory"]:
  85.             for chapter_title, sections in chapter.items():
  86.                 for section in sections:
  87.                     content = self.content_action(
  88.                         title=section,
  89.                         chapter=chapter_title,
  90.                         directory_data=directory_data,
  91.                         language=self.language
  92.                     )
  93.                     full_content.append(content)
  94.                     full_content.append("\n---\n")
  95.         
  96.         return "\n".join(full_content)
  97.     def __call__(self, task: TaskPackage):
  98.         """
  99.         处理教程生成任务,生成目录结构和详细内容,并保存结果。
  100.         Args:
  101.             task (TaskPackage): 教程生成任务,包含指令信息。
  102.         Returns:
  103.             TaskPackage: 处理后的任务,包含生成的教程内容和完成状态。
  104.         Raises:
  105.             Exception: 如果任务指令不符合预期格式。
  106.         """
  107.         # Extract topic from task
  108.         topic = task.instruction.split("Create a ")[-1].split(" tutorial")[0]
  109.         if not topic:
  110.             topic = task.instruction
  111.             
  112.         # Generate directory structure
  113.         directory_result = self.directory_action(
  114.             topic=topic,
  115.             language=self.language
  116.         )
  117.         print(directory_result)
  118.         
  119.         # Generate complete tutorial
  120.         tutorial_content = self._generate_tutorial(directory_result["directory_data"])
  121.         # Save the result
  122.         task.answer = tutorial_content
  123.         task.completion = "completed"
  124.         
  125.         return task
  126.     def _add_tutorial_example(self):
  127.         """
  128.         添加教程生成助手的示例用例。
  129.         示例用例用于演示教程生成助手的工作流程和输出格式。
  130.         """
  131.         exp_task = "Create a Python tutorial for beginners"
  132.         exp_task_pack = TaskPackage(instruction=exp_task)
  133.         topic = "Python基础教程"
  134.         act_1 = AgentAct(
  135.             name=ThinkAct.action_name,
  136.             params={INNER_ACT_KEY: """First, I'll create a directory structure for the Python tutorial,
  137.             then generate detailed content for each section."""}
  138.         )
  139.         obs_1 = "OK. I'll start with the directory structure."
  140.         act_2 = AgentAct(
  141.             name=self.directory_action.action_name,
  142.             params={
  143.                 "topic": topic,
  144.                 "language": self.language
  145.             }
  146.         )
  147.         obs_2 = """{"title": "Python基础教程", "directory": [
  148.             {"第一章:Python介绍": ["1.1 什么是Python", "1.2 环境搭建"]},
  149.             {"第二章:基础语法": ["2.1 变量和数据类型", "2.2 控制流"]}
  150.         ]}"""
  151.         act_3 = AgentAct(
  152.             name=self.content_action.action_name,
  153.             params={
  154.                 "title": "什么是Python",
  155.                 "chapter": "第一章:Python介绍",
  156.                 "directory_data": json.loads(obs_2),
  157.                 "language": self.language
  158.             }
  159.         )
  160.         obs_3 = """# 第一章:Python介绍\n## 什么是Python\n\nPython是一种高级编程语言..."""
  161.         act_4 = AgentAct(
  162.             name=FinishAct.action_name,
  163.             params={INNER_ACT_KEY: "Tutorial structure and content generated successfully."}
  164.         )
  165.         obs_4 = "Tutorial generation task completed successfully."
  166.         exp_act_obs = [(act_1, obs_1), (act_2, obs_2), (act_3, obs_3), (act_4, obs_4)]
  167.         
  168.         self.prompt_gen.add_example(
  169.             task=exp_task_pack,
  170.             action_chain=exp_act_obs
  171.         )
复制代码
执行层:
  1. if __name__ == "__main__":
  2.     #这行代码创建了一个TutorialAssistant实例,传入了一个语言模型llm。这个实例将用于生成教程
  3.     assistant = TutorialAssistant(llm=llm)
  4.     # 交互式生成教程
  5.     FLAG_CONTINUE = True
  6.     #使用一个while循环来持续接收用户输入,直到用户选择不再生成新的教程。
  7.     while FLAG_CONTINUE:
  8.         #通过input函数接收用户想要生成的教程主题。
  9.         input_text = input("What tutorial would you like to create?\n")
  10.         #将用户输入的主题封装成一个TaskPackage对象,这个对象将传递给TutorialAssistant实例。
  11.         task = TaskPackage(instruction=input_text)
  12.         #调用TutorialAssistant实例的__call__方法来处理任务,生成教程内容
  13.         result = assistant(task)
  14.         #将生成的教程内容打印到控制台。
  15.         print("\nGenerated Tutorial:\n")
  16.         print(result.answer)
  17.         # 创建输出目录,使用当前时间创建一个唯一的输出目录,确保每次生成的教程文件不会互相覆盖。
  18.         output_dir = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
  19.         os.makedirs(output_dir, exist_ok=True)
  20.         
  21.         # 处理文件名,确保有效
  22.         safe_input_text = "".join([c if c.isalnum() or c in (' ', '_') else '_' for c in input_text])
  23.         output_file = os.path.join(output_dir, f"{safe_input_text}.md")
  24.         
  25.         # 保存文件
  26.         with open(output_file, 'w', encoding='utf-8') as f:
  27.             f.write(result.answer)
  28.         
  29.         # 询问用户是否继续
  30.         #通过input函数询问用户是否想要继续生成新的教程,如果用户输入n,则退出循环。
  31.         if input("\nDo you want to create another tutorial? (y/n): ").lower() != "y":
  32.             FLAG_CONTINUE = False
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

水军大提督

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表