乐于分享
好东西不私藏

RAGFlow源码解析-8、LLM集成与对话系统深度解析(第六周)

RAGFlow源码解析-8、LLM集成与对话系统深度解析(第六周)

一、LLM Base抽象基类设计

1.1 Base类初始化与配置

源码位置rag/llm/chat_model.py:63-76

class Base(ABC):    def __init__(self, key, model_name, base_url, **kwargs):        # 第65行:从环境变量读取超时时间(默认600秒)        timeout = int(os.environ.get("LLM_TIMEOUT_SECONDS"600))        # 第66-67行:创建同步和异步OpenAI客户端        self.client = OpenAI(api_key=key, base_url=base_url, timeout=timeout)        self.async_client = AsyncOpenAI(api_key=key, base_url=base_url, timeout=timeout)        self.model_name = model_name        # 第69-71行:配置重试参数        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)  # 工具调用最大轮数        # 第73-75行:工具调用配置        self.is_tools = False        self.tools = []        self.toolcall_sessions = {}

配置参数表

参数名
默认值
环境变量
说明
timeout
600秒
LLM_TIMEOUT_SECONDS
HTTP请求超时时间
max_retries
5
LLM_MAX_RETRIES
最大重试次数
base_delay
2.0秒
LLM_BASE_DELAY
重试基础延迟
max_rounds
5
-
工具调用最大轮数

LLM客户端初始化流程图


1.2 错误分类机制

源码位置rag/llm/chat_model.py:80-99

def _classify_error(self, error):    error_str = str(error).lower()  # 第81行:转小写便于匹配    # 第83-94行:关键词到错误码映射表    keywords_mapping = [        (["quota""capacity""credit""billing""balance""欠费"], LLMErrorCode.ERROR_QUOTA),        (["rate limit""429""tpm limit""too many requests""requests per minute"], LLMErrorCode.ERROR_RATE_LIMIT),        (["auth""key""apikey""401""forbidden""permission"], LLMErrorCode.ERROR_AUTHENTICATION),        (["invalid""bad request""400""format""malformed""parameter"], LLMErrorCode.ERROR_INVALID_REQUEST),        (["server""503""502""504""500""unavailable"], LLMErrorCode.ERROR_SERVER),        (["timeout""timed out"], LLMErrorCode.ERROR_TIMEOUT),        (["connect""network""unreachable""dns"], LLMErrorCode.ERROR_CONNECTION),        (["filter""content""policy""blocked""safety""inappropriate"], LLMErrorCode.ERROR_CONTENT_FILTER),        (["model""not found""does not exist""not available"], LLMErrorCode.ERROR_MODEL),        (["max rounds"], LLMErrorCode.ERROR_MODEL),    ]    # 第95-98行:遍历关键词匹配    for words, code in keywords_mapping:        if re.search("({})".format("|".join(words)), error_str):            return code    return LLMErrorCode.ERROR_GENERIC  # 第99行:默认通用错误

错误码枚举定义

class LLMErrorCode(StrEnum):    ERROR_RATE_LIMIT = "RATE_LIMIT_EXCEEDED"      # 速率限制    ERROR_AUTHENTICATION = "AUTH_ERROR"           # 认证错误    ERROR_INVALID_REQUEST = "INVALID_REQUEST"    # 无效请求    ERROR_SERVER = "SERVER_ERROR"                 # 服务器错误    ERROR_TIMEOUT = "TIMEOUT"                     # 超时    ERROR_CONNECTION = "CONNECTION_ERROR"         # 连接错误    ERROR_MODEL = "MODEL_ERROR"                   # 模型错误    ERROR_MAX_ROUNDS = "ERROR_MAX_ROUNDS"         # 超过最大轮数    ERROR_CONTENT_FILTER = "CONTENT_FILTERED"     # 内容过滤    ERROR_QUOTA = "QUOTA_EXCEEDED"                # 配额超限    ERROR_MAX_RETRIES = "MAX_RETRIES_EXCEEDED"    # 超过最大重试    ERROR_GENERIC = "GENERIC_ERROR"               # 通用错误

错误分类流程图


1.3 重试机制设计

源码位置rag/llm/chat_model.py:211-242

def _exceptions(self, e, attempt) -> str | None:    logging.exception("OpenAI chat_with_tools")    # 第213-214行:分类错误    error_code = self._classify_error(e)    # 第215-216行:达到最大重试次数    if attempt == self.max_retries:        error_code = LLMErrorCode.ERROR_MAX_RETRIES    # 第218-222行:判断是否需要重试    if self._should_retry(error_code):        delay = self._get_delay()  # 第219行:计算延迟时间        logging.warning(f"Error: {error_code}. Retrying in {delay:.2f} seconds... (Attempt {attempt + 1}/{self.max_retries})")        time.sleep(delay)        return None  # 第222行:返回None继续重试    # 第224-226行:不可重试错误,返回错误消息    msg = f"{ERROR_PREFIX}{error_code} - {str(e)}"    logging.error(f"sync base giving up: {msg}")    return msgasync def _exceptions_async(self, e, attempt):    logging.exception("OpenAI async completion")    # 第230-232行:分类错误    error_code = self._classify_error(e)    if attempt == self.max_retries:        error_code = LLMErrorCode.ERROR_MAX_RETRIES    # 第234-238行:异步重试    if self._should_retry(error_code):        delay = self._get_delay()        logging.warning(f"Error: {error_code}. Retrying in {delay:.2f} seconds... (Attempt {attempt + 1}/{self.max_retries})")        await asyncio.sleep(delay)  # 第237行:异步sleep        return None    # 第240-242行:返回错误消息    msg = f"{ERROR_PREFIX}{error_code} - {str(e)}"    logging.error(f"async base giving up: {msg}")    return msg@propertydef _retryable_errors(self) -> set[str]:    return {        LLMErrorCode.ERROR_RATE_LIMIT,        LLMErrorCode.ERROR_SERVER,    }  # 第203-206行:可重试错误集合def _should_retry(self, error_code: str) -> bool:    return error_code in self._retryable_errors  # 第209行:判断是否可重试def _get_delay(self):    return self.base_delay * random.uniform(10150)  # 第78行:随机延迟10-150倍基础延迟

重试决策表

错误类型
是否重试
原因
ERROR_RATE_LIMIT
✅ 重试
API限流,等待后可能恢复
ERROR_SERVER
✅ 重试
服务端临时故障,可能恢复
ERROR_AUTHENTICATION
❌ 不重试
认证失败,需修正配置
ERROR_INVALID_REQUEST
❌ 不重试
请求格式错误,需修正参数
ERROR_TIMEOUT
❌ 不重试
超时需调整timeout配置
ERROR_CONNECTION
❌ 不重试
网络问题需修正连接
ERROR_QUOTA
❌ 不重试
配额超限需充值或升级
ERROR_CONTENT_FILTER
❌ 不重试
内容违规需调整输入
ERROR_MAX_RETRIES
❌ 不重试
已达最大重试次数

重试流程图

关键技术点

  1. 随机延迟策略
    (第78行):random.uniform(10, 150)避免多请求同时重试造成二次限流
  2. 有限可重试集合
    (第203-206行):仅RATE_LIMIT和SERVER两类错误可重试,防止无限重试
  3. 异步重试支持
    (第237行):await asyncio.sleep(delay)支持异步场景重试
  4. attempt计数
    (第215-216行):达到max_retries强制终止,防止无限循环

二、工具调用机制

2.1 chat_with_tools工具调用流程

源码位置rag/llm/chat_model.py:278-329

async def async_chat_with_tools(self, system: str, history: list, gen_conf: dict = {}):    gen_conf = self._clean_conf(gen_conf)    # 第280-281行:添加system消息    if system and history and history[0].get("role") != "system":        history.insert(0, {"role""system""content": system})    ans = ""    tk_count = 0    hist = deepcopy(history)  # 第285行:深拷贝历史    # 第286-329行:重试循环    for attempt in range(self.max_retries + 1):        history = deepcopy(hist)        try:            # 第289-324行:工具调用循环            for _ in range(self.max_rounds + 1):                logging.info(f"{self.tools=}")                # 第291行:调用LLM(包含工具定义)                response = await self.async_client.chat.completions.create(                    model=self.model_name,                    messages=history,                    tools=self.tools,                    tool_choice="auto",                    **gen_conf                )                tk_count += total_token_count_from_response(response)                # 第293-294行:响应结构校验                if any([not response.choices, not response.choices[0].message]):                    raise Exception(f"500 response structure error. Response: {response}")                # 第296-304行:无工具调用,返回直接答案                if not hasattr(response.choices[0].message, "tool_calls"or not response.choices[0].message.tool_calls:                    if hasattr(response.choices[0].message, "reasoning_content"):                        ans += "seillee" + response.choices[0].message.reasoning_content + "aite"                    ans += response.choices[0].message.content                    if response.choices[0].finish_reason == "length":                        ans = self._length_stop(ans)                    return ans, tk_count                # 第306-317行:处理工具调用                for tool_call in response.choices[0].message.tool_calls:                    logging.info(f"Response {tool_call=}")                    name = tool_call.function.name                    try:                        # 第310-311行:解析参数并调用工具                        args = json_repair.loads(tool_call.function.arguments)                        tool_response = await thread_pool_exec(self.toolcall_session.tool_call, name, args)                        # 第312-313行:添加工具调用历史                        history = self._append_history(history, tool_call, tool_response)                        ans += self._verbose_tool_use(name, args, tool_response)                    except Exception as e:                        # 第315-317行:工具调用异常处理                        logging.exception(msg=f"Wrong JSON argument format: {tool_call}")                        history.append({"role""tool""tool_call_id": tool_call.id"content"f"Tool call error: {str(e)}"})                        ans += self._verbose_tool_use(name, {}, str(e))            # 第319-324行:超过最大轮数,强制结束            logging.warning(f"Exceed max rounds: {self.max_rounds}")            history.append({"role""user""content"f"Exceed max rounds: {self.max_rounds}"})            response, token_count = await self._async_chat(history, gen_conf)            ans += response            tk_count += token_count            return ans, tk_count        except Exception as e:            e = await self._exceptions_async(e, attempt)            if e:                return e, tk_count    assert False"Shouldn't be here."

工具调用流程图


2.2 历史记录管理

源码位置rag/llm/chat_model.py:247-269

def _append_history(self, hist, tool_call, tool_res):    # 第248-262行:添加assistant消息(包含tool_calls)    hist.append({        "role""assistant",        "tool_calls": [            {                "index": tool_call.index,                "id": tool_call.id,                "function": {                    "name": tool_call.function.name,                    "arguments": tool_call.function.arguments,                },                "type""function",            },        ],    })    try:        # 第264-266行:序列化工具结果        if isinstance(tool_res, dict):            tool_res = json.dumps(tool_res, ensure_ascii=False)    finally:        # 第268行:添加tool消息        hist.append({"role""tool""tool_call_id": tool_call.id"content"str(tool_res)})    return hist

OpenAI工具调用历史格式

[  {"role""user""content""搜索最新的AI新闻"},  {    "role""assistant",    "tool_calls": [      {        "index"0,        "id""call_abc123",        "function": {          "name""web_search",          "arguments""{\"query\"\"AI news\"\"top_k\": 5}"        },        "type""function"      }    ]  },  {    "role""tool",    "tool_call_id""call_abc123",    "content""{\"results\": [...], \"count\": 5}"  }]

2.3 流式工具调用处理

源码位置rag/llm/chat_model.py:332-441

async def async_chat_streamly_with_tools(self, system: str, history: list, gen_conf: dict = {}):    gen_conf = self._clean_conf(gen_conf)    tools = self.tools    # 第335-336行:添加system消息    if system and history and history[0].get("role") != "system":        history.insert(0, {"role""system""content": system})    total_tokens = 0    hist = deepcopy(history)    # 第341-440行:重试循环    for attempt in range(self.max_retries + 1):        history = deepcopy(hist)        try:            # 第344-411行:工具调用循环            for _ in range(self.max_rounds + 1):                reasoning_start = False                logging.info(f"{tools=}")                # 第348行:流式调用LLM                response = await self.async_client.chat.completions.create(                    model=self.model_name,                    messages=history,                    stream=True,  # 流式模式                    tools=tools,                    tool_choice="auto",                    **gen_conf                )                final_tool_calls = {}  # 第350行:累积工具调用                answer = ""  # 第351行:累积答案                # 第353-394行:处理流式响应                async for resp in response:                    if not hasattr(resp, "choices"or not resp.choices:                        continue                    delta = resp.choices[0].delta                    # 第359-368行:处理工具调用delta                    if hasattr(delta, "tool_calls"and delta.tool_calls:                        for tool_call in delta.tool_calls:                            index = tool_call.index                            if index not in final_tool_calls:                                if not tool_call.function.arguments:                                    tool_call.function.arguments = ""                                final_tool_calls[index] = tool_call                            else:                                # 第367行:累积arguments                                final_tool_calls[index].function.arguments += tool_call.function.arguments or ""                        continue                    # 第370-394行:处理文本delta                    if not hasattr(delta, "content"or delta.content is None:                        delta.content = ""                    # 第373-379行:处理reasoning_content(推理模型)                    if hasattr(delta, "reasoning_content"and delta.reasoning_content:                        ans = ""                        if not reasoning_start:                            reasoning_start = True                            ans = "seillee"                        ans += delta.reasoning_content + "aite"                        yield ans                    else:                        reasoning_start = False                        answer += delta.content                        yield delta.content  # 第383行:流式输出                    # 第385-389行:统计token                    tol = total_token_count_from_response(resp)                    if not tol:                        total_tokens += num_tokens_from_string(delta.content)                    else:                        total_tokens = tol                    # 第391-393行:处理截断                    finish_reason = getattr(resp.choices[0], "finish_reason""")                    if finish_reason == "length":                        yield self._length_stop("")                # 第395-397行:有答案文本,直接返回                if answer:                    yield total_tokens                    return                # 第399-410行:处理累积的工具调用                for tool_call in final_tool_calls.values():                    name = tool_call.function.name                    try:                        args = json_repair.loads(tool_call.function.arguments)                        yield self._verbose_tool_use(name, args, "Begin to call...")  # 第403行:输出开始调用                        tool_response = await thread_pool_exec(self.toolcall_session.tool_call, name, args)                        history = self._append_history(history, tool_call, tool_response)                        yield self._verbose_tool_use(name, args, tool_response)  # 第406行:输出工具结果                    except Exception as e:                        logging.exception(msg=f"Wrong JSON argument format: {tool_call}")                        history.append({"role""tool""tool_call_id": tool_call.id"content"f"Tool call error: {str(e)}"})                        yield self._verbose_tool_use(name, {}, str(e))            # 第412-430行:超过最大轮数,强制流式结束            logging.warning(f"Exceed max rounds: {self.max_rounds}")            history.append({"role""user""content"f"Exceed max rounds: {self.max_rounds}"})            response = await self.async_client.chat.completions.create(model=self.model_name, messages=history, stream=True, tools=tools, tool_choice="auto", **gen_conf)            async for resp in response:                if not hasattr(resp, "choices"or not resp.choices:                    continue                delta = resp.choices[0].delta                if not hasattr(delta, "content"or delta.content is None:                    continue                tol = total_token_count_from_response(resp)                if not tol:                    total_tokens += num_tokens_from_string(delta.content)                else:                    total_tokens = tol                yield delta.content            yield total_tokens            return        except Exception as e:            e = await self._exceptions_async(e, attempt)            if e:                logging.error(f"async_chat_streamly failed: {e}")                yield e                yield total_tokens                return    assert False"Shouldn't be here."

流式工具调用累积机制图

关键技术点

  1. 工具调用累积
    (第367行):final_tool_calls[index].function.arguments += tool_call.function.arguments流式工具调用分多次返回,需累积arguments
  2. 双输出模式
    (第383、403、406行):同时yield文本内容和工具调用日志,用户可实时看到工具执行过程
  3. reasoning_content处理
    (第373-379行):推理模型(如QwQ)返回推理过程,添加特殊标记便于前端区分
  4. json_repair修复
    (第310、402行):json_repair.loads容错解析,处理LLM返回的格式错误的JSON

三、流式响应处理

3.1 async_chat_streamly流式聊天

源码位置rag/llm/chat_model.py:173-195

async def async_chat_streamly(self, system, history, gen_conf: dict = {}, **kwargs):    # 第174-175行:添加system消息    if system and history and history[0].get("role") != "system":        history.insert(0, {"role""system""content": system})    gen_conf = self._clean_conf(gen_conf)    ans = ""    total_tokens = 0    # 第180-195行:重试循环    for attempt in range(self.max_retries + 1):        try:            # 第182-187行:流式输出循环            async for delta_ans, tol in self._async_chat_streamly(history, gen_conf, **kwargs):                ans = delta_ans  # 第183行:累积答案(流式模式下每次yield完整增量)                total_tokens += tol                yield ans  # 第185行:流式输出            yield total_tokens  # 第187行:最后yield token数            return        except Exception as e:            e = await self._exceptions_async(e, attempt)            if e:                yield e  # 第192行:yield错误消息                yield total_tokens                return

_async_chat_streamly核心实现

async def _async_chat_streamly(self, history, gen_conf, **kwargs):    logging.info("[HISTORY STREAMLY]" + json.dumps(history, ensure_ascii=False, indent=4))    reasoning_start = False    # 第141行:构造请求参数    request_kwargs = {"model"self.model_name, "messages": history, "stream"True, **gen_conf}    stop = kwargs.get("stop")    if stop:        request_kwargs["stop"] = stop    # 第146行:流式调用    response = await self.async_client.chat.completions.create(**request_kwargs)    async for resp in response:        if not resp.choices:            continue        # 第150-151行:处理空content        if not resp.choices[0].delta.content:            resp.choices[0].delta.content = ""        # 第152-161行:处理reasoning_content(推理模型)        if kwargs.get("with_reasoning"Trueand hasattr(resp.choices[0].delta, "reasoning_content"and resp.choices[0].delta.reasoning_content:            ans = ""            if not reasoning_start:                reasoning_start = True                ans = "seillee"            ans += resp.choices[0].delta.reasoning_content + "aite"        else:            reasoning_start = False            ans = resp.choices[0].delta.content        # 第161-163行:统计token        tol = total_token_count_from_response(resp)        if not tol:            tol = num_tokens_from_string(resp.choices[0].delta.content)        # 第165-171行:处理截断        finish_reason = resp.choices[0].finish_reason if hasattr(resp.choices[0], "finish_reason"else ""        if finish_reason == "length":            if is_chinese(ans):                ans += LENGTH_NOTIFICATION_CN            else:                ans += LENGTH_NOTIFICATION_EN        yield ans, tol  # 第171行:yield增量答案和token数

流式输出流程图


3.2 参数清理机制

源码位置rag/llm/chat_model.py:101-135

def _clean_conf(self, gen_conf):    model_name_lower = (self.model_name or "").lower()    # 第103-106行:GPT-5特殊处理(清空所有自定义参数)    if "gpt-5" in model_name_lower:        gen_conf = {}        return gen_conf    # 第108-109行:删除max_tokens(使用max_completion_tokens代替)    if "max_tokens" in gen_conf:        del gen_conf["max_tokens"]    # 第111-132行:允许的参数列表    allowed_conf = {        "temperature",        "max_completion_tokens",        "top_p",        "stream",        "stream_options",        "stop",        "n",        "presence_penalty",        "frequency_penalty",        "functions",        "function_call",        "logit_bias",        "user",        "response_format",        "seed",        "tools",        "tool_choice",        "logprobs",        "top_logprobs",        "extra_headers",    }    # 第134行:过滤参数    gen_conf = {k: v for k, v in gen_conf.items() if k in allowed_conf}    return gen_conf

参数过滤原因表

参数
处理方式
原因
max_tokens
删除
OpenAI API已弃用,改用max_completion_tokens
gpt-5
所有参数
清空
GPT-5端点参数支持不一致,防止意外错误
其他参数
白名单过滤
仅保留OpenAI支持的参数,防止API报错

四、多提供商适配

4.1 提供商继承关系

源码位置rag/llm/chat_model.py:488-694

class XinferenceChat(Base):  # 第488行:Xinference推理框架    _FACTORY_NAME = "Xinference"    def __init__(self, key=None, model_name="", base_url="", **kwargs):        if not base_url:            raise ValueError("Local llm url cannot be None")        base_url = urljoin(base_url, "v1")  # 第494行:拼接v1路径        super().__init__(key, model_name, base_url, **kwargs)class HuggingFaceChat(Base):  # 第498行:HuggingFace本地模型    _FACTORY_NAME = "HuggingFace"    def __init__(self, key=None, model_name="", base_url="", **kwargs):        if not base_url:            raise ValueError("Local llm url cannot be None")        base_url = urljoin(base_url, "v1")        super().__init__(key, model_name.split("___")[0], base_url, **kwargs)  # 第505行:去除___后缀class BaiChuanChat(Base):  # 第518行:百川AI    _FACTORY_NAME = "BaiChuan"    def __init__(self, key, model_name="Baichuan3-Turbo", base_url="https://api.baichuan-ai.com/v1", **kwargs):        if not base_url:            base_url = "https://api.baichuan-ai.com/v1"        super().__init__(key, model_name, base_url, **kwargs)    def _clean_conf(self, gen_conf):  # 第533-537行:自定义参数清理        return {            "temperature": gen_conf.get("temperature"0.3),            "top_p": gen_conf.get("top_p"0.85),        }    def _chat(self, history, gen_conf={}, **kwargs):  # 第539-552行:特殊web_search工具        response = self.client.chat.completions.create(            model=self.model_name,            messages=history,            extra_body={"tools": [{"type""web_search""web_search": {"enable"True"search_mode""performance_first"}}]},            **gen_conf,        )        ans = response.choices[0].message.content.strip()        if response.choices[0].finish_reason == "length":            if is_chinese([ans]):                ans += LENGTH_NOTIFICATION_CN            else:                ans += LENGTH_NOTIFICATION_EN        return ans, total_token_count_from_response(response)class LocalAIChat(Base):  # 第593行:LocalAI本地推理    _FACTORY_NAME = "LocalAI"    def __init__(self, key, model_name, base_url=None, **kwargs):        super().__init__(key, model_name, base_url=base_url, **kwargs)        if not base_url:            raise ValueError("Local llm url cannot be None")        base_url = urljoin(base_url, "v1")        self.client = OpenAI(api_key="empty", base_url=base_url)  # 第602行:空API Key        self.model_name = model_name.split("___")[0]class MistralChat(Base):  # 第668行:Mistral AI    _FACTORY_NAME = "Mistral"    def __init__(self, key, model_name, base_url=None, **kwargs):        super().__init__(key, model_name, base_url=base_url, **kwargs)        from mistralai.client import MistralClient        self.client = MistralClient(api_key=key)  # 第676行:Mistral SDK        self.model_name = model_name    def _clean_conf(self, gen_conf):  # 第679-683行:仅允许3个参数        for k in list(gen_conf.keys()):            if k not in ["temperature""top_p""max_tokens"]:                del gen_conf[k]        return gen_conf

提供商适配策略表

提供商
继承自
特殊处理
SDK/API
Xinference
Base
URL拼接v1
OpenAI兼容
HuggingFace
Base
模型名去除___
OpenAI兼容
BaiChuan
Base
自定义参数清理、web_search工具
OpenAI兼容
LocalAI
Base
空API Key
OpenAI兼容
Mistral
Base
仅允许3参数
MistralClient SDK
VolcEngine
Base
JSON key解析
OpenAI兼容
QWen
Base
dashscope SDK
dashscope SDK

提供商继承关系图


五、Chunking解析应用

5.1 解析器工厂映射

源码位置rag/app/naive.py:222-228

PARSERS = {    "deepdoc": by_deepdoc,       # DeepDoc解析器    "mineru": by_mineru,         # MinerU解析器    "docling": by_docling,       # Docling解析器    "tcadp": by_tcadp,           # Tencent Cloud ADP解析器    "paddleocr": by_paddleocr,   # PaddleOCR解析器    "plaintext": by_plaintext,   # 纯文本解析器(默认)}

解析器对比表

解析器
特点
适用场景
LLM依赖
deepdoc
自研深度文档解析
PDF复杂布局
mineru
MinerU OCR引擎
高精度OCR
可选
docling
IBM Docling
学术论文
tcadp
腾讯云ADP
企业级文档
腾讯云API
paddleocr
PaddleOCR
中文OCR优化
可选
plaintext
纯文本提取
简单文本
Vision模型可选

5.2 by_plaintext解析流程

源码位置rag/app/naive.py:202-219

def by_plaintext(filename, binary=None, from_page=0, to_page=100000, callback=None, **kwargs):    layout_recognizer = (kwargs.get("layout_recognizer"or "").strip()    # 第204-206行:无layout_recognizer或PlainText,使用PlainParser    if (not layout_recognizer) or (layout_recognizer == "Plain Text"):        pdf_parser = PlainParser()    else:        # 第207-216行:使用Vision布局识别        tenant_id = kwargs.get("tenant_id")        if not tenant_id:            raise ValueError("tenant_id is required when using vision layout recognizer")        vision_model = LLMBundle(            tenant_id,            LLMType.IMAGE2TEXT,            llm_name=layout_recognizer,            lang=kwargs.get("lang""Chinese"),        )        pdf_parser = VisionParser(vision_model=vision_model, **kwargs)    # 第218行:调用解析器    sections, tables = pdf_parser(filename if not binary else binary, from_page=from_page, to_page=to_page, callback=callback)    return sections, tables, pdf_parser

解析流程图


六、设计模式与技术决策总结

6.1 核心设计模式统计表

设计模式
应用位置
实现细节
目的
抽象基类
Base类
ABC抽象类、NotImplementedError
统一LLM接口
模板方法
async_chat_with_tools
固定流程:调用→工具→历史→重试
标准化工具调用
策略模式
错误分类
keywords_mapping映射表
精准错误处理
装饰器模式
_clean_conf
参数白名单过滤
防止API报错
工厂模式
PARSERS映射
字典映射解析器
动态解析器选择
继承复用
XinferenceChat等
继承Base,自定义配置
多提供商适配
流式迭代器
async_chat_streamly
yield增量输出
支持流式响应

6.2 技术决策对比表

技术点
方案A
方案B
选择理由
客户端类型
双客户端(同步+异步)
仅异步客户端
同步用于简单场景,异步用于流式
错误重试
仅RATE_LIMIT和SERVER
所有错误重试
部分错误重试无意义(如认证失败)
工具调用轮数限制
max_rounds=5
无限制
防止无限工具调用循环
参数清理
白名单过滤
直接传递
防止不支持的参数导致API报错
流式工具调用
累积arguments
立即解析
工具调用分多次返回需累积
JSON解析
json_repair.loads
json.loads
json_repair容错处理格式错误

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-06-02 03:24:37 HTTP/1.1 GET : https://www.yeyulingfeng.com/a/696336.html
  2. 运行时间 : 0.125089s [ 吞吐率:7.99req/s ] 内存消耗:4,761.63kb 文件加载:145
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=1cd4177274ccd3872806526a3506130c
  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.001142s ] mysql:host=127.0.0.1;port=3306;dbname=wenku;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001667s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000671s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000689s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001431s ]
  6. SELECT * FROM `set` [ RunTime:0.000636s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001579s ]
  8. SELECT * FROM `article` WHERE `id` = 696336 LIMIT 1 [ RunTime:0.002246s ]
  9. UPDATE `article` SET `lasttime` = 1780341878 WHERE `id` = 696336 [ RunTime:0.001543s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.000622s ]
  11. SELECT * FROM `article` WHERE `id` < 696336 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001221s ]
  12. SELECT * FROM `article` WHERE `id` > 696336 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.002810s ]
  13. SELECT * FROM `article` WHERE `id` < 696336 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.003330s ]
  14. SELECT * FROM `article` WHERE `id` < 696336 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.002587s ]
  15. SELECT * FROM `article` WHERE `id` < 696336 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.006159s ]
0.126763s