【LLM-agent】(task6)构建教程编写智能体
note
- 构建教程编写智能体
文章目录
- note
- 一、功能需求
- 二、相关代码
- (1)定义生成教程的目录 Action 类
- (2)定义生成教程内容的 Action 类
- (3)定义教程编写智能体
- (4)交互式操作调用教程编写智能体
- 三、Python小细节
- Reference
一、功能需求
功能:输入教程主题,然后自动生成完整的教程内容
思路:先通过 LLM 大模型生成教程的目录,再对目录按照二级标题进行分块,对于每块目录按照标题生成详细内容,最后再将标题和内容进行拼接。分块的设计解决了 LLM 大模型长文本的限制问题。
二、相关代码
(1)定义生成教程的目录 Action 类
定义 WriteDirectoryAction
类,继承自 BaseAction
。该类的主要功能是生成一个教程的目录结构。具体来说,它通过调用大语言模型(LLM)来根据给定的主题和语言生成一个符合特定格式的目录。
(2)定义生成教程内容的 Action 类
WriteContentAction
类用于生成教程内容。它的 __call__
方法接收标题、章节、语言和目录数据,并构建一个内容提示,最后调用 LLM 生成相应的内容。
(3)定义教程编写智能体
定义 TutorialAssistant
类,继承自 BaseAgent
,用于生成教程内容。其主要功能包括:
- 初始化目录和内容生成的动作(
WriteDirectoryAction
和WriteContentAction
) _generate_tutorial
方法根据目录数据生成完整的教程内容包括目录和每个章节的详细内容_add_tutorial_example
方法为助手添加一个示例任务并展示如何生成一个 Python 教程的目录和内容。最终调用__call__
方法处理生成教程的任务。它从任务中提取主题,生成目录结构,然后生成完整的教程内容,并将结果保存到本地。
(4)交互式操作调用教程编写智能体
在主程序中,创建 TutorialAssistant
实例并调用其 __call__
方法,实现交互式生成教程的功能。用户可以输入要创建的教程主题,然后调用 TutorialAssistant
生成相应的教程内容,并将结果保存到本地文件。
import os
from dotenv import load_dotenv# 加载环境变量
load_dotenv()
# 初始化变量
base_url = None
chat_model = None
api_key = None# 使用with语句打开文件,确保文件使用完毕后自动关闭
env_path = ".env.txt"
with open(env_path, 'r') as file:# 逐行读取文件for line in file:# 移除字符串头尾的空白字符(包括'\n')line = line.strip()# 检查并解析变量if "base_url" in line:base_url = line.split('=', 1)[1].strip().strip('"')elif "chat_model" in line:chat_model = line.split('=', 1)[1].strip().strip('"')elif "ZHIPU_API_KEY" in line:api_key = line.split('=', 1)[1].strip().strip('"')elif "BOCHA_API_KEY" in line:BOCHA_API_KEY = line.split('=', 1)[1].strip().strip('"')# 打印变量以验证
print(f"base_url: {base_url}")
print(f"chat_model: {chat_model}")
print(f"ZHIPU_API_KEY: {api_key}")from typing import List, Dict
from zigent.llm.agent_llms import LLM
from zigent.actions import BaseAction, ThinkAct, FinishAct
from zigent.agents import BaseAgent
from zigent.commons import TaskPackage, AgentAct
from zigent.actions.InnerActions import INNER_ACT_KEY
from datetime import datetime
import jsonllm = LLM(api_key=api_key, base_url=base_url, model_name=chat_model)
response = llm.run("你是谁?")
print(response)# 一、定义生成教程的目录 Action 类
class WriteDirectoryAction(BaseAction):"""Generate tutorial directory structure action"""def __init__(self) -> None:action_name = "WriteDirectory"action_desc = "Generate tutorial directory structure"params_doc = {"topic": "(Type: string): The tutorial topic name","language": "(Type: string): Output language (default: 'Chinese')"}super().__init__(action_name, action_desc, params_doc)def __call__(self, **kwargs):topic = kwargs.get("topic", "")language = kwargs.get("language", "Chinese")directory_prompt = f"""请为主题"{topic}"生成教程目录结构,要求:1. 输出语言必须是{language}2. 严格按照以下字典格式输出: {{"title": "xxx", "directory": [{{"章节1": ["小节1", "小节2"]}}, {{"章节2": ["小节3", "小节4"]}}]}}3. 目录层次要合理,包含主目录和子目录4. 每个目录标题要有实际意义5. 不要有多余的空格或换行"""# 调用 LLM 生成目录# directory_data = llm.llm_chain.invoke({"prompt": directory_prompt})directory_data = llm.run(prompt=directory_prompt) # 注意这里传入的是prompt参数try:directory_data = json.loads(directory_data)except:directory_data = {"title": topic, "directory": []}return {"topic": topic,"language": language,"directory_data": directory_data}# 二、定义生成教程内容的 Action 类
class WriteContentAction(BaseAction):"""Generate tutorial content action"""def __init__(self) -> None:action_name = "WriteContent"action_desc = "Generate detailed tutorial content based on directory structure"params_doc = {"title": "(Type: string): The section title","chapter": "(Type: string): The chapter title","directory_data": "(Type: dict): The complete directory structure", "language": "(Type: string): Output language (default: 'Chinese')"}super().__init__(action_name, action_desc, params_doc)def __call__(self, **kwargs):title = kwargs.get("title", "")chapter = kwargs.get("chapter", "")language = kwargs.get("language", "Chinese")directory_data = kwargs.get("directory_data", {})content_prompt = f"""请为教程章节生成详细内容:教程标题: {directory_data.get('title', '')}章节: {chapter}小节: {title}要求:1. 内容要详细且准确2. 如果需要代码示例,请按标准规范提供3. 使用 Markdown 格式4. 输出语言必须是{language}5. 内容长度适中,通常在500-1000字之间"""# 调用 LLM 生成内容# content = llm.llm_chain.invoke({"prompt": content_prompt})content = llm.run(prompt=content_prompt) return content# 三、定义教程编写智能体
class TutorialAssistant(BaseAgent):"""Tutorial generation assistant that manages directory and content creation"""def __init__(self,llm: LLM, # BaseLLM,language: str = "Chinese"):name = "TutorialAssistant"role = """You are a professional tutorial writer. You can create well-structured, comprehensive tutorials on various topics. You excel at organizing content logically and explaining complex concepts clearly."""super().__init__(name=name,role=role,llm=llm,)self.language = languageself.directory_action = WriteDirectoryAction()self.content_action = WriteContentAction()# Add example for the tutorial assistantself._add_tutorial_example()def _generate_tutorial(self, directory_data: Dict) -> str:"""Generate complete tutorial content based on directory structure"""full_content = []title = directory_data["title"]full_content.append(f"# {title}\n")# Generate table of contentsfull_content.append("## 目录\n")for idx, chapter in enumerate(directory_data["directory"], 1):for chapter_title, sections in chapter.items():full_content.append(f"{idx}. {chapter_title}")for section_idx, section in enumerate(sections, 1):full_content.append(f" {idx}.{section_idx}. {section}")full_content.append("\n---\n")# Generate content for each sectionfor chapter in directory_data["directory"]:for chapter_title, sections in chapter.items():for section in sections:content = self.content_action(title=section,chapter=chapter_title,directory_data=directory_data,language=self.language)full_content.append(content)full_content.append("\n---\n")return "\n".join(full_content)def __call__(self, task: TaskPackage):"""Process the tutorial generation task"""# Extract topic from tasktopic = task.instruction.split("Create a ")[-1].split(" tutorial")[0]if not topic:topic = task.instruction# Generate directory structuredirectory_result = self.directory_action(topic=topic,language=self.language)print(directory_result)# Generate complete tutorialtutorial_content = self._generate_tutorial(directory_result["directory_data"])# Save the resulttask.answer = tutorial_contenttask.completion = "completed"return taskdef _add_tutorial_example(self):"""Add an illustration example for the tutorial assistant"""exp_task = "Create a Python tutorial for beginners"exp_task_pack = TaskPackage(instruction=exp_task)topic = "Python基础教程"act_1 = AgentAct(name=ThinkAct.action_name,params={INNER_ACT_KEY: """First, I'll create a directory structure for the Python tutorial, then generate detailed content for each section."""})obs_1 = "OK. I'll start with the directory structure."act_2 = AgentAct(name=self.directory_action.action_name,params={"topic": topic, "language": self.language})obs_2 = """{"title": "Python基础教程", "directory": [{"第一章:Python介绍": ["1.1 什么是Python", "1.2 环境搭建"]},{"第二章:基础语法": ["2.1 变量和数据类型", "2.2 控制流"]}]}"""act_3 = AgentAct(name=self.content_action.action_name,params={"title": "什么是Python","chapter": "第一章:Python介绍","directory_data": json.loads(obs_2),"language": self.language})obs_3 = """# 第一章:Python介绍\n## 什么是Python\n\nPython是一种高级编程语言..."""act_4 = AgentAct(name=FinishAct.action_name,params={INNER_ACT_KEY: "Tutorial structure and content generated successfully."})obs_4 = "Tutorial generation task completed successfully."exp_act_obs = [(act_1, obs_1), (act_2, obs_2), (act_3, obs_3), (act_4, obs_4)]self.prompt_gen.add_example(task=exp_task_pack,action_chain=exp_act_obs)# 四、交互式操作调用教程编写智能体
if __name__ == "__main__":assistant = TutorialAssistant(llm=llm)# 交互式生成教程FLAG_CONTINUE = Truewhile FLAG_CONTINUE:input_text = input("What tutorial would you like to create?\n")task = TaskPackage(instruction=input_text)result = assistant(task)print("\nGenerated Tutorial:\n")print(result.answer)# 创建输出目录output_dir = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")os.makedirs(output_dir, exist_ok=True)# 保存文件output_file = os.path.join(output_dir, f"{input_text}.md")with open(output_file, 'w', encoding='utf-8') as f:f.write(result.answer)if input("\nDo you want to create another tutorial? (y/n): ").lower() != "y":FLAG_CONTINUE = False
输出教程的主题后就会生成markdown格式的教程文档,我输的music,由于是先生成教程的大标题和各种子标题,再逐个将标题对应的内容生成,这样保证了长文本的生成,从结果来看确实有一大坨字数:
三、Python小细节
在Python中,__call__
方法允许一个类的实例表现得像函数一样,这意味着你可以直接调用一个实例,就像它是函数一样。当你定义了 __call__
方法后,这个类的实例就可以被当作一个可调用的对象。
下面是一个简单的例子来说明 __call__
方法是如何工作的:
class CallableClass:def __init__(self, value):self.value = valuedef __call__(self, addend):return self.value + addend
# 创建一个CallableClass的实例
callable_instance = CallableClass(10)
# 直接调用实例,就像它是函数一样
result = callable_instance(5) # 这将调用 __call__ 方法
print(result) # 输出 15
在这个例子中,CallableClass
有一个 __call__
方法,它接受一个参数 addend
,并返回实例属性 value
与 addend
的和。
以下是 __call__
方法的一些用途:
- 创建函数工厂:你可以创建一个类,其实例是定制化的函数。
- 封装函数调用:你可以使用类来封装函数调用,提供额外的逻辑或状态管理。
- 装饰器:在编写装饰器时,有时会使用
__call__
方法来定义装饰器如何调用原始函数。 - 回调函数:在需要传递回调函数的场景中,你可以使用具有
__call__
方法的对象,这样可以在回调中保持状态。
Reference
[1] https://github.com/datawhalechina/wow-agent
[2] https://www.datawhale.cn/learn/summary/86
[3] https://open.bochaai.com/
[4] 官方文档:https://docs.cloud.llamaindex.ai/
[5] 出题智能体、metagpt:https://www.cnblogs.com/HYLOVEYOURSELF/p/18691941
[6] 教程编写智能体:https://www.cnblogs.com/HYLOVEYOURSELF/p/18680532
相关文章:

【LLM-agent】(task6)构建教程编写智能体
note 构建教程编写智能体 文章目录 note一、功能需求二、相关代码(1)定义生成教程的目录 Action 类(2)定义生成教程内容的 Action 类(3)定义教程编写智能体(4)交互式操作调用教程编…...

29.Word:公司本财年的年度报告【13】
目录 NO1.2.3.4 NO5.6.7 NO8.9.10 NO1.2.3.4 另存为F12:考生文件夹:Word.docx选中绿色标记的标题文本→样式对话框→单击右键→点击样式对话框→单击右键→修改→所有脚本→颜色/字体/名称→边框:0.5磅、黑色、单线条:点…...

14 2D矩形模块( rect.rs)
一、 rect.rs源码 // Copyright 2013 The Servo Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENS…...

【Unity3D】实现2D角色/怪物死亡消散粒子效果
核心:这是一个Unity粒子系统自带的一种功能,可将粒子生成控制在一个Texture图片网格范围内,并且粒子颜色会自动采样图片的像素点颜色,之后则是粒子编辑出消散效果。 Particle System1物体(爆发式随机速度扩散10000个粒…...

Linux - 进程间通信(3)
目录 3、解决遗留BUG -- 边关闭信道边回收进程 1)解决方案 2)两种方法相比较 4、命名管道 1)理解命名管道 2)创建命名管道 a. 命令行指令 b. 系统调用方法 3)代码实现命名管道 构建类进行封装命名管道&#…...

3、C#基于.net framework的应用开发实战编程 - 实现(三、三) - 编程手把手系列文章...
三、 实现; 三.三、编写应用程序; 此文主要是实现应用的主要编码工作。 1、 分层; 此例子主要分为UI、Helper、DAL等层。UI负责便签的界面显示;Helper主要是链接UI和数据库操作的中间层;DAL为对数据库的操…...

C++编程语言:抽象机制:泛型编程(Bjarne Stroustrup)
泛型编程(Generic Programming) 目录 24.1 引言(Introduction) 24.2 算法和(通用性的)提升(Algorithms and Lifting) 24.3 概念(此指模板参数的插件)(Concepts) 24.3.1 发现插件集(Discovering a Concept) 24.3.2 概念与约束(Concepts and Constraints) 24.4 具体化…...

Python面试宝典13 | Python 变量作用域,从入门到精通
今天,我们来深入探讨一下 Python 中一个非常重要的概念——变量作用域。理解变量作用域对于编写清晰、可维护、无 bug 的代码至关重要。 什么是变量作用域? 简单来说,变量作用域就是指一个变量在程序中可以被访问的范围。Python 中有四种作…...

基于最近邻数据进行分类
人工智能例子汇总:AI常见的算法和例子-CSDN博客 完整代码: import torch import numpy as np from sklearn.neighbors import KNeighborsClassifier from sklearn.metrics import accuracy_score import matplotlib.pyplot as plt# 生成一个简单的数据…...

DeepSeek V3 vs R1:大模型技术路径的“瑞士军刀“与“手术刀“进化
DeepSeek V3 vs R1:——大模型技术路径的"瑞士军刀"与"手术刀"进化 大模型分水岭:从通用智能到垂直突破 2023年,GPT-4 Turbo的发布标志着通用大模型进入性能瓶颈期。当模型参数量突破万亿级门槛后,研究者们开…...

一、TensorFlow的建模流程
1. 数据准备与预处理: 加载数据:使用内置数据集或自定义数据。 预处理:归一化、调整维度、数据增强。 划分数据集:训练集、验证集、测试集。 转换为Dataset对象:利用tf.data优化数据流水线。 import tensorflow a…...

指导初学者使用Anaconda运行GitHub上One - DM项目的步骤
以下是指导初学者使用Anaconda运行GitHub上One - DM项目的步骤: 1. 安装Anaconda 下载Anaconda: 让初学者访问Anaconda官网(https://www.anaconda.com/products/distribution),根据其操作系统(Windows、M…...

7层还是4层?网络模型又为什么要分层?
~犬📰余~ “我欲贱而贵,愚而智,贫而富,可乎? 曰:其唯学乎” 一、为什么要分层 \quad 网络通信的复杂性促使我们需要一种分层的方法来理解和管理网络。就像建筑一样,我们不会把所有功能都混在一起…...

C++:抽象类习题
题目内容: 求正方体、球、圆柱的表面积,抽象出一个公共的基类Container为抽象类,在其中定义一个公共的数据成员radius(此数据可以作为正方形的边长、球的半径、圆柱体底面圆半径),以及求表面积的纯虚函数area()。由此抽象类派生出…...

C++ 泛型编程指南02 (模板参数的类型推导)
文章目录 一 深入了解C中的函数模板类型推断什么是类型推断?使用Boost TypeIndex库进行类型推断分析示例代码关键点解析 2. 理解函数模板类型推断2.1 指针或引用类型2.1.1 忽略引用2.1.2 保持const属性2.1.3 处理指针类型 2.2 万能引用类型2.3 传值方式2.4 传值方式…...

音视频入门基础:RTP专题(5)——FFmpeg源码中,解析SDP的实现
一、引言 FFmpeg源码中通过ff_sdp_parse函数解析SDP。该函数定义在libavformat/rtsp.c中: int ff_sdp_parse(AVFormatContext *s, const char *content) {const char *p;int letter, i;char buf[SDP_MAX_SIZE], *q;SDPParseState sdp_parse_state { { 0 } }, *s1…...

计算机网络 应用层 笔记 (电子邮件系统,SMTP,POP3,MIME,IMAP,万维网,HTTP,html)
电子邮件系统: SMTP协议 基本概念 工作原理 连接建立: 命令交互 客户端发送命令: 服务器响应: 邮件传输: 连接关闭: 主要命令 邮件发送流程 SMTP的缺点: MIME: POP3协议 基本概念…...

【视频+图文详解】HTML基础3-html常用标签
图文教程 html常用标签 常用标签 1. 文档结构 <!DOCTYPE html>:声明HTML文档类型。<html>:定义HTML文档的根元素。<head>:定义文档头部,包含元数据。<title>:设置网页标题,浏览…...

FreeRTOS学习 --- 消息队列
队列简介 队列是任务到任务、任务到中断、中断到任务数据交流的一种机制(消息传递) 全局变量的弊端:数据无保护,导致数据不安全,当多个任务同时对该变量操作时,数据易受损 使用队列的情况如下:…...

PHP If...Else 语句详解
PHP If...Else 语句详解 引言 在PHP编程中,if...else语句是流程控制的重要组成部分,它允许程序根据条件判断执行不同的代码块。本文将详细解析PHP中的if...else语句,包括其基本用法、高级技巧以及注意事项。 一、基本用法 if...else语句的…...

pytorch使用SVM实现文本分类
人工智能例子汇总:AI常见的算法和例子-CSDN博客 完整代码: import torch import torch.nn as nn import torch.optim as optim import jieba import numpy as np from sklearn.model_selection import train_test_split from sklearn.feature_extract…...

安卓(android)读取手机通讯录【Android移动开发基础案例教程(第2版)黑马程序员】
一、实验目的(如果代码有错漏,可在代码地址查看) 1.熟悉内容提供者(Content Provider)的概念和作用。 2.掌握内容提供者的创建和使用方法。 4.掌握内容URI的结构和用途。 二、实验条件 1.熟悉内容提供者的工作原理。 2.掌握内容提供者访问其…...

【Qt】常用的容器
Qt提供了多个基于模板的容器类,这些容器类可用于存储指定类型的数据项。例如常用的字符串列表类 QStringList 可用来操作一个 QList<QString>列表。 Qt的容器类比标准模板库(standard template library,STL)中的容器类更轻巧、使用更安全且更易于使…...

基于UKF-IMM无迹卡尔曼滤波与交互式多模型的轨迹跟踪算法matlab仿真,对比EKF-IMM和UKF
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于UKF-IMM无迹卡尔曼滤波与交互式多模型的轨迹跟踪算法matlab仿真,对比EKF-IMM和UKF。 2.测试软件版本以及运行结果展示 MATLAB2022A版本运行 3.核心程序 .…...

分布式事务组件Seata简介与使用,搭配Nacos统一管理服务端和客户端配置
文章目录 一. Seata简介二. 官方文档三. Seata分布式事务代码实现0. 环境简介1. 添加undo_log表2. 添加依赖3. 添加配置4. 开启Seata事务管理5. 启动演示 四. Seata Server配置Nacos1. 修改配置类型2. 创建Nacos配置 五. Seata Client配置Nacos1. 增加Seata关联Nacos的配置2. 在…...

JavaScript常用的内置构造函数
JavaScript作为一种广泛应用的编程语言,提供了丰富的内置构造函数,帮助开发者处理不同类型的数据和操作。这些内置构造函数在创建和操作对象时非常有用。本文将详细介绍JavaScript中常用的内置构造函数及其用途。 常用内置构造函数概述 1. Object Obj…...

25寒假算法刷题 | Day1 | LeetCode 240. 搜索二维矩阵 II,148. 排序链表
目录 240. 搜索二维矩阵 II题目描述题解 148. 排序链表题目描述题解 240. 搜索二维矩阵 II 点此跳转题目链接 题目描述 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性: 每行的元素从左到右升序排列。每列的元素从上到…...

MQTT知识
MQTT协议 MQTT 是一种基于发布/订阅模式的轻量级消息传输协议,专门针对低带宽和不稳定网络环境的物联网应用而设计,可以用极少的代码为联网设备提供实时可靠的消息服务。MQTT 协议广泛应用于物联网、移动互联网、智能硬件、车联网、智慧城市、远程医疗、…...

【机器学习与数据挖掘实战】案例11:基于灰色预测和SVR的企业所得税预测分析
【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈机器学习与数据挖掘实战 ⌋ ⌋ ⌋ 机器学习是人工智能的一个分支,专注于让计算机系统通过数据学习和改进。它利用统计和计算方法,使模型能够从数据中自动提取特征并做出预测或决策。数据挖掘则是从大型数据集中发现模式、关联…...

新一代搜索引擎,是 ES 的15倍?
Manticore Search介绍 Manticore Search 是一个使用 C 开发的高性能搜索引擎,创建于 2017 年,其前身是 Sphinx Search 。Manticore Search 充分利用了 Sphinx,显着改进了它的功能,修复了数百个错误,几乎完全重写了代码…...