乐于分享
好东西不私藏

我们用 RAG 自建了一个能读懂源码的智能知识库

我们用 RAG 自建了一个能读懂源码的智能知识库

我们用 RAG 自建了一个能读懂源码的智能知识库

真正难回答的问题,从来不在 FAQ 里,而藏在源码、提交记录、设计文档、事故复盘和发布变更里。能读懂这些材料的,不是一个“会聊天的机器人”,而是一套带检索、编排、版本治理和权限控制的知识引擎。


一、从一次凌晨故障开始:为什么 FAQ 注定会失效

事情发生在一个电商大促前夜。

客服群里连续出现同一类问题:

为什么用户支付成功后,订单状态还一直卡在“处理中”?

传统 FAQ 里有一条很标准的答案:

请确认支付是否成功,若已成功请稍后刷新页面。

这条回答不能说错,但它对生产系统毫无帮助。因为那次故障的真正原因并不是“支付未完成”,而是订单服务在消费支付成功事件后,命中了一个只在特定灰度版本里出现的补偿分支:

  • • 支付网关超时后,Saga 状态被标记为 WAIT_COMPENSATION
  • • 订单聚合根的重试逻辑依赖 Redis 分布式锁
  • • 某个版本将锁租期从 15 秒改成 8 秒,却没有同步调整下游库存服务的重试窗口
  • • 最终导致补偿流程提前放弃,订单状态停留在中间态

这些信息分别散落在:

  • • Git 仓库里一段最近刚合并的代码
  • • 一篇设计文档里的状态机说明
  • • 一条发布说明中的灰度开关配置
  • • 一份事故复盘里关于补偿超时的结论

也就是说,真正有价值的答案不在 FAQ 里,而在系统本身留下的“工程痕迹”里。

这就是很多企业知识问答项目一开始效果不错,后面却迅速失真的根本原因:它们构建的是一个“文档搜索器”,不是一个“能跟着代码和版本一起演化的知识系统”。

所以本文要讨论的,不是怎么做一个 Demo 级 RAG 聊天机器人,而是怎么构建一套真正能读懂源码、理解上下文、感知版本变化、适合线上高并发场景的智能知识库。


二、源码知识库和普通 FAQ 机器人的根本区别

很多团队第一次做 RAG 时,直觉上会把它理解成:

把文档喂给向量库,再让大模型按检索结果回答问题。

这个理解只能解决“静态知识问答”,却解决不了“源码理解”和“线上排障辅助”。

因为源码知识库面对的并不是简单文本,而是四类完全不同的知识对象:

  1. 1. 说明性知识
    包括产品文档、接口文档、Runbook、事故复盘、设计评审记录。
  2. 2. 执行性知识
    包括源码、配置、SQL、脚本、工作流定义、CI/CD 编排文件。
  3. 3. 结构性知识
    包括模块依赖、调用链、包结构、类关系、状态机、事件流和表之间的关联。
  4. 4. 时序性知识
    包括分支差异、版本变更、灰度配置、提交记录、发布窗口和索引构建时点。

如果系统只会做“文本相似度召回”,它会遇到三个典型问题:

  • • 用户问“订单为什么卡处理中”,检索回来的却是“订单状态定义”文档,而不是补偿逻辑所在的代码路径。
  • • 用户问“这个接口为什么要带 tenant_id”,系统只找到字段解释,却找不到 ACL 下推和多租户隔离的真实实现。
  • • 用户问“今天凌晨为什么回答错了”,系统无法判断自己引用的是旧版本文档还是旧版本代码。

所以,一个真正可用的源码知识库,底层不是单一的向量检索,而是一个“多源知识召回 + 结构化约束 + 版本一致性 + 可信生成”的组合系统。

从工程视角看,它至少要做到下面四件事:

  • • 能把源码切成对检索友好的语义单元,而不是把整文件粗暴截断。
  • • 能把“代码符号、配置项、文档段落、事故结论”放到同一个问题求解链路里。
  • • 能保证回答引用的是同一个知识快照,而不是文档来自新版本、代码来自旧版本。
  • • 能在高风险问题上给出“证据不足”而不是“流畅胡说”。

这才是“FAQ 已死”之后真正应该建设的系统形态。


三、从 RAG 到知识引擎:一套可读源码的生产级总体架构

为了让系统真正落地,我们把整套能力拆成两条链路:

  • • 在线链路:负责接住用户问题,在毫秒到秒级内返回可信答案。
  • • 离线链路:负责持续把代码、文档、配置和变更事件加工成可检索、可追踪、可回滚的知识快照。

整个系统可以抽象成下面这张图:

                           +-----------------------+
                           |  API Gateway / SSO    |
                           +-----------+-----------+
                                       |
                            +----------v----------+
                            |  Query Orchestrator |
                            | rewrite / policy    |
                            +----+----------+-----+
                                 |          |
                      +----------v--+    +--v----------------+
                      | Retrieval    |    | Answer Guardrail  |
                      | Coordinator  |    | citation / risk   |
                      +---+----+-----+    +---------+---------+
                          |    |                        |
          +---------------+    +-------------------+    |
          |                                        |    |
 +--------v---------+                    +---------v----v--------+
 | Dense Retriever  |                    | Sparse / Symbol /     |
 | vector index     |                    | Graph Retriever       |
 +--------+---------+                    +-----------+-----------+
          |                                          |
          +------------------+   +-------------------+
                             |   |
                      +------v---v------+
                      | Re-rank Service  |
                      | relevance / ACL  |
                      +------+-----------+
                             |
                   +---------v----------+
                   | Context Builder    |
                   | snapshot / budget  |
                   +---------+----------+
                             |
                   +---------v----------+
                   | LLM Gateway        |
                   | route / cache      |
                   +--------------------+


 +-------------------------------------------------------------------+
 | Offline Pipeline                                                   |
 | repo webhook -> parser -> semantic chunk -> embedding -> indexing  |
 | document sync -> metadata enrich -> snapshot publish -> rollback   |
 +-------------------------------------------------------------------+

3.1 控制面、执行面、状态面、治理面

如果你希望这套系统可以长期演进,建议不要把它当成一个“大模型调用服务”,而要按四个平面来设计。

控制面

  • • 管理知识源接入
  • • 定义索引构建规则
  • • 管理模型路由、上下文预算、重排策略
  • • 控制快照发布和回滚

执行面

  • • 承载 Query 改写、检索、重排、上下文拼装、生成和流式输出
  • • 对高频问题做缓存,对慢查询做并发隔离和超时收敛

状态面

  • • 存储文档块、源码块、符号表、依赖图、索引版本、反馈记录
  • • 记录回答引用的知识快照与证据链

治理面

  • • 权限过滤、审计、风险拦截
  • • 可观测性、成本治理、灰度发布、质量评估

这种分层的好处是:以后不管你替换向量库、替换 Embedding 模型,还是把单租户升级为多租户,系统都不会因为一处改动而整条链路重做。

3.2 在线链路到底在做什么

一条生产级问答请求,大致会经历下面这些步骤:

  1. 1. 问题归一化
    把“订单卡处理中咋办”改写成结构化查询意图,例如:
    domain=order, symptom=processing_timeout, expected_artifacts=code+runbook+postmortem
  2. 2. 权限裁剪
    根据用户身份过滤仓库、目录、文档空间和环境范围,避免把生产配置或敏感仓库内容暴露给无权限用户。
  3. 3. 多路召回
    并行走四种检索:
    • • dense 向量召回
    • • BM25 全文召回
    • • 符号级召回
    • • 依赖图扩散召回
  4. 4. 交叉重排
    不是只看文本相似度,而是结合“问题意图 + 证据类型 + 新鲜度 + 权限 + 版本一致性”排序。
  5. 5. 上下文组装
    把代码片段、配置说明、事故结论按因果链拼成上下文,而不是简单拼 TopK 文本。
  6. 6. 可信生成
    强制模型只基于证据回答;证据不足时直接返回“不确定”和建议补充排查路径。
  7. 7. 结果落库
    记录本次使用的 snapshot_id、引用片段、生成时延、风险标签、用户反馈,为后续评估和优化提供基础数据。

3.3 离线链路为什么决定上限

大多数 RAG 项目不是死在“生成效果差”,而是死在离线链路太弱。

因为系统回答质量的上限,取决于你是否把知识加工成了适合检索的形态。

源码知识库的离线链路至少包含六个关键环节:

  1. 1. 变更捕获
    Git webhook、Confluence webhook、配置中心事件、数据库 DDL 变更日志。
  2. 2. 语义解析
    Markdown 文档按章节解析,源码按 AST 或符号边界解析,YAML/SQL 按配置段和语句级别解析。
  3. 3. 结构补充
    为每个 chunk 追加元数据:仓库、分支、提交、模块、语言、服务名、责任团队、环境、版本、生效时间。
  4. 4. 多索引写入
    不只写向量库,还要同步写入全文索引、符号索引和依赖图。
  5. 5. 快照发布
    将本轮构建结果封装成 snapshot_id,只有验证通过后才切主读流量。
  6. 6. 回滚与对账
    一旦发现召回率骤降、空结果率升高或反馈质量下滑,可以快速回滚到上一个稳定快照。

离线链路做得越扎实,在线链路越不需要靠 Prompt 魔法硬扛。


四、关键设计决策:为什么“能读懂源码”比“能搜到文档”难得多

4.1 代码不能按固定 Token 长度切块

普通文档常见的切块方式是按 300 到 800 token 分段,但源码不能这么干。

因为对于代码来说,最有意义的检索单位往往是:

  • • 一个函数
  • • 一个类
  • • 一个路由处理器
  • • 一段状态机分支
  • • 一个配置段与它对应的消费逻辑

如果你把下面这类函数拦腰截断,检索几乎一定会失真:

def confirm_payment(order_id: str, payment_id: str) -> None:
    with
 distributed_lock(f"order:{order_id}", lease=8):
        order = repository.get(order_id)
        if
 order.status == "WAIT_COMPENSATION":
            workflow.resume(order_id, payment_id)
            outbox.append("order.compensation.resume", order_id)

用户真正关心的不是这 6 行代码本身,而是:

  • • 这是哪个服务的哪个聚合根方法
  • • 它在什么状态下被调用
  • • 锁租期为什么是 8 秒
  • • 这段逻辑跟哪个补偿事件有关

所以更合理的做法是:

  • • 文本按自然段和章节切块
  • • 源码按 AST/符号边界切块
  • • 配置按功能段切块
  • • 图结构按节点和边关系切块

然后通过统一的 artifact_id 把这些对象串起来。

4.2 检索不是 Dense 和 BM25 二选一

“Dense 还是 BM25”这个争论,在源码知识库里意义不大。因为它们解决的是不同问题。

Dense 擅长:

  • • 语义相近但措辞不同的问题
  • • 口语化提问
  • • 文档结论与问题表达不一致的场景

BM25 擅长:

  • • 精准命中类名、方法名、错误码、配置键
  • • 检索 SQL、命令、接口路径、异常文本
  • • 用户直接贴日志、堆栈或字段名的场景

而源码知识库还需要第三类检索:符号检索和关系扩展

例如用户问:

tenant_id 为什么必须透传到下游?

最有价值的证据可能来自:

  • • AuthContext 结构体定义
  • • TenantScopeInterceptor 中的校验逻辑
  • • 一篇多租户隔离设计文档
  • • 某个接口网关的 ACL 下推配置

也就是说,真正有效的是“混合召回 + 关系补全”,而不是只盯着某一种相似度算法。

4.3 版本一致性比召回率更容易被忽视

很多团队做完 RAG 后,第一反应都是优化召回率和生成分数,但在企业场景里,更危险的问题往往是“答对了旧知识”。

比如:

  • • 文档已经更新到 v2026.07.14
  • • 向量库里还是前一天的 chunk
  • • 代码仓库主分支已经修复问题,但事故复盘还指向旧行为

如果系统把这些证据混在一起回答,用户会得到一段看上去很完整、实际上跨版本拼接的错误结论。

因此我们在生产里把 snapshot_id 作为一等公民:

  • • 每轮离线构建生成一个新的知识快照
  • • 在线请求只在单一快照内检索
  • • 每条回答都记录引用自哪个快照
  • • 快照发布前先做离线评测和抽样验证

这件事的价值,往往比把 Recall@20 从 0.81 提到 0.84 更大。

4.4 权限过滤不能放在回答之后

源码知识库一旦进入企业内部,权限问题就不能靠“模型别说出来”解决。

必须在检索前做 ACL 过滤,否则你即便在输出层屏蔽了答案,模型在生成阶段也已经见过不该见的数据。

推荐的做法是:

  • • 检索时携带 principal_idrepo_scopedoc_scopeenv_scope
  • • 各索引统一支持元数据过滤
  • • 重排前再次做证据级校验
  • • 输出只保留用户有权查看的引用链接

这也是为什么企业级 RAG 系统一定要把“权限模型”和“检索模型”一起设计,而不是后补一个脱敏层。


五、核心实现:一条真正可上线的源码知识链路应该怎么写

下面不展示玩具级 Demo,而是给出三段最关键的生产级实现骨架:

  • • 如何按源码语义切块并构建快照
  • • 如何做混合检索和版本一致性控制
  • • 如何生成带引用、可审计、可降级的答案

5.1 索引配置:把快照、一致性和权限当成默认能力

# config/knowledge_engine.yaml
snapshot:

  active_snapshot:
 "kb-2026-07-14-02"
  publish_strategy:
 "blue_green"
  rollback_window:
 3

retrieval:

  dense_top_k:
 40
  sparse_top_k:
 40
  symbol_top_k:
 20
  rerank_top_k:
 12
  final_top_k:
 6
  timeout_ms:
 450

filters:

  enforce_acl:
 true
  require_snapshot_consistency:
 true
  allowed_artifact_types:

    -
 markdown
    -
 source_code
    -
 yaml
    -
 sql
    -
 postmortem

generation:

  max_context_tokens:
 12000
  refuse_without_evidence:
 true
  high_risk_keywords:

    -
 drop
    -
 delete
    -
 truncate
    -
 rm -rf

cache:

  semantic_ttl_seconds:
 300
  answer_ttl_seconds:
 120

这份配置有几个容易被忽略但非常关键的点:

  • • active_snapshot 决定在线检索使用哪个知识快照
  • • require_snapshot_consistency 禁止混用不同版本证据
  • • refuse_without_evidence 要求系统在缺少依据时显式拒答
  • • high_risk_keywords 用于高危操作拦截

5.2 源码语义切块:不要把函数和上下文拆散

# pipeline/source_chunker.py
from
 dataclasses import dataclass
from
 pathlib import Path
from
 typing import Iterable


@dataclass

class
 CodeChunk:
    chunk_id: str
    artifact_id: str
    repo: str
    path: str
    symbol: str
    language: str
    content: str
    summary: str
    start_line: int
    end_line: int
    snapshot_id: str
    acl_tags: list[str]
    metadata: dict


class
 SourceChunker:
    def
 __init__(self, parser_registry, summarizer):
        self
.parser_registry = parser_registry
        self
.summarizer = summarizer

    def
 chunk_file(
        self,
        repo: str,
        file_path: Path,
        snapshot_id: str,
        acl_tags: list[str],
) -> Iterable[CodeChunk]:
        parser = self.parser_registry.for_path(file_path)
        tree = parser.parse(file_path.read_text())

        for
 symbol in tree.iter_symbols():
            if
 symbol.kind not in {"function", "method", "class", "handler"}:
                continue


            source = symbol.source_text()
            summary = self.summarizer.summarize_symbol(
                name=symbol.qualified_name,
                docstring=symbol.docstring,
                source=source,
            )

            yield
 CodeChunk(
                chunk_id=f"{snapshot_id}:{repo}:{file_path}:{symbol.start_line}",
                artifact_id=f"{repo}:{file_path}",
                repo=repo,
                path=str(file_path),
                symbol=symbol.qualified_name,
                language=parser.language,
                content=source,
                summary=summary,
                start_line=symbol.start_line,
                end_line=symbol.end_line,
                snapshot_id=snapshot_id,
                acl_tags=acl_tags,
                metadata={
                    "kind"
: symbol.kind,
                    "imports"
: symbol.imports,
                    "calls"
: symbol.calls,
                    "owners"
: symbol.owners,
                },
            )

这段逻辑的重点不在“能把文件读出来”,而在它输出的是一个可检索、可过滤、可关联的知识对象:

  • • artifact_id 用来把同一个文件的文档说明、代码块、配置块串联起来
  • • summary 用来补足代码的语义表达,改善向量检索效果
  • • snapshot_id 确保后续在线查询可以做版本锁定
  • • callsimports 等关系字段可以供图检索使用

5.3 混合检索协调器:先把证据找全,再谈生成

# online/retrieval_coordinator.py
import
 asyncio
from
 dataclasses import dataclass


@dataclass

class
 RetrievalRequest:
    query: str
    principal_id: str
    snapshot_id: str
    repo_scopes: list[str]
    top_k: int


class
 RetrievalCoordinator:
    def
 __init__(self, dense, sparse, symbol, graph, reranker):
        self
.dense = dense
        self
.sparse = sparse
        self
.symbol = symbol
        self
.graph = graph
        self
.reranker = reranker

    async
 def retrieve(self, req: RetrievalRequest) -> list[dict]:
        filters = {
            "snapshot_id"
: req.snapshot_id,
            "repo"
: {"$in": req.repo_scopes},
            "acl"
: {"$allow": req.principal_id},
        }

        dense_task = self.dense.search(req.query, top_k=40, filters=filters)
        sparse_task = self.sparse.search(req.query, top_k=40, filters=filters)
        symbol_task = self.symbol.search(req.query, top_k=20, filters=filters)

        dense_hits, sparse_hits, symbol_hits = await asyncio.gather(
            dense_task,
            sparse_task,
            symbol_task,
        )

        graph_seeds = [hit["chunk_id"] for hit in symbol_hits[:5]]
        graph_hits = await self.graph.expand(
            seeds=graph_seeds,
            snapshot_id=req.snapshot_id,
            principal_id=req.principal_id,
            depth=1,
        )

        merged = self._rrf_merge(dense_hits, sparse_hits, symbol_hits, graph_hits)
        reranked = await self.reranker.rank(req.query, merged[:80])
        return
 reranked[: req.top_k]

    def
 _rrf_merge(self, *hit_lists: list[dict]) -> list[dict]:
        scores: dict[str, float] = {}
        docs: dict[str, dict] = {}
        for
 hits in hit_lists:
            for
 rank, hit in enumerate(hits):
                chunk_id = hit["chunk_id"]
                docs[chunk_id] = hit
                scores[chunk_id] = scores.get(chunk_id, 0.0) + 1.0 / (60 + rank + 1)
        ranked = sorted(scores.items(), key=lambda item: item[1], reverse=True)
        return
 [docs[chunk_id] for chunk_id, _ in ranked]

这里体现了三个生产级取舍:

  • • 先做 ACL 和快照过滤,再做召回,而不是召回之后再删
  • • 用符号召回结果作为图扩展的种子,让代码理解更接近真实调用链
  • • 重排前保留更多候选,避免单路检索过早把关键证据刷掉

5.4 回答服务:模型必须为每一句判断负责

# online/answer_service.py
class
 AnswerService:
    def
 __init__(self, retriever, llm_gateway, risk_guard, citation_builder):
        self
.retriever = retriever
        self
.llm_gateway = llm_gateway
        self
.risk_guard = risk_guard
        self
.citation_builder = citation_builder

    async
 def answer(self, query, principal, snapshot_id, repo_scopes):
        hits = await self.retriever.retrieve(
            RetrievalRequest(
                query=query,
                principal_id=principal.user_id,
                snapshot_id=snapshot_id,
                repo_scopes=repo_scopes,
                top_k=6,
            )
        )

        if
 not hits:
            return
 {
                "status"
: "insufficient_evidence",
                "answer"
: "当前知识快照中没有足够证据支撑回答,请缩小问题范围或补充服务名、接口名、错误码。",
                "citations"
: [],
            }

        context = self.citation_builder.build_context(hits, max_tokens=12000)
        prompt = self._build_prompt(query, context)
        draft = await self.llm_gateway.generate(prompt, temperature=0.1)
        checked = self.risk_guard.verify(draft=draft, evidence=hits)

        return
 {
            "status"
: checked.status,
            "answer"
: checked.answer,
            "citations"
: [
                {
                    "repo"
: hit["repo"],
                    "path"
: hit["path"],
                    "symbol"
: hit.get("symbol"),
                    "lines"
: [hit["start_line"], hit["end_line"]],
                    "snapshot_id"
: hit["snapshot_id"],
                }
                for
 hit in hits
            ],
        }

    def
 _build_prompt(self, query, context):
        return
 f"""
你是企业内部源码知识助手。
请严格遵守以下规则:
1. 只能基于给定证据回答。
2. 若证据不足,直接说明不确定,不要猜测。
3. 若涉及删除、变更、回滚、数据修复等高风险操作,必须先说明风险和前置检查项。
4. 回答时优先给出结论、原因、证据位置和排查建议。

问题:
{query}


证据:
{context}

"""

这段代码看起来简单,但它体现的是一套很重要的回答哲学:

  • • 没证据时拒答,比答得流畅但错更重要
  • • 回答必须带引用,否则无法回溯和复盘
  • • 高危场景必须走风险拦截,不能把大模型当自动执行器

5.5 离线构建发布:索引更新要可灰度、可回滚

# pipeline/snapshot_publisher.py
class
 SnapshotPublisher:
    def
 __init__(self, evaluator, registry, router):
        self
.evaluator = evaluator
        self
.registry = registry
        self
.router = router

    def
 publish(self, snapshot_id: str) -> None:
        report = self.evaluator.evaluate(snapshot_id)
        if
 report.empty_hit_ratio > 0.18:
            raise
 RuntimeError("empty hit ratio exceeds threshold")
        if
 report.faithfulness_score < 0.82:
            raise
 RuntimeError("faithfulness score too low")

        self
.registry.mark_ready(snapshot_id)
        self
.router.shift_read_traffic(snapshot_id, strategy="blue_green")

很多团队只做“写入成功即生效”,这在线上非常危险。更稳妥的做法是:

  • • 新快照先做离线评测
  • • 指标过线后再切部分流量
  • • 观察空结果率、正反馈率、平均时延
  • • 异常时一键切回旧快照

这样系统才真正具备工程可运维性。


六、生产环境最容易踩的四个坑,以及我们怎么补上

6.1 坑一:系统能读文档,但读不懂代码

最常见的表现是:

  • • 能回答“这个服务是干什么的”
  • • 但回答不了“这个状态为什么没推进”
  • • 或者能找到类名,却解释不清它和下游依赖的关系

这通常不是模型不够强,而是索引对象设计错了。你把源码当纯文本喂进去,模型当然只能“看到字”,看不到结构。

我们的修正办法是:

  • • 代码按符号切块
  • • 为每个符号补生成摘要
  • • 构建调用关系图
  • • 文档段落与代码对象建立 artifact_id 关联

一旦这样做,很多原本看似复杂的问题,检索命中率会明显提升。

6.2 坑二:答案看上去正确,其实引用的是旧版本

这个坑非常隐蔽,因为用户很难第一时间意识到自己看到的是旧知识。

我们在线上遇到过一次典型案例:

  • • 文档已经写明“新版本改用 Outbox 推事件”
  • • 检索结果却把两周前的“直接发 MQ”旧实现也拉了进来
  • • 最终回答变成了“系统同时支持两种模式”

从文字上看它很顺,但实际上这是错误结论。

后来我们强制要求所有证据都落在同一个 snapshot_id 上,并在回答里显示当前快照版本。做完这个改造后,这类“跨版本拼接错误”明显减少。

6.3 坑三:高并发下延迟炸掉,系统开始随机超时

RAG 系统在低流量测试环境里往往没问题,一到业务高峰就暴露出延迟链过长的问题:

  • • Query 改写要调用一次模型
  • • 检索要打多路存储
  • • 重排又要走一轮模型
  • • 最后生成再来一次大模型

如果没有做并发控制和超时收敛,P99 很容易劣化。

我们的几个经验是:

  • • Query 改写不是每次都做,只对低质量问题触发
  • • 重排候选数量要设上限,别无脑 Top50 全送
  • • 对高频问题做语义缓存
  • • 给 dense、sparse、symbol 检索各自设置超时,超时就降级而不是整体失败
  • • LLM Gateway 层统一做限流和熔断

真正上线以后,你会发现“优雅降级”比“理论最优回答”更值钱。

6.4 坑四:权限模型缺失,系统变成内部信息泄漏放大器

只要系统接入了源码、配置、排障文档,它就一定会碰到权限问题:

  • • 研发能否看到生产 Runbook
  • • 外包成员能否检索核心仓库代码
  • • 客服能否看到支付风控策略
  • • 不同租户的一线运维能否看到共享平台的内部实现

如果 ACL 只是一个后置过滤器,这套系统迟早出问题。

我们的原则很简单:

  • • 没权限的数据,检索阶段就不让命中
  • • 没权限的引用,输出层根本不展示
  • • 所有问答保留审计日志,记录“谁在什么时间问了什么、命中了哪些证据”

企业级知识库做到最后,本质上是“检索系统 + 权限系统 + 证据系统”的组合,而不是一个单纯的聊天前端。


七、Kubernetes 上的部署与运维:别只盯着模型,也要盯住链路

源码知识库上生产后,最怕的不是单点故障,而是链路中某个环节悄悄变慢、变旧、变脏。

所以部署时建议把系统拆成几个独立可伸缩的服务:

  • • query-orchestrator
  • • retrieval-coordinator
  • • rerank-service
  • • llm-gateway
  • • index-builder
  • • snapshot-controller

一个更贴近生产的部署片段如下:

apiVersion: apps/v1
kind:
 Deployment
metadata:

  name:
 retrieval-coordinator
spec:

  replicas:
 4
  selector:

    matchLabels:

      app:
 retrieval-coordinator
  template:

    metadata:

      labels:

        app:
 retrieval-coordinator
    spec:

      containers:

        -
 name: app
          image:
 registry.internal/kb/retrieval-coordinator:v2.4.1
          ports:

            -
 containerPort: 8080
          env:

            -
 name: ACTIVE_SNAPSHOT
              valueFrom:

                configMapKeyRef:

                  name:
 knowledge-engine
                  key:
 active_snapshot
          resources:

            requests:

              cpu:
 "2"
              memory:
 "4Gi"
            limits:

              cpu:
 "4"
              memory:
 "8Gi"
          readinessProbe:

            httpGet:

              path:
 /readyz
              port:
 8080
---

apiVersion:
 autoscaling/v2
kind:
 HorizontalPodAutoscaler
metadata:

  name:
 retrieval-coordinator
spec:

  scaleTargetRef:

    apiVersion:
 apps/v1
    kind:
 Deployment
    name:
 retrieval-coordinator
  minReplicas:
 4
  maxReplicas:
 20
  metrics:

    -
 type: Resource
      resource:

        name:
 cpu
        target:

          type:
 Utilization
          averageUtilization:
 65

这里有两个经验尤其重要:

第一,Embedding、重排、生成不要混在一个服务里。

它们的资源模型完全不同:

  • • Embedding 偏吞吐
  • • 重排偏低延迟
  • • 生成偏长连接和 token 流控

拆开后更容易做弹性扩缩和资源治理。

第二,快照发布不要靠重启服务来生效。

更好的方式是:

  • • 由 snapshot-controller 统一登记新快照
  • • 查询服务通过配置热更新切换 active_snapshot
  • • 切换过程保留旧快照一段时间,方便回滚

这样能避免发布窗口里的读写不一致。

7.1 必看的核心监控指标

如果只能选最关键的指标,我建议盯这几类:

  • • 检索空结果率
  • • 引用缺失率
  • • Faithfulness 分数
  • • 正反馈率和追问率
  • • Query 改写触发率
  • • 各检索子链路 P95/P99 延迟
  • • 快照切换后的质量波动
  • • 单问题平均 token 成本

对 RAG 系统来说,只有“模型延迟”和“接口 QPS”是远远不够的。你必须知道系统到底是“找不到证据”,还是“找到了但排序错了”,还是“生成阶段跑偏了”。


八、从 FAQ 替代品到企业知识基础设施:一条真实的演进路线

很多团队一开始都会问:

我们是不是一上来就要做这么复杂?

答案通常是否定的。大多数系统都应该按阶段演进。

第一阶段:先跑通单仓库、单文档空间的问答闭环

目标不是覆盖全公司知识,而是验证三个问题:

  • • 用户到底在问什么
  • • 现有知识是否足够支撑回答
  • • 哪一类证据最有价值

这个阶段重点是把反馈链路建起来,而不是追求架构完美。

第二阶段:引入源码解析和多索引检索

当你发现用户的问题开始指向:

  • • 某个方法
  • • 某个状态机分支
  • • 某个错误码
  • • 某个灰度配置

就说明你已经不能只靠文档了,这时应该引入符号级解析和混合检索。

第三阶段:建立快照发布、评测和回滚机制

当系统开始服务真实业务,最重要的不是“偶尔答对”,而是“稳定地不犯大错”。

这时必须补齐:

  • • 快照化索引
  • • 评测基线
  • • 灰度发布
  • • 一键回滚
  • • 问答审计

第四阶段:把它升级成企业知识引擎

再往后,这套系统就不只是客服助手或研发问答工具了,它会逐步承担更多角色:

  • • 一线运维排障助手
  • • Oncall 事故辅助系统
  • • 新人 onboarding 导航器
  • • 研发编码辅助知识层
  • • 业务流程解释器

到这一步,你建设的已经不是“一个问答应用”,而是整个企业的知识基础设施。


九、总结:RAG 的真正门槛,不在模型,而在工程闭环

回到文章开头那个问题。

为什么 FAQ 会死?

不是因为 FAQ 这种形式天然不好,而是因为现代系统里的知识更新速度,已经远快于人工维护静态问答的速度。只要你的业务还在迭代、代码还在变、配置还在灰度、事故还在发生,FAQ 就注定滞后。

而源码知识库之所以有价值,也不只是因为它接了大模型,而是因为它做到了四件 FAQ 永远做不到的事:

  • • 把源码、文档、配置和事故结论放到同一个知识闭环里
  • • 让检索结果跟着版本一起演化,而不是永远停在历史快照
  • • 让回答必须附带证据,而不是只输出“像答案的话”
  • • 让系统在高并发、强权限、可审计的条件下长期运行

如果你正准备在公司内部落地 RAG,我更建议你把它当作“知识引擎工程”来做,而不是“聊天机器人项目”。

真正拉开差距的,从来不是 Prompt 写得多漂亮,也不是模型参数量多大,而是下面这些工程动作你有没有做好:

  • • 代码和文档有没有被加工成可检索对象
  • • 检索和权限是否前置融合
  • • 索引是否快照化、可灰度、可回滚
  • • 回答是否强制证据约束
  • • 线上是否有完整的评测、观测和反馈闭环

当这些基础能力具备以后,FAQ 不是被“替代”了,而是被升级成了一套真正能跟着系统一起成长的智能知识体系。

这时候,RAG 才算真正从 Demo 走进生产。

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-15 15:49:50 HTTP/1.1 GET : https://www.yeyulingfeng.com/a/861210.html
  2. 运行时间 : 0.116455s [ 吞吐率:8.59req/s ] 内存消耗:4,812.59kb 文件加载:145
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=5cd528d701704dadfbf579d2904b0fe3
  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.000528s ] mysql:host=127.0.0.1;port=3306;dbname=wenku;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000796s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000298s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000251s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000508s ]
  6. SELECT * FROM `set` [ RunTime:0.000195s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000492s ]
  8. SELECT * FROM `article` WHERE `id` = 861210 LIMIT 1 [ RunTime:0.000474s ]
  9. UPDATE `article` SET `lasttime` = 1784101790 WHERE `id` = 861210 [ RunTime:0.000891s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.000228s ]
  11. SELECT * FROM `article` WHERE `id` < 861210 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000430s ]
  12. SELECT * FROM `article` WHERE `id` > 861210 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.005437s ]
  13. SELECT * FROM `article` WHERE `id` < 861210 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.001195s ]
  14. SELECT * FROM `article` WHERE `id` < 861210 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.001178s ]
  15. SELECT * FROM `article` WHERE `id` < 861210 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.000624s ]
0.118165s