# LLM 处理器模块技术文档 ```markdown # LLM 处理器模块(`llm_processor.py`) 本模块实现了基于 `BaseProcessor` 的三种不同模式的 LLM(大语言模型)请求处理器,支持流式、同步和异步调用方式。通过模板引擎动态生成请求配置,并结合 `LlmProxy` 系列代理类实现与 LLM 服务的交互。 --- ## 模块依赖 ```python import aiohttp from aiohttp import web, BasicAuth from aiohttp import client from appPublic.dictObject import DictObject from .llm_client import StreamLlmProxy, AsyncLlmProxy, SyncLlmProxy from .baseProcessor import * ``` ### 依赖说明: - **`aiohttp`**:用于构建异步 Web 服务及发起 HTTP 客户端请求。 - **`web` / `BasicAuth` / `client`**:AIOHTTP 的核心组件,分别用于 Web 路由、认证和客户端操作。 - **`DictObject`**:来自 `appPublic.dictObject` 的字典封装类,将字典转换为可属性访问的对象。 - **`StreamLlmProxy`, `AsyncLlmProxy`, `SyncLlmProxy`**:LLM 请求代理类,分别处理流式、异步和同步响应。 - **`BaseProcessor`**:所有处理器继承的基础类,提供通用运行环境设置和资源管理能力。 --- ## 核心类概述 | 类名 | 功能描述 | |-------------------|--------| | `LlmProcessor` | 流式 LLM 请求处理器,适用于需要实时返回生成内容的场景(如聊天流)。 | | `LlmSProcessor` | 同步式 LLM 请求处理器,等待完整响应后一次性返回结果。 | | `LlmAProcessor` | 异步非阻塞式 LLM 请求处理器,适用于后台任务或延迟响应场景。 | --- ## 公共方法详解 ### `@classmethod isMe(self, name)` 判断当前处理器是否匹配指定名称。 #### 参数: - `name` (str): 请求路径中标识处理器类型的名称。 #### 返回值: - `bool`: 若 `name` 匹配该处理器类型则返回 `True`。 > 所有子类均通过此方法注册自身处理器类型(`llm`, `llms`, `llma`)。 --- ### `async path_call(self, request, params={})` 从模板 URL 加载并渲染配置数据,解析为结构化对象。 #### 参数: - `request` (`aiohttp.web.Request`):当前 HTTP 请求对象。 - `params` (dict, optional):额外传入的参数,用于模板渲染上下文。 #### 流程: 1. 设置运行环境(`set_run_env`) 2. 构造完整请求路径 URL 3. 获取运行命名空间 `run_ns` 4. 更新命名空间中的参数 5. 使用模板引擎(`tmpl_engine`)渲染远程模板内容 6. 解析 JSON 字符串为 `DictObject` #### 返回值: - `DictObject`:包含 LLM 配置信息的对象,如模型地址、参数、提示词等。 #### 示例输出结构(假设模板返回): ```json { "model": "gpt-4", "prompt": "你好,请介绍一下你自己。", "temperature": 0.7, "max_tokens": 1024 } ``` --- ### `setheaders(self)` 占位方法,用于后续扩展自定义响应头设置。 > 当前为空实现(`pass`),可根据需求重写以添加 CORS、Content-Type 或其他头部字段。 --- ## 各处理器类详细说明 ### 1. `LlmProcessor` —— 流式处理器 #### 处理器标识: ```python @classmethod def isMe(cls, name): return name == 'llm' ``` #### 方法:`async datahandle(request)` 执行流式 LLM 请求处理: ##### 步骤: 1. 调用 `path_call()` 获取配置对象 `d` 2. 创建 `StreamLlmProxy(self, d)` 实例 3. 发起流式请求:`await llm(request, self.run_ns.params_kw)` 4. 结果存入 `self.retResponse`(通常是一个 `StreamingResponse` 对象) ##### 特点: - 支持逐块传输(chunked transfer),适合前端实时显示文本生成过程。 - 响应体不会被完全缓存,内存占用低。 --- ### 2. `LlmSProcessor` —— 同步处理器 #### 处理器标识: ```python @classmethod def isMe(cls, name): return name == 'llms' ``` #### 方法:`async datahandle(request)` 执行同步式 LLM 请求处理: ##### 步骤: 1. 调用 `path_call()` 获取配置对象 `d` 2. 创建 `SyncLlmProxy(self, d)` 实例 3. 发起同步请求并等待完整响应:`await llm(...)` 4. 结果存入 `self.content`(字符串或字典形式的结果) ##### 特点: - 必须等待整个响应完成才返回。 - 适合对延迟不敏感但需获取完整结果的接口(如摘要生成、问答等)。 --- ### 3. `LlmAProcessor` —— 异步处理器 #### 处理器标识: ```python @classmethod def isMe(cls, name): return name == 'llma' ``` #### 方法:`async datahandle(request)` 执行异步非阻塞式 LLM 请求处理: ##### 步骤: 1. 调用 `path_call()` 获取配置对象 `d` 2. 创建 `AsyncLlmProxy(self, d)` 实例 3. 发起异步请求并获取响应:`await llm(...)` 4. 结果存入 `self.retResponse` ##### 特点: - 可配合回调机制或消息队列使用。 - 不立即返回结果,常用于任务提交型 API。 --- ## 设计模式与架构思想 ### 分层设计 - **路由识别层**:通过 `isMe()` 判断处理器类型。 - **配置加载层**:统一使用 `path_call()` 渲染模板获取 LLM 配置。 - **执行代理层**:解耦具体调用逻辑至 `LlmProxy` 系列类。 - **响应处理层**:根据模式决定如何构造最终响应。 ### 模板驱动配置 所有 LLM 请求参数均由外部模板文件控制,支持动态变量注入(如用户输入、会话状态等),提升灵活性与安全性。 ### 异步 I/O 支持 全栈异步设计,充分利用 `aiohttp` 和 `async/await` 特性,支持高并发场景下的高效处理。 --- ## 使用示例 假设存在以下模板 URL:`/templates/llm/chat.json.tmpl` ```jinja2 { "model": "qwen", "prompt": "用户: {{ query }}\\n助手:", "temperature": 0.8, "max_tokens": 512 } ``` 当访问 `/llm/chat` 时: - `LlmProcessor` 将启动流式对话; - `LlmSProcessor` 将返回完整回答; - `LlmAProcessor` 将异步提交任务并可能返回任务 ID。 --- ## 注意事项 1. **模板安全**:确保模板引擎对恶意输入进行过滤,防止 SSTI(服务器端模板注入)攻击。 2. **错误处理**:建议在 `datahandle` 中增加异常捕获逻辑,避免服务崩溃。 3. **性能调优**:`chunk_size = 40960` 可根据网络状况调整。 4. **认证支持**:可通过重写 `setheaders` 或扩展 `BaseProcessor` 添加身份验证逻辑。 --- ## 待优化建议 - 增加日志记录功能(如请求 ID、耗时统计)。 - 提供默认 `setheaders` 实现(如设置 `Content-Type: application/json`)。 - 支持更多 LLM 协议(OpenAI、Anthropic、Ollama 等)。 - 添加中间件支持(限流、缓存、审计等)。 --- ``` > 📝 **文档版本**:v1.0 > 💡 **维护团队**:应用平台组 > 🕒 **最后更新**:2025年4月5日