乐于分享
好东西不私藏

RAGFlow源码解析-12、高级特性与多模态模型深度解析(第十周)

RAGFlow源码解析-12、高级特性与多模态模型深度解析(第十周)

概述

本周深入分析 RAGFlow 的多模态能力实现,涵盖 OCR 识别、计算机视觉(CV)模型、语音转文字(ASR)三大核心模块。这些模块扩展了 RAGFlow 的文档理解能力,支持图像、视频、音频等多种数据格式的处理。

核心文件

  • rag/llm/ocr_model.py
     - OCR 模型集成(MinerU、PaddleOCR)
  • rag/llm/cv_model.py
     - 计算机视觉模型(25+ 视觉大模型)
  • rag/llm/sequence2txt_model.py
     - 语音转文字模型(12+ ASR 服务)

一、OCR 模型架构

1.1 OCR 模型层次结构

1.2 Base 基类设计

源码位置rag/llm/ocr_model.py:25-30

class Base:    def __init__(self, key: str | dict, model_name: str, **kwargs):        self.model_name = model_name    def parse_pdf(self, filepath: str, binary=None, **kwargs) -> tuple[AnyAny]:        raise NotImplementedError("Please implement parse_pdf!")

设计模式: 模板方法模式,定义 OCR 模型的标准接口。

1.3 MinerU OCR 实现

源码位置rag/llm/ocr_model.py:33-94

class MinerUOcrModel(Base, MinerUParser):    _FACTORY_NAME = "MinerU"    def __init__(self, key: str | dict, model_name: str, **kwargs):        Base.__init__(self, key, model_name, **kwargs)        raw_config = {}        if key:            try:                raw_config = json.loads(key)            except Exception:                raw_config = {}        # 嵌套配置结构处理        config = raw_config.get("api_key", raw_config)        if not isinstance(config, dict):            config = {}        def _resolve_config(key: str, env_key: str, default=""):            # 优先级: UI配置 > 环境变量 > 默认值            return config.get(key, config.get(env_key, os.environ.get(env_key, default)))        # 核心配置参数        self.mineru_api = _resolve_config("mineru_apiserver""MINERU_APISERVER""")        self.mineru_output_dir = _resolve_config("mineru_output_dir""MINERU_OUTPUT_DIR""")        self.mineru_backend = _resolve_config("mineru_backend""MINERU_BACKEND""pipeline")        self.mineru_server_url = _resolve_config("mineru_server_url""MINERU_SERVER_URL""")        self.mineru_delete_output = bool(int(_resolve_config("mineru_delete_output""MINERU_DELETE_OUTPUT"1)))        # 敏感信息脱敏日志        redacted_config = {}        for k, v in config.items():            if any(sensitive_word in k.lower() for sensitive_word in ("key""password""token""secret")):                redacted_config[k] = "[REDACTED]"            else:                redacted_config[k] = v        logging.info(f"Parsed MinerU config (sensitive fields redacted): {redacted_config}")        MinerUParser.__init__(self, mineru_api=self.mineru_api, mineru_server_url=self.mineru_server_url)    def check_available(self, backend: Optional[str] = None, server_url: Optional[str] = None) -> tuple[boolstr]:        backend = backend or self.mineru_backend        server_url = server_url or self.mineru_server_url        return self.check_installation(backend=backend, server_url=server_url)    def parse_pdf(self, filepath: str, binary=None, callback=None, parse_method: str = "raw", **kwargs):        ok, reason = self.check_available()        if not ok:            raise RuntimeError(f"MinerU server not accessible: {reason}")        sections, tables = MinerUParser.parse_pdf(            self,            filepath=filepath,            binary=binary,            callback=callback,            output_dir=self.mineru_output_dir,            backend=self.mineru_backend,            server_url=self.mineru_server_url,            delete_output=self.mineru_delete_output,            parse_method=parse_method,            **kwargs,        )        return sections, tables

配置解析策略:

1.4 PaddleOCR 实现

源码位置rag/llm/ocr_model.py:97-148

class PaddleOCROcrModel(Base, PaddleOCRParser):    _FACTORY_NAME = "PaddleOCR"    def __init__(self, key: str | dict, model_name: str, **kwargs):        Base.__init__(self, key, model_name, **kwargs)        raw_config = {}        if key:            try:                raw_config = json.loads(key)            except Exception:                raw_config = {}        config = raw_config.get("api_key", raw_config)        if not isinstance(config, dict):            config = {}        def _resolve_config(key: str, env_key: str, default=""):            return config.get(key, config.get(env_key, os.environ.get(env_key, default)))        self.paddleocr_api_url = _resolve_config("paddleocr_api_url""PADDLEOCR_API_URL""")        self.paddleocr_algorithm = _resolve_config("paddleocr_algorithm""PADDLEOCR_ALGORITHM""PaddleOCR-VL")        self.paddleocr_access_token = _resolve_config("paddleocr_access_token""PADDLEOCR_ACCESS_TOKEN"None)        # 敏感信息脱敏        redacted_config = {}        for k, v in config.items():            if any(sensitive_word in k.lower() for sensitive_word in ("key""password""token""secret")):                redacted_config[k] = "[REDACTED]"            else:                redacted_config[k] = v        logging.info(f"Parsed PaddleOCR config (sensitive fields redacted): {redacted_config}")        PaddleOCRParser.__init__(            self,            api_url=self.paddleocr_api_url,            access_token=self.paddleocr_access_token,            algorithm=self.paddleocr_algorithm,        )    def check_available(self) -> tuple[boolstr]:        return self.check_installation()    def parse_pdf(self, filepath: str, binary=None, callback=None, parse_method: str = "raw", **kwargs):        ok, reason = self.check_available()        if not ok:            raise RuntimeError(f"PaddleOCR server not accessible: {reason}")        sections, tables = PaddleOCRParser.parse_pdf(            self, filepath=filepath, binary=binary, callback=callback, parse_method=parse_method, **kwargs        )        return sections, tables

OCR 模型对比:

特性
MinerU
PaddleOCR
后端支持
pipeline/server
API服务
部署方式
本地/远程服务
远程API
配置复杂度
高(多种backend)
中(API URL + Token)
适用场景
大规模文档处理
快速集成

二、计算机视觉(CV)模型架构

2.1 CV 模型继承体系

2.2 Base 基类核心实现

源码位置rag/llm/cv_model.py:42-187

图像编码方法

@staticmethoddef image2base64(image):    """将图像转换为 data URL 格式的 base64 字符串"""    if isinstance(image, bytes):        # 根据魔数判断 MIME 类型        mime = "image/png"        if len(image) >= 2 and image[0] == 0xFF and image[1] == 0xD8:            mime = "image/jpeg"        b64 = base64.b64encode(image).decode("utf-8")        return f"data:{mime};base64,{b64}"    if isinstance(image, BytesIO):        data = image.getvalue()        mime = "image/png"        if len(data) >= 2 and data[0] == 0xFF and data[1] == 0xD8:            mime = "image/jpeg"        b64 = base64.b64encode(data).decode("utf-8")        return f"data:{mime};base64,{b64}"    # PIL Image 对象    with BytesIO() as buffered:        fmt = "jpeg"        try:            image.save(buffered, format="JPEG")        except Exception:            buffered.seek(0)            buffered.truncate()            image.save(buffered, format="PNG")            fmt = "png"        data = buffered.getvalue()        b64 = base64.b64encode(data).decode("utf-8")        mime = f"image/{fmt}"    return f"data:{mime};base64,{b64}"

魔数识别:

魔数
格式
0xFF 0xD8
JPEG
0x89 0x50
PNG
0x47 0x49
GIF

图像提示词构建

def _image_prompt(self, text, images):    """构建多模态消息内容"""    if not images:        return text    if isinstance(images, stror "bytes" in type(images).__name__:        images = [images]    pmpt = [{"type""text""text": text}]    for img in images:        pmpt.append({            "type""image_url",            "image_url": {                "url": img if isinstance(img, strand img.startswith("data:"                       else f"data:image/png;base64,{img}"            }        })    return pmpt

2.3 GptV4 实现详解

源码位置rag/llm/cv_model.py:189-218

class GptV4(Base):    _FACTORY_NAME = "OpenAI"    def __init__(self, key, model_name="gpt-4-vision-preview", lang="Chinese", base_url="https://api.openai.com/v1", **kwargs):        if not base_url:            base_url = "https://api.openai.com/v1"        self.api_key = key        self.client = OpenAI(api_key=key, base_url=base_url)        self.async_client = AsyncOpenAI(api_key=key, base_url=base_url)        self.model_name = model_name        self.lang = lang        super().__init__(**kwargs)    def describe(self, image):        """自动生成图像描述"""        b64 = self.image2base64(image)        res = self.client.chat.completions.create(            model=self.model_name,            messages=self.prompt(b64),            extra_body=self.extra_body        )        return res.choices[0].message.content.strip(), total_token_count_from_response(res)    def describe_with_prompt(self, image, prompt=None):        """使用自定义提示词描述图像"""        b64 = self.image2base64(image)        res = self.client.chat.completions.create(            model=self.model_name,            messages=self.vision_llm_prompt(b64, prompt),            extra_body=self.extra_body,        )        return res.choices[0].message.content.strip(), total_token_count_from_response(res)

2.4 QWenCV 视频处理

源码位置rag/llm/cv_model.py:251-305

async def async_chat(self, system, history, gen_conf, images=None, video_bytes=None, filename="", **kwargs):    if video_bytes:        try:            summary, summary_num_tokens = self._process_video(video_bytes, filename)            return summary, summary_num_tokens        except Exception as e:            return "**ERROR**: " + str(e), 0    return "**ERROR**: Method chat not supported yet."0def _process_video(self, video_bytes, filename):    from dashscope import MultiModalConversation    video_suffix = Path(filename).suffix or ".mp4"    with tempfile.NamedTemporaryFile(delete=False, suffix=video_suffix) as tmp:        tmp.write(video_bytes)        tmp_path = tmp.name        video_path = f"file://{tmp_path}"        messages = [            {                "role""user",                "content": [                    {"video": video_path, "fps"2},                    {"text""Please summarize this video in proper sentences."},                ],            }        ]        def call_api():            response = MultiModalConversation.call(                api_key=self.api_key,                model=self.model_name,                messages=messages,            )            if response.get("message"):                raise Exception(response["message"])            summary = response["output"]["choices"][0]["message"].content[0]["text"]            return summary, num_tokens_from_string(summary)        try:            return call_api()        except Exception as e1:            # 切换到国际端点重试            import dashscope            dashscope.base_http_api_url = "https://dashscope-intl.aliyuncs.com/api/v1"            try:                return call_api()            except Exception as e2:                raise RuntimeError(f"Both default and intl endpoint failed.\nFirst error: {e1}\nSecond error: {e2}")

2.5 GeminiCV 实现详解

源码位置rag/llm/cv_model.py:675-896

class GeminiCV(Base):    _FACTORY_NAME = "Gemini"    def __init__(self, key, model_name="gemini-1.0-pro-vision-latest", lang="Chinese", **kwargs):        from google import genai        self.api_key = key        self.model_name = model_name        self.client = genai.Client(api_key=key)        self.lang = lang        Base.__init__(self, **kwargs)        logging.info(f"[GeminiCV] Initialized with model={self.model_name} lang={self.lang}")    def _image_to_part(self, image):        """将图像转换为 Gemini Part 对象"""        from google.genai import types        if isinstance(image, strand image.startswith("data:"and ";base64," in image:            header, b64data = image.split(","1)            mime = header.split(":"1)[1].split(";"1)[0]            data = base64.b64decode(b64data)        else:            data_url = self.image2base64(image)            header, b64data = data_url.split(","1)            mime = header.split(":"1)[1].split(";"1)[0]            data = base64.b64decode(b64data)        return types.Part(            inline_data=types.Blob(                mime_type=mime,                data=data,            )        )    def _process_video(self, video_bytes, filename):        """处理视频文件"""        from google import genai        from google.genai import types        video_size_mb = len(video_bytes) / (1024 * 1024)        client = self.client if hasattr(self"client"else genai.Client(api_key=self.api_key)        logging.info(f"[GeminiCV] _process_video called: filename={filename} size_mb={video_size_mb:.2f}")        tmp_path = None        try:            if video_size_mb <= 20:                # 小文件直接内联处理                response = client.models.generate_content(                    model="models/gemini-2.5-flash",                    contents=types.Content(parts=[                        types.Part(inline_data=types.Blob(data=video_bytes, mime_type="video/mp4")),                        types.Part(text="Please summarize the video in proper sentences.")                    ]),                )            else:                # 大文件使用 Files API                logging.info(f"Video size {video_size_mb:.2f}MB exceeds 20MB. Using Files API...")                video_suffix = Path(filename).suffix or ".mp4"                with tempfile.NamedTemporaryFile(delete=False, suffix=video_suffix) as tmp:                    tmp.write(video_bytes)                    tmp_path = Path(tmp.name)                uploaded_file = client.files.upload(file=tmp_path)                response = client.models.generate_content(                    model="gemini-2.5-flash",                    contents=[uploaded_file, "Please summarize this video in proper sentences."]                )            summary = response.text or ""            logging.info(f"[GeminiCV] Video summarized: {summary[:32]}...")            return summary, num_tokens_from_string(summary)        except Exception as e:            logging.warning(f"[GeminiCV] Video processing failed: {e}")            raise        finally:            if tmp_path and tmp_path.exists():                tmp_path.unlink()

视频处理策略:

视频大小
处理方式
优势
≤ 20MB
内联传输
快速、无额外IO
> 20MB
Files API
支持大文件、流式上传

2.6 AnthropicCV 实现

源码位置rag/llm/cv_model.py:977-1081

class AnthropicCV(Base):    _FACTORY_NAME = "Anthropic"    def __init__(self, key, model_name, base_url=None, **kwargs):        import anthropic        self.client = anthropic.Anthropic(api_key=key)        self.async_client = anthropic.AsyncAnthropic(api_key=key)        self.model_name = model_name        self.system = ""        self.max_tokens = 8192        if "haiku" in self.model_name or "opus" in self.model_name:            self.max_tokens = 4096        Base.__init__(self, **kwargs)    def _image_prompt(self, text, images):        """Anthropic 图像格式"""        if not images:            return text        pmpt = [{"type""text""text": text}]        for img in images:            pmpt.append({                "type""image",                "source": {                    "type""base64",                    "media_type": (img.split(":")[1].split(";")[0if isinstance(img, strand img[:4] == "data" else "image/png"),                    "data": (img.split(",")[1if isinstance(img, strand img[:4] == "data" else img),                },            })        return pmpt    async def async_chat_streamly(self, system, history, gen_conf, images=None, **kwargs):        gen_conf = self._clean_conf(gen_conf)        total_tokens = 0        try:            response = self.async_client.messages.create(                model=self.model_name,                messages=self._form_history(system, history, images),                system=system,                stream=True,                **gen_conf,            )            think = False            async for res in response:                if res.type == "content_block_delta":                    if res.delta.type == "thinking_delta" and res.delta.thinking:                        if not think:                            yield "SEMBED"                            think = True                        yield res.delta.thinking                        total_tokens += num_tokens_from_string(res.delta.thinking)                    elif think:                        yield "DECREF"                    else:                        yield res.delta.text                        total_tokens += num_tokens_from_string(res.delta.text)        except Exception as e:            yield "\n**ERROR**: " + str(e)        yield total_tokens

扩展思考支持: AnthropicCV 支持 Claude 的扩展思考(extended thinking)功能,在流式输出中标记思考过程。

2.7 CV 模型提供商汇总

提供商特性对比:

提供商
视频支持
流式输出
特殊功能
OpenAI
-
Azure
企业认证
Anthropic
扩展思考
Gemini
Files API
通义千问
视频摘要
智谱
国产优化
Ollama
本地部署

三、语音转文字(ASR)模型架构

3.1 Sequence2txt 模型层次

3.2 Base 基类实现

源码位置rag/llm/sequence2txt_model.py:31-49

class Base(ABC):    def __init__(self, key, model_name, **kwargs):        """抽象基类构造器"""        pass    def transcription(self, audio_path, **kwargs):        """语音转文字核心方法"""        audio_file = open(audio_path, "rb")        transcription = self.client.audio.transcriptions.create(            model=self.model_name,             file=audio_file        )        return transcription.text.strip(), num_tokens_from_string(transcription.text.strip())    def audio2base64(self, audio):        """音频转 base64"""        if isinstance(audio, bytes):            return base64.b64encode(audio).decode("utf-8")        if isinstance(audio, io.BytesIO):            return base64.b64encode(audio.getvalue()).decode("utf-8")        raise TypeError("The input audio file should be in binary format.")

3.3 OpenAI Whisper 实现

源码位置rag/llm/sequence2txt_model.py:52-60

class GPTSeq2txt(Base):    _FACTORY_NAME = "OpenAI"    def __init__(self, key, model_name="whisper-1", base_url="https://api.openai.com/v1", **kwargs):        if not base_url:            base_url = "https://api.openai.com/v1"        self.client = OpenAI(api_key=key, base_url=base_url)        self.model_name = model_name

3.4 通义千问 ASR 实现

源码位置rag/llm/sequence2txt_model.py:71-154

class QWenSeq2txt(Base):    _FACTORY_NAME = "Tongyi-Qianwen"    def __init__(self, key, model_name="qwen-audio-asr", **kwargs):        import dashscope        dashscope.api_key = key        self.model_name = model_name    def transcription(self, audio_path):        import dashscope        if audio_path.startswith("http"):            audio_input = audio_path        else:            audio_input = f"file://{audio_path}"        messages = [            {"role""system""content": [{"text"""}]},            {"role""user""content": [{"audio": audio_input}]}        ]        resp = dashscope.MultiModalConversation.call(            model=self.model_name,            messages=messages,            result_format="message",            asr_options={                "enable_lid"True,  # 语言识别                "enable_itn"False  # 逆文本标准化            }        )        try:            text = resp["output"]["choices"][0]["message"].content[0]["text"]        except Exception as e:            text = "**ERROR**: " + str(e)        return text, num_tokens_from_string(text)    def stream_transcription(self, audio_path):        """流式语音识别"""        import dashscope        if audio_path.startswith("http"):            audio_input = audio_path        else:            audio_input = f"file://{audio_path}"        messages = [            {"role""system""content": [{"text"""}]},            {"role""user""content": [{"audio": audio_input}]}        ]        stream = dashscope.MultiModalConversation.call(            model=self.model_name,            messages=messages,            result_format="message",            stream=True,            asr_options={                "enable_lid"True,                "enable_itn"False            }        )        full = ""        for chunk in stream:            try:                piece = chunk["output"]["choices"][0]["message"].content[0]["text"]                full = piece                yield {"event""delta""text": piece}            except Exception as e:                yield {"event""error""text"str(e)}        yield {"event""final""text": full}

ASR 选项说明:

选项
说明
默认值
enable_lid
语言识别(自动检测语言)
True
enable_itn
逆文本标准化(数字、日期转换)
False

3.5 腾讯云 ASR 实现

源码位置rag/llm/sequence2txt_model.py:201-260

class TencentCloudSeq2txt(Base):    _FACTORY_NAME = "Tencent Cloud"    def __init__(self, key, model_name="16k_zh", base_url="https://asr.tencentcloudapi.com"):        from tencentcloud.asr.v20190614 import asr_client        from tencentcloud.common import credential        key = json.loads(key)        sid = key.get("tencent_cloud_sid""")        sk = key.get("tencent_cloud_sk""")        cred = credential.Credential(sid, sk)        self.client = asr_client.AsrClient(cred, "")        self.model_name = model_name    def transcription(self, audio, max_retries=60, retry_interval=5):        import time        from tencentcloud.asr.v20190614 import models        from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException        b64 = self.audio2base64(audio)        try:            # 1. 提交识别任务            req = models.CreateRecTaskRequest()            params = {                "EngineModelType"self.model_name,                "ChannelNum"1,                "ResTextFormat"0,                "SourceType"1,                "Data": b64,            }            req.from_json_string(json.dumps(params))            resp = self.client.CreateRecTask(req)            # 2. 轮询查询结果            req = models.DescribeTaskStatusRequest()            params = {"TaskId": resp.Data.TaskId}            req.from_json_string(json.dumps(params))            retries = 0            while retries < max_retries:                resp = self.client.DescribeTaskStatus(req)                if resp.Data.StatusStr == "success":                    # 移除时间戳标记 [00:00.000,00:05.000]                    text = re.sub(r"\[\d+:\d+\.\d+,\d+:\d+\.\d+\]\s*""", resp.Data.Result).strip()                    return text, num_tokens_from_string(text)                elif resp.Data.StatusStr == "failed":                    return "**ERROR**: Failed to retrieve speech recognition results."0                else:                    time.sleep(retry_interval)                    retries += 1            return "**ERROR**: Max retries exceeded. Task may still be processing."0        except TencentCloudSDKException as e:            return "**ERROR**: " + str(e), 0

异步识别流程:

3.6 智谱 ASR 实现

源码位置rag/llm/sequence2txt_model.py:317-378

class ZhipuSeq2txt(Base):    _FACTORY_NAME = "ZHIPU-AI"    def __init__(self, key, model_name="glm-asr", base_url="https://open.bigmodel.cn/api/paas/v4", **kwargs):        if not base_url:            base_url = "https://open.bigmodel.cn/api/paas/v4"        self.base_url = base_url        self.api_key = key        self.model_name = model_name        self.gen_conf = kwargs.get("gen_conf", {})        self.stream = kwargs.get("stream"False)    def _convert_to_wav(self, input_path):        """音频格式转换"""        ext = os.path.splitext(input_path)[1].lower()        if ext in [".wav"".mp3"]:            return input_path        fd, out_path = tempfile.mkstemp(suffix=".wav")        os.close(fd)        try:            import ffmpeg            import imageio_ffmpeg as ffmpeg_exe            ffmpeg_path = ffmpeg_exe.get_ffmpeg_exe()            (                ffmpeg                .input(input_path)                .output(out_path, ar=16000, ac=1)  # 16kHz, 单声道                .overwrite_output()                .run(cmd=ffmpeg_path, quiet=True)            )            return out_path        except Exception as e:            raise RuntimeError(f"audio convert failed: {e}")    def transcription(self, audio_path):        payload = {            "model"self.model_name,            "temperature"str(self.gen_conf.get("temperature"0.75)) or "0.75",            "stream"self.stream,        }        headers = {"Authorization"f"Bearer {self.api_key}"}        converted = self._convert_to_wav(audio_path)        with open(converted, "rb"as audio_file:            files = {"file": audio_file}            try:                response = requests.post(                    url=f"{self.base_url}/audio/transcriptions",                    data=payload,                    files=files,                    headers=headers,                )                body = response.json()                if response.status_code == 200:                    full_content = body["text"]                    return full_content, num_tokens_from_string(full_content)                else:                    error = body["error"]                    return f"**ERROR**: code: {error['code']}, message: {error['message']}"0            except Exception as e:                return "**ERROR**: " + str(e), 0

音频格式转换:

输入格式
转换后
参数
WAV
不转换
-
MP3
不转换
-
其他
WAV
16kHz, 单声道

3.7 ASR 提供商汇总


四、设计模式总结

4.1 策略模式

OCR/CV/ASR 模型采用策略模式,通过统一的接口支持多种实现:

# 统一接口class Base:    def describe(self, image): ...    def transcription(self, audio_path): ...    def parse_pdf(self, filepath): ...# 不同策略实现class GptV4(Base): ...class GeminiCV(Base): ...class OllamaCV(Base): ...

4.2 工厂模式

每个模型类通过 _FACTORY_NAME 标识,支持动态实例化:

classGptV4(Base):    _FACTORY_NAME = "OpenAI"classGeminiCV(Base):    _FACTORY_NAME = "Gemini"# 根据工厂名称创建实例MODEL_MAP = {    "OpenAI": GptV4,    "Gemini": GeminiCV,    ...}model = MODEL_MAP[factory_name](key, model_name, **kwargs)

4.3 适配器模式

不同 API 提供商的响应格式通过适配器统一:

# OpenAI 格式return res.choices[0].message.content.strip(), total_token_count_from_response(res)# Anthropic 格式return response["content"][0]["text"].strip(), response["usage"]["input_tokens"] + response["usage"]["output_tokens"]# Gemini 格式return res.text, total_token_count_from_response(res)

五、错误处理与重试机制

5.1 配置化重试参数

class Base(ABC):    def __init__(self, **kwargs):        # 配置重试参数        self.max_retries = kwargs.get("max_retries"int(os.environ.get("LLM_MAX_RETRIES"5)))        self.base_delay = kwargs.get("retry_interval"float(os.environ.get("LLM_BASE_DELAY"2.0)))        self.max_rounds = kwargs.get("max_rounds"5)

5.2 多端点故障转移

def _process_video(self, video_bytes, filename):    try:        return call_api()  # 默认端点    except Exception as e1:        # 切换到备用端点        dashscope.base_http_api_url = "https://dashscope-intl.aliyuncs.com/api/v1"        try:            return call_api()        except Exception as e2:            raise RuntimeError(f"Both default and intl endpoint failed.\nFirst error: {e1}\nSecond error: {e2}")

5.3 敏感信息脱敏

# 日志输出前脱敏redacted_config = {}for k, v in config.items():    if any(sensitive_word in k.lower() for sensitive_word in ("key""password""token""secret")):        redacted_config[k] = "[REDACTED]"    else:        redacted_config[k] = vlogging.info(f"Parsed config (sensitive fields redacted): {redacted_config}")

六、性能优化策略

6.1 视频处理优化

策略
实现
适用场景
内联传输
直接传输字节
小文件(<20MB)
Files API
先上传后处理
大文件(>20MB)
临时文件
tempfile模块
本地处理

6.2 异步处理

# 同步客户端self.client = OpenAI(api_key=key, base_url=base_url)# 异步客户端self.async_client = AsyncOpenAI(api_key=key, base_url=base_url)# 异步方法async def async_chat(self, system, history, gen_conf, images=None, **kwargs):    response = await self.async_client.chat.completions.create(...)    return response.choices[0].message.content.strip(), total_token_count_from_response(response)

6.3 流式输出

async def async_chat_streamly(self, system, history, gen_conf, images=None, **kwargs):    response = await self.async_client.chat.completions.create(        model=self.model_name,        messages=self._form_history(system, history, images),        stream=True,        extra_body=self.extra_body,    )    async for resp in response:        if not resp.choices[0].delta.content:            continue        delta = resp.choices[0].delta.content        ans = delta        yield ans

七、总结

RAGFlow 的多模态模型架构体现了以下核心设计原则:

  1. 可扩展性
    : 支持 25+ CV 模型、12+ ASR 服务、2+ OCR 引擎
  2. 统一接口
    : Base 基类定义标准 API,子类实现特定逻辑
  3. 配置灵活
    : 支持环境变量、JSON配置、参数传递多种方式
  4. 错误容错
    : 多端点故障转移、敏感信息脱敏、详细日志记录
  5. 性能优化
    : 异步处理、流式输出、大文件特殊处理

这种架构设计使 RAGFlow 能够灵活应对各种多模态数据处理需求,为 RAG 应用提供了强大的文档理解能力。

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-06-06 12:16:36 HTTP/1.1 GET : https://www.yeyulingfeng.com/a/717505.html
  2. 运行时间 : 0.228279s [ 吞吐率:4.38req/s ] 内存消耗:4,828.86kb 文件加载:145
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=d9f003567a16899564c1a758a2053697
  1. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_static.php ( 6.05 KB )
  7. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/ralouphie/getallheaders/src/getallheaders.php ( 1.60 KB )
  10. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  11. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  12. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  13. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  14. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  15. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  16. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  17. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  18. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  19. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions_include.php ( 0.16 KB )
  21. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions.php ( 5.54 KB )
  22. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  23. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  24. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  25. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/provider.php ( 0.19 KB )
  26. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  27. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  28. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  29. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/common.php ( 0.03 KB )
  30. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  32. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/alipay.php ( 3.59 KB )
  33. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  34. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/app.php ( 0.95 KB )
  35. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cache.php ( 0.78 KB )
  36. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/console.php ( 0.23 KB )
  37. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cookie.php ( 0.56 KB )
  38. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/database.php ( 2.48 KB )
  39. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/filesystem.php ( 0.61 KB )
  40. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/lang.php ( 0.91 KB )
  41. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/log.php ( 1.35 KB )
  42. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/middleware.php ( 0.19 KB )
  43. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/route.php ( 1.89 KB )
  44. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/session.php ( 0.57 KB )
  45. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/trace.php ( 0.34 KB )
  46. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/view.php ( 0.82 KB )
  47. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/event.php ( 0.25 KB )
  48. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  49. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/service.php ( 0.13 KB )
  50. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/AppService.php ( 0.26 KB )
  51. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  52. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  53. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  54. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  55. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  56. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/services.php ( 0.14 KB )
  57. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  58. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  59. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  60. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  61. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  62. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  63. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  64. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  65. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  66. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  67. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  68. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  69. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  70. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  71. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  72. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  73. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  74. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  75. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  76. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  77. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  78. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  79. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  80. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  81. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  82. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  83. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  84. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  85. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  86. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  87. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/Request.php ( 0.09 KB )
  88. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  89. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/middleware.php ( 0.25 KB )
  90. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  91. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  92. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  93. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  94. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  95. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  96. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  97. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  98. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  99. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  100. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  101. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  102. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  103. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/route/app.php ( 3.94 KB )
  104. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  105. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  106. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Index.php ( 9.87 KB )
  108. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/BaseController.php ( 2.05 KB )
  109. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  110. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  111. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  112. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  113. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  114. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  115. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  116. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  117. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  118. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  119. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  120. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  121. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  122. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  123. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  124. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  125. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  126. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  127. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  128. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  129. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  130. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  131. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  132. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  133. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  134. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  135. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Es.php ( 3.30 KB )
  136. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  137. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  138. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  139. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  140. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  141. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  142. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  143. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  144. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/runtime/temp/c935550e3e8a3a4c27dd94e439343fdf.php ( 31.50 KB )
  145. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000874s ] mysql:host=127.0.0.1;port=3306;dbname=wenku;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000680s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000284s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000311s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000519s ]
  6. SELECT * FROM `set` [ RunTime:0.000172s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000685s ]
  8. SELECT * FROM `article` WHERE `id` = 717505 LIMIT 1 [ RunTime:0.002511s ]
  9. UPDATE `article` SET `lasttime` = 1780719396 WHERE `id` = 717505 [ RunTime:0.003943s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.000254s ]
  11. SELECT * FROM `article` WHERE `id` < 717505 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000429s ]
  12. SELECT * FROM `article` WHERE `id` > 717505 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000552s ]
  13. SELECT * FROM `article` WHERE `id` < 717505 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.002609s ]
  14. SELECT * FROM `article` WHERE `id` < 717505 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.000661s ]
  15. SELECT * FROM `article` WHERE `id` < 717505 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.000858s ]
0.232309s