Qwen-Agent框架的文件相关操作:从Assistant到BasicDocQA

在前面的几篇文章如《针对Qwen-Agent框架的Function Call及ReAct的源码阅读与解析:Agent基类篇》 、《基于Qwen-Agent框架的Function Call及ReAct方式调用自定义工具》、
《针对Qwen-Agent框架的源码阅读与解析:FnCallAgent与ReActChat篇》中,我们已经理解了Agent的具体运作机制与原理,这里我们再以文件相关操作为例,学习一下Agent的实际应用。

事实上,Qwen-Agent是一个强大的智能助手框架,它集成了RAG(检索增强生成)能力和函数调用能力,能够处理各种复杂任务。本文将深入探讨Qwen-Agent框架中的文件相关操作,特别是从Assistant类到BasicDocQA类的实现,分析代码结构、工作原理以及各个组件的功能。

文章目录

  • 2. Assistant类分析
    • 2.1 类定义与初始化
    • 2.2 知识格式化函数
    • 2.3 核心运行方法
    • 2.4 知识提示预处理
    • 2.5 辅助函数
  • 3. BasicDocQA类分析
    • 3.1 类定义与初始化
    • 3.2 提示模板
    • 3.3 核心运行方法
  • 4. 两个类的比较
    • 4.1 相同点
    • 4.2 区别点
  • 5. 工作流程分析
    • 5.1 Assistant类工作流程
    • 5.2 BasicDocQA类工作流程
  • 6. 实际应用场景
    • 6.1 Assistant类适用场景
    • 6.2 BasicDocQA类适用场景
  • 7. 总结


🎉进入大模型应用与实战专栏 | 🚀查看更多专栏内容


2. Assistant类分析

2.1 类定义与初始化

Assistant类是Qwen-Agent框架中的一个核心类,它继承自FnCallAgent,集成了RAG能力和函数调用能力。

class Assistant(FnCallAgent):"""This is a widely applicable agent integrated with RAG capabilities and function call ability."""def __init__(self,function_list: Optional[List[Union[str, Dict, BaseTool]]] = None,llm: Optional[Union[Dict, BaseChatModel]] = None,system_message: Optional[str] = DEFAULT_SYSTEM_MESSAGE,name: Optional[str] = None,description: Optional[str] = None,files: Optional[List[str]] = None,rag_cfg: Optional[Dict] = None):super().__init__(function_list=function_list,llm=llm,system_message=system_message,name=name,description=description,files=files,rag_cfg=rag_cfg)

初始化参数包括:

  • function_list:可调用的函数列表
  • llm:语言模型实例
  • system_message:系统消息
  • namedescription:Agent的名称和描述
  • files:文件列表
  • rag_cfg:RAG配置

2.2 知识格式化函数

format_knowledge_to_source_and_content函数用于将检索结果格式化为源和内容的标准格式:

def format_knowledge_to_source_and_content(result: Union[str, List[dict]]) -> List[dict]:knowledge = []if isinstance(result, str):# 字符串格式处理result = f'{result}'.strip()try:docs = json5.loads(result)except Exception:print_traceback()knowledge.append({'source': '上传的文档', 'content': result})return knowledgeelse:docs = resulttry:# 文档列表格式处理_tmp_knowledge = []assert isinstance(docs, list)for doc in docs:url, snippets = doc['url'], doc['text']assert isinstance(snippets, list)_tmp_knowledge.append({'source': f'[文件]({get_basename_from_url(url)})','content': '\n\n...\n\n'.join(snippets)})knowledge.extend(_tmp_knowledge)except Exception:print_traceback()knowledge.append({'source': '上传的文档', 'content': result})return knowledge

该函数支持两种输入格式:

  1. 字符串格式:尝试解析为JSON,失败则作为整体内容
  2. 文档列表格式:包含URL和文本片段的字典列表

输出为统一的[{'source': '来源', 'content': '内容'}, ...]格式。

2.3 核心运行方法

_run方法是Assistant类的核心方法,负责处理用户查询:

def _run(self,messages: List[Message],lang: Literal['en', 'zh'] = 'en',knowledge: str = '',**kwargs) -> Iterator[List[Message]]:"""Q&A with RAG and tool use abilities."""new_messages = self._prepend_knowledge_prompt(messages=messages, lang=lang, knowledge=knowledge, **kwargs)return super()._run(messages=new_messages, lang=lang, **kwargs)

该方法首先调用_prepend_knowledge_prompt方法添加知识提示,然后调用父类的_run方法处理消息。

2.4 知识提示预处理

_prepend_knowledge_prompt方法用于在消息前添加知识提示:

def _prepend_knowledge_prompt(self,messages: List[Message],lang: Literal['en', 'zh'] = 'en',knowledge: str = '',**kwargs) -> List[Message]:messages = copy.deepcopy(messages)if not knowledge:# 从文件中检索知识*_, last = self.mem.run(messages=messages, lang=lang, **kwargs)knowledge = last[-1][CONTENT]logger.debug(f'Retrieved knowledge of type `{type(knowledge).__name__}`:\n{knowledge}')if knowledge:knowledge = format_knowledge_to_source_and_content(knowledge)logger.debug(f'Formatted knowledge into type `{type(knowledge).__name__}`:\n{knowledge}')else:knowledge = []snippets = []for k in knowledge:snippets.append(KNOWLEDGE_SNIPPET[lang].format(source=k['source'], content=k['content']))knowledge_prompt = ''if snippets:knowledge_prompt = KNOWLEDGE_TEMPLATE[lang].format(knowledge='\n\n'.join(snippets))if knowledge_prompt:if messages[0][ROLE] == SYSTEM:messages[0][CONTENT] += '\n\n' + knowledge_promptelse:messages = [Message(role=SYSTEM, content=knowledge_prompt)] + messagesreturn messages

处理流程:

  1. 如果未提供知识,则从文件中检索
  2. 格式化知识为标准格式
  3. 将知识片段格式化为多语言模板
  4. 将格式化的知识添加到系统消息中

2.5 辅助函数

get_current_date_str函数用于获取当前日期的字符串表示:

def get_current_date_str(lang: Literal['en', 'zh'] = 'en',hours_from_utc: Optional[int] = None,
) -> str:# 获取当前时间if hours_from_utc is None:cur_time = datetime.datetime.now()else:cur_time = datetime.datetime.utcnow() + datetime.timedelta(hours=hours_from_utc)# 根据语言格式化日期字符串if lang == 'en':date_str = 'Current date: ' + cur_time.strftime('%A, %B %d, %Y')elif lang == 'zh':cur_time = cur_time.timetuple()date_str = f'当前时间:{cur_time.tm_year}{cur_time.tm_mon}{cur_time.tm_mday}日,星期'date_str += ['一', '二', '三', '四', '五', '六', '日'][cur_time.tm_wday]date_str += '。'else:raise NotImplementedErrorreturn date_str

该函数支持中英文两种格式,可以指定UTC时差。

3. BasicDocQA类分析

3.1 类定义与初始化

BasicDocQA类继承自Assistant类,专门用于文档问答:

class BasicDocQA(Assistant):"""This is an agent for doc QA."""def __init__(self,function_list: Optional[List[Union[str, Dict, BaseTool]]] = None,llm: Optional[Union[Dict, BaseChatModel]] = None,system_message: Optional[str] = DEFAULT_SYSTEM_MESSAGE,name: Optional[str] = DEFAULT_NAME,description: Optional[str] = DEFAULT_DESC,files: Optional[List[str]] = None,rag_cfg: Optional[Dict] = None):super().__init__(function_list=function_list,llm=llm,system_message=system_message,name=name,description=description,files=files,rag_cfg=rag_cfg)

默认名称和描述:

  • DEFAULT_NAME = 'Basic DocQA'
  • DEFAULT_DESC = '可以根据问题,检索出知识库中的某个相关细节来回答。适用于需要定位到具体位置的问题,例如"介绍表1"等类型的问题'

3.2 提示模板

BasicDocQA类使用特定的提示模板,支持中英文:

PROMPT_TEMPLATE_ZH = """请充分理解以下参考资料内容,组织出满足用户提问的条理清晰的回复。
#参考资料:
{ref_doc}"""PROMPT_TEMPLATE_EN = """Please fully understand the content of the following reference materials and organize a clear response that meets the user's questions.
# Reference materials:
{ref_doc}"""PROMPT_TEMPLATE = {'zh': PROMPT_TEMPLATE_ZH,'en': PROMPT_TEMPLATE_EN,
}

3.3 核心运行方法

BasicDocQA类重写了_run方法,使用不同的文档问答提示:

def _run(self, messages: List[Message], lang: str = 'en', **kwargs) -> Iterator[List[Message]]:"""This agent using different doc qa prompt with Assistant"""# 使用Memory agent进行数据管理*_, last = self.mem.run(messages=messages, **kwargs)knowledge = last[-1][CONTENT]messages = copy.deepcopy(messages)system_prompt = PROMPT_TEMPLATE[lang].format(ref_doc=knowledge)if messages[0][ROLE] == SYSTEM:messages[0][CONTENT] += '\n\n' + system_promptelse:messages.insert(0, Message(SYSTEM, system_prompt))response = self._call_llm(messages=messages)return response

处理流程:

  1. 使用mem.run检索相关知识
  2. 使用特定的文档问答提示模板
  3. 将格式化的提示添加到系统消息中
  4. 调用语言模型生成回复

4. 两个类的比较

4.1 相同点

  1. 都继承自Agent基类,具备Agent的基本能力
  2. 都集成了RAG能力,可以检索知识库
  3. 都支持中英文两种语言
  4. 都通过添加系统提示来引导模型回答

4.2 区别点

  1. 用途不同

    • Assistant类是通用助手,集成了RAG和函数调用能力
    • BasicDocQA类专注于文档问答,适用于需要定位具体细节的问题
  2. 提示模板不同

    • Assistant类使用知识库模板,强调知识来源
    • BasicDocQA类使用参考资料模板,强调对参考资料的理解和组织
  3. 处理流程不同

    • Assistant类先格式化知识,再添加到系统消息
    • BasicDocQA类直接将知识作为参考资料添加到系统消息

5. 工作流程分析

5.1 Assistant类工作流程

  1. 初始化Assistant实例,配置参数
  2. 接收用户消息
  3. 如果未提供知识,从文件中检索相关知识
  4. 格式化知识为标准格式(源和内容)
  5. 将格式化的知识添加到系统消息中
  6. 调用语言模型生成回复

5.2 BasicDocQA类工作流程

  1. 初始化BasicDocQA实例,配置参数
  2. 接收用户消息
  3. 从文件中检索相关知识
  4. 使用特定的文档问答提示模板
  5. 将格式化的提示添加到系统消息中
  6. 调用语言模型生成回复

6. 实际应用场景

6.1 Assistant类适用场景

  • 通用问答系统
  • 需要调用外部函数的场景
  • 多种知识源集成的场景
  • 需要展示知识来源的场景

6.2 BasicDocQA类适用场景

  • 特定文档问答
  • 需要定位文档中具体细节的场景
  • 专注于文档内容理解和组织的场景
  • 例如:“介绍表1”、"第三章说了什么"等具体位置问题

7. 总结

Qwen-Agent框架中的Assistant类和BasicDocQA类展示了框架在文件相关操作中的灵活性和强大能力。Assistant类作为通用助手,集成了RAG能力和函数调用能力,可以处理各种复杂任务;而BasicDocQA类专注于文档问答,适用于需要定位具体细节的问题。

两个类都通过添加系统提示来引导模型回答,但使用了不同的提示模板和处理流程。这种设计使得框架可以根据不同场景灵活配置,提供最适合的回答。

在实际应用中,开发者可以根据具体需求选择合适的类,或者基于这些类进行扩展,构建更加专业和高效的智能助手系统。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/74779.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RSSI定位程序,N个锚点、三维空间,使用CKF对轨迹进行滤波,附MATLAB代码的下载链接

本文所述的程序实现三维空间中基于RSSI信号的多锚点定位,并采用容积卡尔曼滤波(CKF)对动态轨迹进行降噪优化。代码包含完整的定位仿真流程,涵盖环境建模、信号强度模拟、定位解算、轨迹滤波及可视化分析模块 文章目录 程序介绍概述…

开源软件与自由软件:一场理念与实践的交锋

在科技的世界里,“开源软件”和“自由软件”这两个词几乎无人不知。很多人或许都听说过,它们的代码是公开的,可以供所有人查看、修改和使用。然而,若要细究它们之间的区别,恐怕不少朋友会觉得云里雾里。今天&#xff0…

C++ - 头文件基础(常用标准库头文件、自定义头文件、头文件引入方式、防止头文件重复包含机制)

一、头文件 在 C 中&#xff0c;头文件&#xff08;.h&#xff09;用于函数声明、类定义、宏定义等等 在 Visual Studio 中&#xff0c;头文件通常放在头文件目录中&#xff0c;头文件实现通常放在源文件目录中 二、常用标准库头文件 1、输入输出 <iostream> 标准输入…

CSS 背景属性学习笔记

一、CSS 背景属性概述 CSS 背景属性用于定义 HTML 元素的背景效果&#xff0c;主要包括以下几种属性&#xff1a; background-color&#xff1a;定义元素的背景颜色。 background-image&#xff1a;定义元素的背景图像。 background-repeat&#xff1a;定义背景图像如何重复…

Qt实现鼠标拖动窗口

Qt实现鼠标拖动窗口 1、设置窗口无边框2、重写鼠标点击&#xff0c;移动函数2.1添加头文件2.2 重写函数2.3 添加定义 3、定义一个偏移值4、判断鼠标左键是否按下并计算偏移值5、移动窗口6、.h文件和.cpp文件6.1 .h文件6.2 .cpp文件 7、总结 1、设置窗口无边框 this->setWin…

MDX语言的数论算法

MDX语言的数论算法探讨 引言 数论作为数学的一个重要分支&#xff0c;主要研究整数及其性质。在计算机科学和信息技术领域&#xff0c;数论算法被广泛应用于密码学、算法设计、数据加密等领域。MDX&#xff08;Multi-Dimensional Expressions&#xff09;语言&#xff0c;虽然…

【学Rust写CAD】34 精确 Alpha 混合函数(argb.rs补充方法)

源码 #[inline]pub fn over_exact(self, dst: Argb) -> Argb {let a 255 - self.alpha32();let t dst.rb() * a 0x80_00_80;let mut rb (t ((t >> 8) & Argb::MASK)) >> 8;rb & Argb::MASK;rb self.rb();// saturaterb | 0x1000100 - ((rb >&…

2025-04-06 NO.2 Quest3 基础配置与打包

文章目录 1 场景配置1.1 开启手势支持1.2 创建 OVRCameraRig1.3 创建可交互 Cube 2 打包配置 环境&#xff1a; Windows 11Unity6000.0.42f1 Quest3 开发环境配置见 2025-03-17 NO.1 Quest3 开发环境配置教程_quest3 unity 开发流程-CSDN博客。 1 场景配置 1.1 开启手势支持 …

LabVIEW提升程序响应速度

LabVIEW 程序在不同计算机上的响应速度可能存在较大差异&#xff0c;这通常由两方面因素决定&#xff1a;计算机硬件性能和程序本身的优化程度。本文将分别从硬件配置对程序运行的影响以及代码优化方法进行详细分析&#xff0c;帮助提升 LabVIEW 程序的执行效率。 一、计算机硬…

Matlab:三维绘图

目录 1.三维曲线绘图命令&#xff1a;plot3 实例——绘制空间直线 实例——绘制三角曲线 2.三维曲线绘图命令&#xff1a;explot3 3.三维网格命令&#xff1a;mesh 实例——绘制网格面 实例——绘制山峰曲面 实例——绘制函数曲线 1.三维曲线绘图命令&#xff1a;plot3 …

微信小程序基于Canvas实现头像图片裁剪(上)

序言 嘿&#xff0c;打工人混迹职场这么久&#xff0c;图片处理肯定都没少碰。不过咱说实话&#xff0c;大部分时候都是直接 “抄近道”&#xff0c;用现成的三方组件&#x1f60f;。就像我&#xff0c;主打一个会用工具&#xff0c;毕竟善用工具可是咱人类的 “超能力”&…

[特殊字符] 使用 Handsontable 构建一个支持 Excel 公式计算的动态表格

在 Web 应用中&#xff0c;处理表格数据并提供 Excel 级的功能&#xff08;如公式计算、数据导入导出&#xff09;一直是个挑战。今天&#xff0c;我将带你使用 React Handsontable 搭建一个强大的 Excel 风格表格&#xff0c;支持 公式计算、Excel 文件导入导出&#xff0c;并…

0302useState-hooks-react-仿低代码平台项目

文章目录 1 useState1.1 说明返回 1.2 示例1.3 数据类型 2 state2.1 概述2.2 state特点 3 state重构问卷4 immer结语 1 useState useState 是一个 React Hook&#xff0c;它允许你向组件添加一个 状态变量。 1.1 说明 语法 const [state, setState] useState(initialState…

前端实现单点登录(SSO)的方案

概念&#xff1a;单点登录&#xff08;Single Sign-On, SSO&#xff09;主要是在多个系统、多个浏览器或多个标签页之间共享登录状态&#xff0c;保证用户只需登录一次&#xff0c;就能访问多个关联应用&#xff0c;而不需要重复登录。 &#x1f4a1; 方案分类 1. 前端级别 SS…

zabbix监控网站(nginx、redis、mysql)

目录 前提准备&#xff1a; zabbix-server主机配置&#xff1a; 1. 安装数据库 nginx主机配置&#xff1a; 1. 安装nginx redis主机配置&#xff1a; 1. 安装redis mysql主机配置&#xff1a; 1. 安装数据库 zabbix-server&#xff1a; 1. 安装zabbix 2. 编辑配置文…

无人机等非合作目标公开数据集2025.4.3

一.无人机遥感数据概述 1.1 定义与特点 在遥感技术的不断发展中&#xff0c;无人机遥感数据作为一种新兴的数据源&#xff0c;正逐渐崭露头角。它是通过无人驾驶飞行器&#xff08;UAV&#xff09;搭载各种传感器获取的地理空间信息&#xff0c;具有 覆盖范围大、综合精度高、…

大数据时代的隐私保护:区块链技术的创新应用

一、引言 在当今数字化时代&#xff0c;大数据已经成为推动社会发展的关键力量。从商业决策到社会治理&#xff0c;从医疗健康到金融服务&#xff0c;数据的价值日益凸显。然而&#xff0c;随着数据的大量收集和广泛使用&#xff0c;隐私保护问题也日益突出。如何在充分利用大…

LeetCode 2442:统计反转后的不同整数数量

目录 核心思想&#xff1a;数字的“拆分”与“重组” 分步拆解&#xff08;以输入 123 为例&#xff09; 关键操作详解 为什么能处理中间或末尾的0&#xff1f; 数学本质 总结 题目描述 解题思路 代码实现 代码解析 复杂度分析 示例演示 总结 核心思想&#xff1a;…

Python爬虫第3节-会话、Cookies及代理的基本原理

目录 一、会话和Cookies 1.1 静态网页和动态网页 1.2 无状态HTTP 1.3 常见误区 二、代理的基本原理 2.1 基本原理 2.2 代理的作用 2.3 爬虫代理 2.4 代理分类 2.5 常见代理设置 一、会话和Cookies 大家在浏览网站过程中&#xff0c;肯定经常遇到需要登录的场景。有些…

Flutter项目之登录注册功能实现

目录&#xff1a; 1、页面效果2、登录两种状态界面3、中间按钮部分4、广告区域5、最新资讯6、登录注册页联调6.1、网络请求工具类6.2、注册页联调6.3、登录问题分析6.4、本地缓存6.5、共享token6.6、登录页联调6.7、退出登录 1、页面效果 import package:flutter/material.dart…