乐于分享
好东西不私藏

Spring AI 入门教程(四) Tool calling前言

Spring AI 入门教程(四) Tool calling前言

在前几篇文章中,我们学习了如何使用 Spring AI 进行基础的对话、流式响应、会话记忆等功能。但在实际应用中,AI 模型往往需要与外部系统交互,获取实时信息或执行特定操作。这就是 Tool Calling(工具调用) 的核心价值所在。

本文将深入探讨 Spring AI 的工具调用机制,从基础概念到高级特性,帮助您构建功能强大的 AI 应用。


一、什么是 Tool Calling?

1.1 核心概念

Tool Calling 是指 AI 模型在执行任务时,可以调用预定义的工具(函数/方法)来获取信息或执行操作。这是一种让 AI "突破"自身知识限制的重要机制。

典型场景:

  • • 📅 获取当前时间、日期等实时信息
  • • 🌤️ 查询天气、股票等动态数据
  • • 💾 执行数据库增删改查操作
  • • 🔔 设置闹钟、发送通知等系统操作
  • • 📊 检索企业内部文档(RAG)

1.2 工作原理

用户提问 → AI 分析 → 决定调用工具 → Spring AI 执行工具 → 返回结果给 AI → AI 生成最终响应

关键组件:

  1. 1. Tool Definition:工具定义(名称、描述、参数 Schema)
  2. 2. Tool Callback:工具回调(实际执行的 Java 方法)
  3. 3. ToolCallingManager:工具执行管理器
  4. 4. ToolCallAdvisor:工具调用拦截器(自动模式)

二、快速开始:最简单的工具调用

2.1 使用 @Tool 注解

Spring AI 提供了最简洁的方式——通过 @Tool 注解将普通方法转换为 AI 可调用的工具。

@Slf4j
publicclassDateTimeTools {

/**
     * 获取当前日期时间
     */

@Tool(description = "获取用户时区的当前日期和时间")
    String getCurrentDateTime() {
        log.info("工具调用: getCurrentDateTime");
LocalDateTimenow= LocalDateTime.now();
return now.atZone(LocaleContextHolder.getTimeZone().toZoneId()).toString();
    }

/**
     * 设置闹钟
     */

@Tool(description = "为用户设置闹钟")
voidsetAlarm(@ToolParam(description = "ISO-8601 格式的时间") String time) {
        log.info("设置闹钟: {}", time);
LocalDateTimealarmTime= LocalDateTime.parse(time, DateTimeFormatter.ISO_DATE_TIME);
        System.out.println("闹钟已设置为 " + alarmTime);
    }
}

2.2 在 ChatClient 中使用

@RestController
@RequestMapping("/tool")
publicclassToolCallingController {

@Resource
private ZhiPuAiChatModel zhiPuAiChatModel;

@RequestMapping("/datetime-now")
public String getCurrentDateTime() {
ChatClientchatClient= ChatClient.create(zhiPuAiChatModel);

Stringresponse= chatClient.prompt("What day is tomorrow?")
                .tools(newDateTimeTools())  // 注册工具
                .call()
                .content();

return response;
    }
}

执行流程:

  1. 1. 用户问:"明天是星期几?"
  2. 2. AI 分析后决定调用 getCurrentDateTime 工具
  3. 3. Spring AI 执行该方法,获取当前时间
  4. 4. 将结果返回给 AI 模型
  5. 5. AI 根据当前时间计算明天是星期几,生成最终响应

三、工具注册的三种方式

3.1 方式一:@Tool 注解(推荐用于简单工具)

publicclassMyTools {
@Tool(description = "计算数学表达式")
public String calculate(String expression) {
// 实现逻辑
    }
}

// 使用时
chatClient.prompt("计算 6 * 8")
    .tools(newMyTools())
    .call()
    .content();

优点:

  • • ✅ 简单直观,代码可读性好
  • • ✅ 支持任意可见性(public、private 均可)
  • • ✅ 自动生成 JSON Schema

缺点:

  • • ❌ 不支持依赖注入
  • • ❌ 工具必须在运行时显式传递

3.2 方式二:Function Bean(推荐用于复杂工具)

这是 Spring AI 的高级特性,通过 Spring Bean 注册工具,支持依赖注入和全局共享。

步骤 1:定义 Function Bean

@Configuration
publicclassToolCallingConfig {

publicstaticfinalStringCURRENT_WEATHER_TOOL="currentWeather";

@Bean(CURRENT_WEATHER_TOOL)
@Description("Get the current weather for a given location")
public Function<WeatherRequest, WeatherResponse> currentWeather() {
returnnewWeatherService();
    }
}

步骤 2:实现 Function 接口

@Slf4j
publicclassWeatherServiceimplementsFunction<WeatherRequest, WeatherResponse> {

@Override
public WeatherResponse apply(WeatherRequest request) {
        log.info("查询天气: location={}, unit={}", request.location(), request.unit());

// 模拟天气数据(实际应调用真实 API)
doubletemperature= getTemperatureFromApi(request.location(), request.unit());
returnnewWeatherResponse(temperature, request.unit());
    }

publicrecordWeatherRequest(
        @ToolParam(description = "城市名称")
 String location,
@ToolParam(description = "温度单位") Unit unit
    ) {}

publicrecordWeatherResponse(double temp, Unit unit) {}
}

步骤 3:通过工具名称引用

@RequestMapping("/weather-bean")
public String getWeatherByBean(String location) {
ChatClientchatClient= ChatClient.create(zhiPuAiChatModel);

Stringresponse= chatClient.prompt("What's the weather in " + location + "?")
            .toolNames(ToolCallingConfig.CURRENT_WEATHER_TOOL)  // 通过名称引用
            .call()
            .content();

return response;
}

底层原理:

  • • Spring AI 的 SpringBeanToolCallbackResolver 会扫描所有 Function 类型的 Bean
  • • 自动将其转换为 ToolCallback
  • • 使用 DelegatingToolCallbackResolver 在运行时动态解析工具名称

优点:

  • • ✅ 支持依赖注入(可注入 Service、Repository)
  • • ✅ 工具可被多个 ChatClient 共享
  • • ✅ 工具名称集中管理

缺点:

  • • ❌ 缺少编译时类型安全(工具名称是字符串)
  • • ❌ 配置相对复杂

3.3 方式三:Lambda 表达式(适合简单计算)

@Bean("mathCalculator")
@Description("Perform basic mathematical calculations")
public Function<MathRequest, MathResponse> mathCalculator() {
return request -> {
double result;
switch (request.operation()) {
case"+" -> result = request.a() + request.b();
case"-" -> result = request.a() - request.b();
case"*" -> result = request.a() * request.b();
case"/" -> result = request.a() / request.b();
default -> thrownewIllegalArgumentException("Unsupported operation");
        }
returnnewMathResponse(result);
    };
}

// 使用
chatClient.prompt("What is 6 * 8?")
    .toolNames("mathCalculator")
    .call()
    .content();

四、高级特性

4.1 ToolContext:传递上下文信息

在某些场景下,我们需要向工具传递额外的上下文信息(如租户 ID、用户权限),但这些信息不应该发送给 AI 模型。这时可以使用 ToolContext

@Slf4j
publicclassCustomerTools {

@Tool(description = "Retrieve customer information by ID")
    Customer getCustomerInfo(
@ToolParam(description = "客户 ID") Long id,
            ToolContext toolContext  // 最后一个参数,由 Spring AI 自动注入
    )
 {
// 从上下文中获取租户 ID
StringtenantId= (String) toolContext.getContext().get("tenantId");
        log.info("Tenant ID: {}", tenantId);

// 根据租户 ID 和客户 ID 查询数据(多租户隔离)
Customercustomer= customerRepository.findByIdAndTenant(id, tenantId);
return customer;
    }
}

使用时传递上下文:

Map<String, Object> context = Map.of(
"tenantId""acme-corp",
"requestId", UUID.randomUUID().toString()
);

Stringresponse= chatClient.prompt("Tell me about customer 42")
        .tools(newCustomerTools())
        .toolContext(context)  // 传递上下文
        .call()
        .content();

应用场景:

  • • 🔐 多租户系统:传递 tenantId 实现数据隔离
  • • 👤 权限控制:传递 userId、roles 进行权限校验
  • • 📝 审计日志:传递 requestId、sessionId 用于追踪

4.2 Return Direct:直接返回工具结果

默认情况下,工具执行结果会发送回 AI 模型,让模型生成自然语言响应。但有些场景需要直接返回原始数据,这时可以使用 returnDirect=true

@Tool(
    description = "Retrieve customer information by ID",
    returnDirect = true  // 直接返回,不经过 AI 处理
)

Customer getCustomerInfo(Long id, ToolContext toolContext) {
return customerRepository.findById(id);
}

对比:

特性
默认行为 (returnDirect=false)
Return Direct (returnDirect=true)
执行流程
AI → 工具 → AI → 用户
AI → 工具 → 用户
返回内容
自然语言
原始数据(JSON/对象)
适用场景
对话式 AI
RAG、数据库查询、精确数据

重要注意事项:

  • • ⚠️ 如果一次请求调用了多个工具,所有工具的 returnDirect 都必须为 true 才能直接返回
  • • ⚠️ 直接返回的是原始工具返回值,不是自然语言

适用场景:

  • • 📚 RAG 检索:检索到的文档片段直接返回
  • • 💾 数据库查询:精确的结构化数据直接返回
  • • 🔒 敏感信息:保证数据完整性和准确性

4.3 可选参数:防止 AI 幻觉

某些参数不是必需的,应该标记为 required=false,避免 AI 编造不存在的值。

@Tool(description = "Update customer information")
voidupdateCustomerInfo(
@ToolParam(description = "客户 ID") Long id,
@ToolParam(description = "客户姓名") String name,
@ToolParam(description = "客户邮箱(可选)", required = false) String email
)
 {
// 更新逻辑
}

为什么需要可选参数?

如果参数标记为 required=true,但用户没有提供该值,AI 模型可能会产生幻觉(hallucination),编造一个看似合理的值。将非必需参数标记为 optional 可以避免这个问题。


五、用户控制的工具执行

5.1 框架控制 vs 用户控制

Spring AI 提供了两种工具执行模式:

框架控制(Framework-Controlled)

// 默认行为:Spring AI 自动处理工具调用循环
Stringresponse= chatClient.prompt("What day is tomorrow?")
        .tools(newDateTimeTools())
        .call()
        .content();

优点:

  • • ✅ 简单易用,一行代码搞定
  • • ✅ 自动处理工具调用循环
  • • ✅ 适合大多数场景

用户控制(User-Controlled)

// 禁用自动工具执行
ZhiPuAiChatOptionschatOptions= ZhiPuAiChatOptions.builder()
        .toolCallbacks(ToolCallbacks.from(newDateTimeTools()))
        .internalToolExecutionEnabled(false)  // 关键配置
        .build();

// 手动执行工具调用循环
Promptprompt=newPrompt(
    List.of(newSystemMessage("You are helpful."), newUserMessage("What day is tomorrow?")),
    chatOptions
);

ChatResponsechatResponse= zhiPuAiChatModel.call(prompt);

// 循环执行工具调用
while (chatResponse.hasToolCalls()) {
ToolExecutionResultresult= toolCallingManager.executeToolCalls(prompt, chatResponse);

    prompt = newPrompt(result.conversationHistory(), chatOptions);
    chatResponse = zhiPuAiChatModel.call(prompt);
}

StringfinalResponse= chatResponse.getResult().getOutput().getText();

适用场景:

  • • 🔧 需要在工具执行前后添加自定义逻辑(日志、监控、权限检查)
  • • 📊 需要访问工具执行的中间结果
  • • ⚙️ 需要自定义错误处理策略
  • • 🔗 需要与外部系统集成(消息队列、事件总线)

5.2 结合 ChatMemory 的用户控制执行

将用户控制的工具执行与 ChatMemory 结合,可以实现有状态的多轮工具调用对话。

@RequestMapping("/memory-tool-execution")
public String memoryWithToolExecution() {
ToolCallingManagertoolCallingManager= ToolCallingManager.builder().build();
StringconversationId= UUID.randomUUID().toString();

// 配置选项
ZhiPuAiChatOptionschatOptions= ZhiPuAiChatOptions.builder()
            .toolCallbacks(ToolCallbacks.from(newDateTimeTools()))
            .internalToolExecutionEnabled(false)
            .build();

// 创建初始提示词
Promptprompt=newPrompt(
        List.of(
newSystemMessage("You are a helpful assistant."),
newUserMessage("What day is tomorrow?")
        ),
        chatOptions
    );

// 将初始消息添加到 ChatMemory
    chatMemory.add(conversationId, prompt.getInstructions());

// 从 ChatMemory 获取完整对话历史
PromptpromptWithMemory=newPrompt(chatMemory.get(conversationId), chatOptions);

// 第一次调用模型
ChatResponsechatResponse= zhiPuAiChatModel.call(promptWithMemory);

// 循环执行工具调用
intmaxIterations=5;
intiteration=0;
while (chatResponse.hasToolCalls() && iteration < maxIterations) {
        iteration++;

// 如果有工具调用,将 AI 的响应添加到记忆
if (chatResponse.hasToolCalls()) {
            chatMemory.add(conversationId, chatResponse.getResult().getOutput());
        }

// 执行工具调用
ToolExecutionResulttoolExecutionResult=
            toolCallingManager.executeToolCalls(promptWithMemory, chatResponse);

// 将工具执行结果添加到 ChatMemory
        chatMemory.add(conversationId, 
            toolExecutionResult.conversationHistory()
                .get(toolExecutionResult.conversationHistory().size() - 1));

// 更新提示词
        promptWithMemory = newPrompt(chatMemory.get(conversationId), chatOptions);

// 再次调用模型
        chatResponse = zhiPuAiChatModel.call(promptWithMemory);
    }

// 继续对话:询问之前的问题
    chatMemory.add(conversationId, newUserMessage("What did I ask you earlier?"));
ChatResponsenewResponse= zhiPuAiChatModel.call(
newPrompt(chatMemory.get(conversationId))
    );

return newResponse.getResult().getOutput().getText();
}

优势:

  • • ✅ 支持复杂的多轮工具调用场景
  • • ✅ 保持完整的对话上下文
  • • ✅ 可以查询之前的对话内容
  • • ✅ 适合构建智能 Agent 系统

六、组合多种工具

在实际应用中,我们经常需要同时使用多种类型的工具。

@RequestMapping("/combined-tools")
public String combinedTools() {
ChatClientchatClient= ChatClient.create(zhiPuAiChatModel);

Stringresponse= chatClient.prompt(
"What's the current date and time, and what's the weather in Beijing? " +
"Also, can you calculate 15 * 7 for me?"
        )
        .tools(newDateTimeTools())  // @Tool 注解工具
        .toolNames(  // Bean 注册工具
            ToolCallingConfig.CURRENT_WEATHER_TOOL,
            ToolCallingConfig.MATH_CALCULATOR_TOOL
        )
        .call()
        .content();

return response;
}

关键点:

  • • 🔄 可以同时使用 @Tool 注解工具和 Bean 注册工具
  • • 🎯 AI 模型会自动选择需要的工具并编排调用顺序
  • • ⚡ 多个工具可以协同完成复杂任务

七、最佳实践

7.1 工具设计原则

  1. 1. 单一职责:每个工具只做一件事
    // ✅ 好:单一职责
    @Tool(description = "获取当前时间")
    String getCurrentTime() { ... }

    @Tool(description = "获取当前日期")
    String getCurrentDate() { ... }

    // ❌ 不好:职责混乱
    @Tool(description = "获取时间或日期")
    String getTimeOrDate(String type) { ... }
  2. 2. 详细描述:为工具和参数提供清晰的描述
    @Tool(description = "获取指定城市的当前天气,返回温度和湿度信息")
    WeatherResponse getWeather(
    @ToolParam(description = "城市名称,如:北京、上海、New York") String city,
    @ToolParam(description = "温度单位:C=摄氏度,F=华氏度") Unit unit
    )
     { ... }
  3. 3. 使用常量定义工具名称
    publicclassToolCallingConfig {
    publicstaticfinalStringCURRENT_WEATHER_TOOL="currentWeather";

    @Bean(CURRENT_WEATHER_TOOL)
    public Function<...> currentWeather() { ... }
    }

    // 使用时
    .toolNames(ToolCallingConfig.CURRENT_WEATHER_TOOL)
  4. 4. 合理设置可选参数
    // ✅ 好:email 是可选的
    @ToolParam(description = "邮箱(可选)", required = false) String email

    // ❌ 不好:可能导致 AI 幻觉
    @ToolParam(description = "邮箱") String email

7.2 安全性考虑

  1. 1. 工具执行边界:AI 模型只能请求调用工具,不能直接访问工具 API
  2. 2. 权限校验:在工具内部进行权限检查
    @Tool(description = "删除用户")
    voiddeleteUser(Long userId, ToolContext context) {
    Stringrole= (String) context.getContext().get("userRole");
    if (!"ADMIN".equals(role)) {
    thrownewSecurityException("Permission denied");
        }
    // 执行删除
    }
  3. 3. 输入验证:始终验证工具参数
    @Tool(description = "执行命令")
    String executeCommand(String command) {
    // 白名单验证
    if (!ALLOWED_COMMANDS.contains(command)) {
    thrownewIllegalArgumentException("Command not allowed");
        }
    // 执行
    }

7.3 性能优化

  1. 1. 懒加载工具:只在需要时注册工具
  2. 2. 缓存工具结果:对于频繁调用的工具,考虑缓存结果
  3. 3. 异步工具:对于耗时操作,考虑使用异步执行

八、常见问题

Q1: 工具没有被调用怎么办?

可能原因:

  1. 1. 工具描述不够清晰,AI 不知道何时调用
  2. 2. 提示词中没有明确暗示需要调用工具
  3. 3. 工具参数 Schema 不正确

解决方案:

  • • 提供更详细的工具描述
  • • 在提示词中暗示可能需要工具
  • • 检查 @ToolParam 的描述是否准确

Q2: 如何调试工具调用?

方法:

  1. 1. 启用日志:查看工具调用日志
    logging.level.cn.dianyu.ai.myspringai.toolcalling=DEBUG
  2. 2. 检查 JSON Schema:确保生成的 Schema 符合预期
  3. 3. 使用用户控制模式:逐步跟踪工具执行过程

Q3: 如何处理工具执行异常?

Spring AI 提供了 ToolExecutionExceptionProcessor 来处理异常:

@Tool(description = "查询数据")
String queryData(String key) {
try {
return dataRepository.findByKey(key);
    } catch (Exception e) {
        log.error("Query failed", e);
thrownewRuntimeException("Failed to query data: " + e.getMessage());
    }
}

异常会被捕获并返回给 AI 模型,AI 可以根据错误信息调整策略。


九、总结

本文详细介绍了 Spring AI 的工具调用机制,包括:

✅ 基础概念:什么是 Tool Calling,工作原理是什么
✅ 三种注册方式:@Tool 注解、Function Bean、Lambda 表达式
✅ 高级特性:ToolContext、Return Direct、可选参数
✅ 执行模式:框架控制 vs 用户控制
✅ 整合 ChatMemory:实现有状态的多轮工具调用
✅ 最佳实践:工具设计、安全性、性能优化

核心要点:

  1. 1. 工具调用让 AI 能够突破自身限制,与外部系统交互
  2. 2. 根据场景选择合适的工具注册方式
  3. 3. 合理使用 ToolContext 和 Return Direct 提升灵活性
  4. 4. 用户控制模式适合需要精细控制的复杂场景
  5. 5. 始终遵循最佳实践,确保工具的安全性和可维护性

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-06-05 13:30:52 HTTP/1.1 GET : https://www.yeyulingfeng.com/a/715388.html
  2. 运行时间 : 0.119014s [ 吞吐率:8.40req/s ] 内存消耗:4,732.29kb 文件加载:145
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=4b55338b555c81e91b2e45b247cc6a29
  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.000427s ] mysql:host=127.0.0.1;port=3306;dbname=wenku;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000697s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000323s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000295s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000482s ]
  6. SELECT * FROM `set` [ RunTime:0.000193s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000571s ]
  8. SELECT * FROM `article` WHERE `id` = 715388 LIMIT 1 [ RunTime:0.000534s ]
  9. UPDATE `article` SET `lasttime` = 1780637452 WHERE `id` = 715388 [ RunTime:0.000777s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.000217s ]
  11. SELECT * FROM `article` WHERE `id` < 715388 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000434s ]
  12. SELECT * FROM `article` WHERE `id` > 715388 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000354s ]
  13. SELECT * FROM `article` WHERE `id` < 715388 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.000648s ]
  14. SELECT * FROM `article` WHERE `id` < 715388 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.000812s ]
  15. SELECT * FROM `article` WHERE `id` < 715388 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.001179s ]
0.120743s