Qwen Agent 多文件问答系统

2026-02-03 Qwen Agent RAG

概述

本项目演示如何使用 Qwen Agent 框架构建一个多功能智能问答系统,集成了文档检索、图像生成和代码执行能力,提供图形界面和命令行两种交互模式。

核心功能:从 docs 目录加载多个文档文件,创建自定义图像生成工具,支持代码执行和图像处理。

技术架构

技术组件 功能描述 在本例中的作用
Assistant Qwen 智能体助手 核心智能体,协调工具和对话
BaseTool 基础工具类 自定义工具的基础类
register_tool 工具注册装饰器 注册自定义工具供智能体调用
code_interpreter 代码执行工具 在沙箱环境中执行 Python 代码
WebUI 图形界面组件 提供可视化交互界面

自定义图像生成工具

@register_tool('my_image_gen')
class MyImageGen(BaseTool):
    """
    自定义图像生成工具类
    
    该工具使用 pollinations.ai 服务根据文本描述生成图像,
    通过调用外部 API 实现 AI 绘画功能。
    """
    # 工具描述信息
    description = 'AI 绘画(图像生成)服务,输入文本描述,返回基于文本信息绘制的图像 URL。'
    
    # 工具参数定义
    parameters = [{
        'name': 'prompt',
        'type': 'string',
        'description': '期望的图像内容的详细描述',
        'required': True
    }]

    def call(self, params: str, **kwargs) -> str:
        """执行工具调用的方法"""
        # 解析参数字符串
        prompt = json5.loads(params)['prompt']
        
        # 对 prompt 进行 URL 编码
        prompt = urllib.parse.quote(prompt)
        
        # 构造图像生成服务的完整 URL
        return json5.dumps(
            {'image_url': f'https://image.pollinations.ai/prompt/{prompt}'},
            ensure_ascii=False)

该自定义工具使用 pollinations.ai 服务根据文本描述生成图像,通过 URL 编码确保特殊字符正确传输。

LLM 配置

llm_cfg = {
    # 配置 DashScope API 提供的深度寻求模型服务
    'model': 'deepseek-v3',
    # DashScope 兼容 OpenAI 格式的 API 地址
    'model_server': 'https://dashscope.aliyuncs.com/compatible-mode/v1',
    # 从系统环境变量获取 API 密钥
    'api_key': os.getenv('DASHSCOPE_API_KEY'),
    # 生成参数配置
    'generate_cfg': {
        'top_p': 0.8  # 核采样参数,控制输出的多样性
    }
}

配置 LLM 模型参数,包括模型名称、API 地址、密钥和生成参数等。

系统指令与工具配置

# 系统提示词,定义智能体的行为准则
system_instruction = '''你是一个乐于助人的AI助手。
在收到用户的请求后,你应该:
- 首先绘制一幅图像,得到图像的url,
- 然后运行代码`requests.get`以下载该图像的url,
- 最后从给定的文档中选择一个图像操作进行图像处理。
用 `plt.show()` 展示图像。
你总是用中文回复用户。'''

# 工具列表
tools = ['my_image_gen', 'code_interpreter']

定义系统指令,告诉智能体如何处理用户请求。配置了两个工具:自定义图像生成工具和内置代码执行工具。

文档加载

def get_doc_files():
    """获取文档目录下所有文件的路径列表"""
    file_dir = os.path.join('./', 'docs')
    files = []
    
    if os.path.exists(file_dir):
        for file in os.listdir(file_dir):
            file_path = os.path.join(file_dir, file)
            if os.path.isfile(file_path):
                files.append(file_path)
    
    print('加载的文件:', files)
    return files

遍历 docs 目录,获取所有文件路径,用于后续的文档检索功能。

智能体初始化

获取文档列表
创建 Assistant
配置工具和文档
返回智能体实例
def init_agent_service():
    """初始化智能体服务"""
    try:
        # 获取文档文件列表
        files = get_doc_files()
        
        # 创建 Assistant 智能体实例
        bot = Assistant(
            llm=llm_cfg,                       # 语言模型配置
            system_message=system_instruction, # 系统行为指导
            function_list=tools,               # 可用功能工具列表
            files=files                        # 要索引的文档文件
        )
        print("智能体初始化成功!")
        return bot
    except Exception as e:
        print(f"智能体初始化失败: {str(e)}")
        raise

创建 Assistant 智能体实例,传入 LLM 配置、系统提示词、可用工具和文档文件列表。

终端交互模式(TUI)

def app_tui():
    """终端交互模式"""
    try:
        bot = init_agent_service()
        messages = []
        
        while True:
            try:
                query = input('\n用户问题: ')
                
                if not query:
                    print('用户问题不能为空!')
                    continue
                    
                messages.append({'role': 'user', 'content': query})
                print("正在处理您的请求...")
                
                # 运行智能体并流式处理响应
                response = []
                current_index = 0
                
                for response in bot.run(messages=messages):
                    if current_index == 0:
                        # 尝试获取并打印召回的文档内容
                        if hasattr(bot, 'retriever') and bot.retriever:
                            print("\n===== 召回的文档内容 =====")
                            retrieved_docs = bot.retriever.retrieve(query)
                            if retrieved_docs:
                                for i, doc in enumerate(retrieved_docs):
                                    print(f"\n文档片段 {i+1}:")
                                    print(f"内容: {doc.page_content[:200]}...")
                                    print(f"元数据: {doc.metadata}")
                            else:
                                print("没有召回任何文档内容")
                            print("===========================\n")
                    
                    # 输出增量响应内容
                    current_response = response[0]['content'][current_index:]
                    current_index = len(response[0]['content'])
                    print(current_response, end='')
                
                messages.extend(response)
                print("\n")
                
            except KeyboardInterrupt:
                print("\n\n退出程序")
                break
            except Exception as e:
                print(f"处理请求时出错: {str(e)}")
                print("请重试或输入新的问题")
                
    except Exception as e:
        print(f"启动终端模式失败: {str(e)}")

提供命令行交互界面,支持连续对话、文件输入和实时响应。

图形界面模式(GUI)

def app_gui():
    """图形界面模式"""
    try:
        print("正在启动 Web 界面...")
        bot = init_agent_service()
        
        # 配置聊天界面,提供示例问题建议
        chatbot_config = {
            'prompt.suggestions': [
                '介绍下雇主责任险',
                '帮我生成一幅关于春天的图像',
                '分析一下文档中的关键信息',
            ]
        }
        
        print("Web 界面准备就绪,正在启动服务...")
        WebUI(
            bot,
            chatbot_config=chatbot_config
        ).run()
        
    except Exception as e:
        print(f"启动 Web 界面失败: {str(e)}")
        print("请检查网络连接和 API Key 配置")

启动 Web 界面,提供可视化交互体验,配置示例问题建议。

核心特点

1. 多工具集成

集成了自定义图像生成工具和内置代码执行工具,可以处理多种类型的任务。

2. 双模式交互

实现了图形界面(GUI)和终端(TUI)两种交互模式,GUI 模式提供可视化体验,TUI 模式适合命令行环境。

3. 文档检索能力

自动索引 docs 目录下的文档,支持基于文档内容的智能问答。

4. 流式响应

支持流式输出,实时显示智能体的回复内容,提升用户体验。

应用场景

这种多功能智能体适合:

  • 需要图像生成能力的创意应用
  • 需要代码执行的数据分析场景
  • 企业知识库问答系统
  • 多模态交互的智能助手
  • 教育培训辅助工具

扩展建议

可以进一步优化:

  • 添加更多自定义工具(搜索、翻译、数据库查询等)
  • 实现对话历史持久化,支持会话恢复
  • 添加用户权限管理和访问控制
  • 集成更多图像处理功能(编辑、滤镜等)
  • 添加性能监控和日志分析

标签