当前位置:首页>python>为什么不用 Python?我是如何用几百行 Go 代码撸出一个生产级 AI 智能体编排引擎的

为什么不用 Python?我是如何用几百行 Go 代码撸出一个生产级 AI 智能体编排引擎的

  • 2026-06-21 06:57:15
为什么不用 Python?我是如何用几百行 Go 代码撸出一个生产级 AI 智能体编排引擎的

一、这个项目是什么

GopherGraph 是一个用 Go 语言写的多智能体工作流编排引擎。

仓库地址:https://github.com/unclesam-ly/GopherGraph

如果不用技术术语来讲,可以把它理解成一个“流程图执行器”:你先把一个任务拆成多个步骤,每个步骤由一个函数负责处理;然后告诉系统这些步骤之间怎么连接、什么时候分支、什么时候并发、什么时候暂停等人工确认。最后,GopherGraph 会按照你定义好的路线,把整个流程一步一步跑完。

项目 README 里把它称为 Code-as-Graph,也就是“代码即图”。这里的“图”不是图片,而是计算机科学里的 graph:由节点和边组成的结构。

  • 节点:一个具体的处理步骤,比如翻译、审核、发布。
  • 边:节点之间的连接关系,比如翻译完成后去审核。
  • 状态:整个流程中不断被传递和修改的数据,比如原文、译文、审核意见。
  • 路由:根据当前状态决定下一步去哪,比如审核通过就发布,审核失败就退回重写。

这个项目的目标不是做一个聊天机器人,也不是直接调用大模型 API。它更像是一个底层框架,帮助开发者把多个 Agent、多个处理步骤和人工审批流程组织起来。

二、为什么不用 Python,为什么要自己写一个?

提到多智能体(Multi-Agent)编排,大家的第一反应往往是 Python 生态的明星项目:LangChain 和 LangGraph。既然 Python 生态这么繁荣,为什么还要用 Go 自己“造轮子”写一个 GopherGraph 呢?

核心原因在于语言特性与生产环境的匹配度

1. 动态类型的“盲盒”灾难

Python 框架在传递 Agent 状态时,底层通常是一个松散的字典(dict 或 map[string]any)。在几十上百个节点的复杂工作流中,你很难确定上一个节点到底往字典里塞了什么键值,漏写一个字母就会导致运行时直接崩溃。 而 Go 语言在 1.18 引入泛型后,GopherGraph 利用泛型实现了 100% 的编译期类型安全。状态传递不再是盲盒,每个字段都有强类型约束。写错类型?代码根本编译不过去,直接把隐患扼杀在摇篮里。

2. Python 并发模型的天然缺陷

真实的业务工作流经常需要高并发(例如,同时调用多个大模型比对结果)。Python 语言由于全局解释器锁(GIL)的存在,其多线程并不是真正的并行;而协程(asyncio)在处理某些同步阻塞的网络请求时又很容易出问题。 相反,Go 语言天生为高并发而生。GopherGraph 底层完全基于 Go 的 goroutine 和 channel 构建并发分支,并深度融合了 context.WithCancel。这意味着在并发请求大模型时,如果其中一个分支失败报错,引擎会立刻触发“短路机制”,强行取消并中断其他仍在运行的分支,极大节省了不必要的时间等待和高昂的 API 调用费(Token)。

3. 数据竞态(Data Race)与状态共享的优雅解法

在 Python 中,如果多个线程并发修改同一个共享字典,很容易引发数据错乱。要在 Go 中避免并发读写切片或 Map 引发程序崩溃,传统做法是到处加互斥锁(Mutex),但这会让代码变得臃肿且影响性能。 GopherGraph 提供了一套名为 **StateCloner(状态克隆器)**的机制,在进入并发分流前,自动为每一个 Goroutine 拷贝独立的“状态副本”。大家各自修改自己的副本,最后通过合并函数汇总。这种设计完美契合了 Go 的并发哲学:通过通信共享内存,而不是通过共享内存来通信

4. 极致轻量,零第三方依赖

很多 Python 框架动辄依赖几十个庞大的第三方包,甚至强制绑定某些 LLM 厂商的 SDK,这使得项目越来越重。而 GopherGraph 完全只依赖 Go 标准库,没有任何多余的外部依赖,无论是编译体积还是运行时的内存占用,都被压榨到了极低的水平。

这也是作者坚持要自己写一个 GopherGraph 的原因:对于那些对性能、稳定性、并发能力以及工程化类型安全有极高要求的后端微服务架构来说,一套基于 Go 原生特性的轻量级编排引擎是不可或缺的。


现在,我们再来看看为什么必须把流程抽象成“图”。在真实的 AI 业务里,经常会出现这样的流程:

  1. 用户提交一个需求。
  2. 一个 Agent 先理解需求。
  3. 另一个 Agent 生成初稿。
  4. 第三个 Agent 检查质量。
  5. 如果质量不合格,就退回修改。
  6. 如果内容敏感,就暂停等待人工审核。
  7. 审核通过后再发布或执行下一步。

这类流程有几个特点:

  • 不一定是直线执行,可能会循环。
  • 有些步骤可以同时执行,比如同时翻译成英文和日文。
  • 有些步骤必须等待人工确认。
  • 中间状态很重要,不能丢。
  • 出错时要能停止,不能无限跑下去。

普通的函数调用当然也能写出这些逻辑,但代码很容易变成一大堆 if else、回调和状态变量。GopherGraph 的作用,就是把这些复杂关系拆成清晰的节点和连线,让流程结构更容易理解、测试和维护。

三、项目整体结构

这个项目的代码量不大,结构很清晰:

GopherGraph
├── graph.go                 # 定义图、节点、边、路由、并发分支等基础概念
├── engine.go                # 编译后的图如何运行,Start/Resume 的核心调度逻辑
├── engine_options.go        # Engine 增强能力:深拷贝、最大步数、Hook 等
├── checkpoint.go            # 检查点能力:把执行快照保存到 JSON 文件
├── graph_test.go            # 单元测试,覆盖主要能力
├── examples
│   ├── translation/main.go  # 翻译、质检、人工审核、发布示例
│   └── hooks/main.go        # Hook、并发、流式输出示例
├── go.mod
└── README.md

它没有引入第三方依赖,主要依靠 Go 标准库里的 context、sync、encoding/json、os 等能力完成编排、并发、取消和持久化。

四、最核心的几个概念

1. State:贯穿整个流程的共享状态

在 GopherGraph 里,所有节点处理的都是同一个类型的状态。

例如翻译示例里的状态大概是这样:

type TranslationState struct {
    InputText      string
    TranslatedText string
    ReviewNotes    string
    Approved       bool
}

它表示一个翻译任务在流程中需要携带的信息:

  • InputText 是原文。
  • TranslatedText 是译文。
  • ReviewNotes 是审核意见。
  • Approved 表示是否通过审核。

每个节点接收当前状态,处理后返回新的状态。这样做的好处是流程中的数据变化非常明确,不需要到处传零散变量。

更重要的是,GopherGraph 使用 Go 泛型来约束状态类型。创建图时写的是:

g := GopherGraph.NewGraph[TranslationState]()

这意味着这个图只能处理 TranslationState。如果某个节点返回了错误类型,编译阶段就会发现问题。这比 map[string]any 这种松散写法安全很多。

2. Node:流程里的一个步骤

节点本质上就是一个函数,签名是:

type NodeFn[S any] func(ctx context.Context, state S) (S, error)

也就是说,一个节点做三件事:

  1. 接收 context.Context,用于超时、取消等控制。
  2. 接收当前状态 state
  3. 返回新的状态,或者返回错误。

比如一个“翻译员节点”可以读取原文,把译文写回状态;一个“审核员节点”可以检查译文,并把审核结果写回状态。

这种设计很朴素,也很适合 Go:节点不用继承复杂接口,不用关心整个图怎么调度,只需要完成自己的工作。

3. Edge:节点之间的固定连线

最简单的流程是线性的,例如:

A -> B -> C

在代码里可以这样写:

g.AddEdge("A""B")
g.AddEdge("B""C")

这表示 A 执行完就去 B,B 执行完就去 C。如果某个节点没有下一条边,流程就结束。

4. Conditional Edge:根据状态动态决定下一步

真实工作流经常不是固定路线。比如审核通过就发布,审核失败就退回翻译。

GopherGraph 用路由函数解决这个问题:

g.AddConditionalEdges("reviewer", reviewRouter)

reviewRouter 会根据当前状态返回下一个节点名:

func reviewRouter(ctx context.Context, state TranslationState) (stringerror) {
if state.Approved {
return "publisher"nil
    }
return "translator"nil
}

这样,流程就可以根据运行时结果动态转向。

5. Interrupt:在某个节点之前暂停

GopherGraph 支持 Human-in-the-Loop,也就是“人在流程中参与决策”。

例如翻译内容涉及敏感信息时,系统不应该自动发布,而是要暂停下来让人审核。

项目里通过下面这句标记中断点:

g.AddInterrupt("human_review")

这表示工作流准备进入 human_review 节点之前,会先暂停。暂停时,GopherGraph 返回一个 Thread 快照,里面包含当前状态、下一步节点、是否暂停、是否结束等信息。

人工可以查看状态,修改状态,然后调用 Resume 继续执行:

thread, err = cg.Resume(ctx, thread, modifiedState)

这个机制非常适合审批、复核、纠错、人工补充信息等场景。

6. Parallel Edges:并发执行多个分支

有些任务可以同时做,比如一篇文章审核后,同时翻译成英文和日文。

GopherGraph 支持从一个节点分流到多个并发节点:

g.AddParallelEdges(
"reviewer",
    []string{"translate_en""translate_ja"},
"publisher",
    merger,
)

含义是:

  1. reviewer 执行完成后,启动 translate_en 和 translate_ja 两个分支。
  2. 两个分支并发执行。
  3. 分支都完成后,用 merger 合并结果。
  4. 合并后进入 publisher

这种设计既能提升效率,也能保持最终状态可控。并发分支不会随便改同一个共享状态,而是各自处理状态副本,最后由用户提供的合并函数统一汇总。

五、运行过程是怎样的

GopherGraph 的使用流程一般分为四步。

第一步,定义状态:

type MyState struct {
    Query    string
    Response string
    Value    int
}

第二步,创建图并注册节点:

g := GopherGraph.NewGraph[MyState]()
g.AddNode("start", startNode)
g.AddNode("task", taskNode)
g.AddNode("end", endNode)

第三步,建立节点之间的关系:

g.AddEdge("start""task")
g.AddEdge("task""end")

第四步,编译并运行:

cg, err := g.Compile()
thread, err := cg.Start(context.Background(), "start", MyState{})

这里的 Compile 很重要。它会检查图结构是否合法,比如:

  • 有没有注册节点。
  • 普通边的起点和终点是否存在。
  • 条件路由的起点是否存在。
  • 中断节点是否存在。
  • 并发分支的目标节点是否存在。
  • 并发分支是否设置了合并函数。

这一步相当于在真正运行前先做一次体检,避免流程跑到一半才发现节点不存在。

六、Thread:一次执行的快照

GopherGraph 用 Thread 表示一次工作流执行的快照:

type Thread[S any] struct {
    State      S
    NextNode   string
    IsPaused   bool
    IsFinished bool
}

可以把它理解成“当前任务跑到哪里了”的记录。

  • State:当前状态数据。
  • NextNode:下一步要执行哪个节点。
  • IsPaused:是否因为中断而暂停。
  • IsFinished:流程是否已经结束。

这个结构对长流程很有用。比如流程跑到人工审核时暂停,程序可以把 Thread 保存起来;等用户审核完,再用它恢复执行。

七、Engine:在基础图之上的增强包装器

项目里有两个层次:

  • CompiledGraph:基础执行能力。
  • Engine:在基础能力上增加生产环境常用功能。

Engine 主要提供四类增强能力。

1. StateCloner:并发分支里的安全深拷贝

Go 里的结构体值拷贝并不总是“完全独立”。如果结构体里有切片、map、指针等引用类型,浅拷贝后多个分支可能仍然指向同一块底层数据。

比如:

type AgentState struct {
    Messages []string
}

如果两个并发分支都往 Messages 里追加内容,就可能出现数据竞争。

为了解决这个问题,GopherGraph 允许用户注册深拷贝函数:

engine := GopherGraph.NewEngine(cg).
    WithStateCloner(func(s AgentState) AgentState {
        clone := s
        clone.Messages = append([]string{}, s.Messages...)
return clone
    })

这样每个并发分支拿到的都是独立状态副本,最后再由合并函数汇总。

2. MaxSteps:防止死循环

因为 GopherGraph 支持循环,所以也可能因为路由写错导致无限循环。

WithMaxSteps 可以设置最多执行多少个节点:

engine := GopherGraph.NewEngine(cg).WithMaxSteps(100)

超过上限后,引擎会返回错误,而不是一直卡住。这是生产环境里很实用的保护措施。

3. PreNodeHook 和 PostNodeHook:节点前后的钩子

Hook 可以理解成“在节点执行前后顺手做点事”。

例如:

  • 打日志。
  • 记录耗时。
  • 上报监控指标。
  • 给前端推送进度。
  • 接入链路追踪。

示例:

engine := GopherGraph.NewEngine(cg).
    WithPreNodeHook(func(ctx context.Context, name string, s AgentState) {
        fmt.Println("开始执行节点:", name)
    }).
    WithPostNodeHook(func(ctx context.Context, name string, s AgentState) {
        fmt.Println("节点执行完成:", name)
    })

Hook 的好处是不用改节点函数本身。节点继续专注业务逻辑,日志、监控、流式输出这些横向能力由 Engine 统一处理。

八、并发执行和短路取消

GopherGraph 的并发分支使用 goroutine 启动。每个分支运行一个节点,结果通过 channel 收集。

比较关键的是,它使用了 context.WithCancel 实现短路取消:

  • 多个分支并发执行。
  • 如果其中一个分支报错,就调用 cancel()
  • 其他分支如果监听了 ctx.Done(),就能尽快退出。

这对 AI 工作流尤其重要。因为一个 Agent 调用大模型可能很贵、很慢。如果某个必要分支已经失败,其他分支继续跑就可能浪费时间和成本。

测试里也专门验证了这个能力:一个分支立即报错,另一个分支本来要睡 5 秒,但收到取消信号后会提前退出。

九、检查点:把进度保存下来

checkpoint.go 提供了一个通用接口:

type Checkpointer[S any] interface {
    Save(ctx context.Context, threadID string, thread *Thread[S]) error
    Load(ctx context.Context, threadID string) (*Thread[S], error)
}

同时项目内置了 FileCheckpointer,可以把 Thread 保存成 JSON 文件。

这意味着流程中断后,不一定只能存在内存里。你可以把当前进度保存到磁盘:

fc, _ := GopherGraph.NewFileCheckpointer[MyState]("./checkpoints")
fc.Save(context.Background(), "session-123", thread)

程序重启后再加载:

loadedThread, _ := fc.Load(context.Background(), "session-123")
thread, _ = cg.Resume(context.Background(), loadedThread, modifiedState)

这个能力适合长任务、人工审批、后台异步任务等场景。

十、示例一:翻译、质检、人工审核、发布

examples/translation/main.go 展示了一个很典型的 AI 工作流:

translator -> reviewer -> publisher
                 |
                 v
            human_review
                 |
                 v
            translator 或 publisher

流程大致如下:

  1. 翻译员节点读取中文原文,生成日语译文。
  2. 质检员节点审核译文。
  3. 如果审核通过,就进入发布节点。
  4. 如果审核不通过,但只是普通质量问题,就退回翻译员重写。
  5. 如果内容包含敏感词“秘密”,就路由到人工审核。
  6. 人工审核节点被标记为中断点,所以流程会先暂停。
  7. 用户可以输入 y 批准、输入 n 拒绝,或者直接输入修改后的译文。
  8. 系统把人工修改后的状态传给 Resume,继续执行剩余流程。

这个例子展示了 GopherGraph 最有代表性的几个能力:

  • 节点拆分。
  • 条件路由。
  • 循环重试。
  • 人工中断。
  • 恢复执行。

用普通代码当然也能写,但用图的方式表达后,业务流程会更清楚。

十一、示例二:Hook、并发翻译和流式输出

examples/hooks/main.go 展示的是 Engine 的增强能力。

它的流程大致是:

drafter -> reviewer -> translate_en
                    \-> translate_ja
                       -> merger -> publisher

也就是说:

  1. 先起草内容。
  2. 再审阅内容。
  3. 审阅后同时翻译成英文和日文。
  4. 两个翻译分支完成后合并消息日志。
  5. 最后发布。

这个示例重点展示了三件事。

第一,如何用 WithStateCloner 保护并发分支里的切片状态,避免多个 goroutine 同时操作同一个底层数组。

第二,如何用 Pre Hook 和 Post Hook 统计节点耗时、打印进度。

第三,如何通过 context.WithValue 往上下文里放一个 channel,然后在 Post Hook 里写入流式事件。这样前端可以通过 SSE 或 WebSocket 看到“某个节点执行完成”的实时消息。

这说明 GopherGraph 不只是能跑工作流,还考虑到了实际产品里经常需要的可观测性和前端进度展示。

十二、测试覆盖了哪些能力

graph_test.go 里的测试覆盖了项目主要功能:

  • 线性执行:A 执行完去 B。
  • 条件路由:根据状态选择 even 或 odd 分支。
  • 中断和恢复:在 B 前暂停,人工修改状态后继续。
  • 超时取消:节点监听 context,超时后退出。
  • 并发执行:多个分支并发运行后合并。
  • 文件检查点:保存和加载 Thread 快照。
  • 最大步数熔断:检测 A -> B -> A 这类死循环。
  • 并发短路取消:一个分支失败后取消其他分支。
  • 生命周期 Hook:验证 Pre/Post Hook 的触发顺序。

我在本地对核心包执行了测试:

GOCACHE=/Users/mac/IT/GopherGraph/.gocache go test .

结果通过:

ok github.com/unclesam-ly/GopherGraph

不过直接执行 go test ./... 时,示例包会因为 import 路径大小写不一致而失败。当前 go.mod 里是:

module github.com/unclesam-ly/GopherGraph

而示例代码里 import 的是:

github.com/unclesam-LY/GopherGraph

在对大小写敏感的模块解析环境中,这两者会被视为不同路径。这个问题不影响理解项目设计,但如果要让所有示例都能稳定运行,建议统一模块路径大小写。

十三、这个项目的优点

1. 设计简单,学习成本低

整个项目没有复杂的抽象层。核心概念就是 Graph、Node、Edge、Thread、Engine。读完几个文件后,基本就能理解它怎么工作。

2. Go 泛型让状态更安全

许多工作流框架喜欢用动态字典传状态,灵活但容易出错。GopherGraph 用泛型把状态类型固定下来,编译阶段就能发现很多问题。

3. 原生支持循环

很多传统工作流强调 DAG,也就是有向无环图。但 Agent 工作流经常需要“检查不通过就退回重做”,这天然就是循环。GopherGraph 从设计上允许循环,同时通过 MaxSteps 防止意外死循环。

4. 并发模型符合 Go 的习惯

并发分支使用 goroutine 和 channel,取消使用 context。这些都是 Go 开发者熟悉的工具,不需要学习一套陌生运行时。

5. 人工参与流程很自然

中断点设计得很直接:在某个节点前暂停,返回 Thread,外部修改状态,再 Resume。这个模型非常适合审批类业务。

6. 方便接入日志、监控和流式输出

Hook 机制让业务节点不用关心日志、指标、流式推送等横向逻辑,代码边界比较清楚。

十四、目前可以继续改进的地方

这个项目已经具备了一个轻量编排引擎的核心能力,但如果要进一步走向生产级,还可以考虑下面这些方向。

1. 示例 import 路径需要统一

前面提到,go.mod 和示例中的模块路径大小写不一致。建议统一成同一个路径,避免 go test ./... 或 go run examples/... 时出现模块解析问题。

2. Compile 可以做更严格的校验

当前 Compile 会检查大部分静态结构,但条件路由返回的节点名只有运行时才知道。如果希望更安全,可以提供可选的路由目标声明,让编译阶段也能检查条件边可能到达的节点。

3. 持久化可以支持更多后端

现在内置的是文件 JSON。未来可以扩展到 Redis、PostgreSQL、SQLite、S3 等存储。因为已经有 Checkpointer 接口,所以扩展空间比较自然。

4. 可以增加可视化能力

既然工作流本质是一张图,就可以导出 Mermaid、DOT 或 JSON,让用户在页面上看到节点和连线。这样调试复杂流程会更方便。

5. 并发分支可以支持更复杂的子图

目前并发分支执行的是目标节点本身。未来如果支持每个分支是一段子流程,而不只是单个节点,就能表达更复杂的并行工作流。

十五、适合用在什么场景

GopherGraph 比较适合这些场景:

  • 多 Agent 协作。
  • 内容生成、审核、发布流程。
  • 翻译、润色、质检流程。
  • 自动化任务编排。
  • 需要人工审批的 AI 流程。
  • 需要循环重试的任务。
  • 需要并发执行多个子任务的流程。
  • 希望用 Go 构建轻量 AI 后端服务的项目。

它不太适合这些场景:

  • 只需要一次简单函数调用的小任务。
  • 需要完整 Web UI、任务队列、权限系统的大型平台。
  • 需要分布式调度、跨机器执行、复杂定时任务的工作流系统。
  • 不熟悉 Go,且团队主要技术栈是 Python 的项目。

十六、用一句话总结

GopherGraph 是一个轻量、清晰、偏底层的 Go 工作流编排库。它把多 Agent 流程拆成节点和连线,用强类型状态保证数据安全,用条件路由和循环表达复杂业务,用中断恢复支持人工参与,用并发分支提升执行效率。

如果你正在用 Go 写 AI Agent 后端,并且流程已经开始从“单次调用”变成“多步骤协作”,这个项目的设计思路很值得参考。

最新文章

随机文章

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