AI工具

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 5.1 AI工具简介 5.1.1 Function Calling Function Calling需要编写代码,并且存在规格碎片化、可靠性挑战、工程治理缺位、厂商锁定与迁移成本高等问题。 5.1.2 MCP MCP,Model Context Protocol,模型上下文协议,是一个开放标准,帮助连接AI助手与数据所在的系统,包括内容存储库、业务工具和开发环境。 MCP可以看作是AI应用程序的“USB-C端口”,就像USB-C为连接设备与各种外设提供了标准化方式,MCP为AI模型连接不同数据源和工具提供了标准化方法。 MCP把工具(Tools)、资源(Resources/用于检索与长上下文读写)、提示(Prompts)、会话(Sessions)、取样/推理(Sampling)等能力统一纳入协议语义,并标准化“枚举-描述-请求-响应-权限-审计”的全链路。传输层上,MCP不限定具体载体,既可以通过HTTP/WebSocket,也可以通过stdio等方式交换消息。 5.1.3 MCP就足够了吗 无论是RAG、Function Call还是MCP,其实都是为了让模型获取更多知识,调用更多工具来完成更复杂的事情。MCP并不是万能的,短期内存在不确定性与不同声音,国内是否成为事实标准亦未定。以MCP为协议底座,叠加AI工具接入的最佳实践与企业级安全治理,才能把“可接入”变成“可规模、可移植、可审计”的Agent能力。 5.2 AI工具标准化 5.2.1 MCP协议介绍 MCP协议遵循客户端-服务器(Client-Server)架构,允许AI应用程序通过MCP客户端与多个MCP服务器建立连接。MCP架构包含以下几个部分: MCP Host:协调和管理一个或多个MCP客户端的AI应用程序,如Claude Desktop、Visual Studio Code等,需要通过MCP协议访问数据。 MCP Client:MCP客户端,运行在MCP Host内部,负责与MCP Server建立并维护连接。MCP Host会为每一个MCP Server单独创建一个Client,Client与Server保持一对一连接。 MCP Server:MCP服务器,轻量级程序,通过MCP协议公开特定功能。MCP协议规定了MCP Server可为Client提供工具、资源文件以及提示词模板。 MCP协议采用JSON-RPC 2.0作为通信规范,所有消息均使用JSON格式进行序列化。消息类型包括:Request、Result、Error、Notification。示例如下: 请求: 响应: AI应用程序与MCP Server交互的整体流程如下: 5.2.2 MCP的核心优势 标准化模型与工具的连接方式 灵活的资源调度方式 支持双向、异步通信 支持能力共享 构建方式便捷 5.2.3 MCP面临的挑战 安全问题 大规模应用问题 集中管理问题 5.2.4 可行的解决方案 1、AI网关解决MCP安全问题 下一章将详细介绍AI网关。 2、工具优选和语义检索提升批量MCP的调用质量、降低调用耗时 工具优选:当模型请求在经过网关调用LLM时,携带含有大量工具的tool_calls数组时,网关侧基于Qwen3 Embedding和Qwen3 Reranker的方案,提供工具的精选能力,将tool_calls的数量压缩至目标数量,以提升模型响应速度与工具选择精确性。 语义检索:基于Higress网关的WASM插件机制,通过创建一个“All-in-One”的MCP Server,将用户在网关实例中注册的所有MCP工具进行统一聚合和管理,并提供智能的语义化检索能力。 ...

DRF类视图让你的代码DRY起来

刚开始写views.py模块的代码,一般都是用def定义的函数视图,不过DRF更推荐使用class定义的类视图,这能让我们的代码更符合DRY(Don’t Repeat Yourself)设计原则:

JavaWeb开发基础ServletFilter

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 Filter是什么 Filter用于对请求和响应进行预处理和后处理。Filter链(Filter Chain)允许多个Filter依次处理同一个请求和响应。 Filter的使用场景 日志记录:记录请求和响应的详细信息,例如请求时间、响应时间、请求参数等 安全检查:检查用户是否有权限访问特定资源,例如验证用户身份、检查用户角色等 压缩:对响应内容进行压缩,例如使用GZIP压缩响应数据 字符编码设置:设置请求和响应的字符编码,例如将请求和响应的字符编码设置为UTF-8 输入验证:对请求参数进行验证,例如检查参数是否为空、参数格式是否正确等 Filter Interface Filter接口有3个方法: package javax.servlet; import java.io.IOException; public interface Filter { void init(FilterConfig var1) throws ServletException; void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException; void destroy(); } 容器在启动时创建Filter实例,并调用其init(FilterConfig filterConfig)方法进行初始化。每次请求到达时,容器调用Filter的doFilter(ServletRequest request, ServletResponse response, FilterChain chain)方法进行过滤。容器在关闭时调用Filter的destroy()方法进行清理。 Filter可以通过两种方式进行配置: 1.在web.xml中配置: <filter> <filter-name>MyFilter</filter-name> <filter-class>com.example.MyFilter</filter-class> </filter> <filter-mapping> <filter-name>MyFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> 如果采用web.xml,那么去掉Filter只需要修改web.xml即可,不需要修改代码。 web.xml在低版本Servlet是必须的,在高版本Servlet已经不再需要。 2.使用注解配置: import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; import java.io.IOException; @WebFilter("/*") public class MyFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // 初始化操作 } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 预处理操作 System.out.println("Request received at " + System.currentTimeMillis()); // 继续执行下一个过滤器或目标资源 chain.doFilter(request, response); // 后处理操作 System.out.println("Response sent at " + System.currentTimeMillis()); } @Override public void destroy() { // 清理操作 } } FilterChain Interface Filter接口的doFilter方法,第3个参数类型是FilterChain,它的定义如下: ...

Java官方笔记6继承

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 继承 Java只有单继承,最顶级的父类是Object。 子类会继承父类的fields和methods,而不会继承constructors,因为constructors不属于methods,但是子类可以通过super调用父类的constructor。 子类继承父类的范围是:public、protected、package-private 隐式转换,子类转父类(只有1个爸爸): Object obj = new MountainBike(); 显示转换,父类转子类(有多个子女,所以要明确指定): MountainBike myBike = (MountainBike)obj; 类有field,而接口没有,所以在多继承时就有问题:如果多个类有相同的field,那么子类将不知道用哪一个,而接口不存在这个问题。Java不支持继承多个类,但是可以实现多个接口。 重载 子类的方法跟父类有完全相同的签名和返回类型(也可以是子类),将会覆盖父类方法Override。 如果子类定义了1个static方法,跟父类完全相同,那么父类方法会被隐藏Hide。 Override和Hide是不同的: public class Animal { public static void testClassMethod() { System.out.println("The static method in Animal"); } public void testInstanceMethod() { System.out.println("The instance method in Animal"); } } public class Cat extends Animal { public static void testClassMethod() { System.out.println("The static method in Cat"); } public void testInstanceMethod() { System.out.println("The instance method in Cat"); } public static void main(String[] args) { Cat myCat = new Cat(); Animal myAnimal = myCat; // 隐式转换 Animal.testClassMethod(); // 调的父类 myAnimal.testInstanceMethod(); // 父类对象引用,还是调的子类 } } The static method in Animal The instance method in Cat Override只会调子类方法,而Hide取决于调用方是父还是子,比如这里的myCat,隐式转换为父类Animal后,会调父类的static方法,而调的实例方法却是子类的。(如果不是隐式转换,而是直接给父类实例化,那肯定还是调父类方法) ...

JMeter36个内置函数及11个新增函数介绍

JMeter内置了36个函数,这些函数可以通过函数助手进行编辑和测试。了解这些函数,不仅能提高JMeter的使用熟练度,也有助于知晓测试工具或测试框架通用的函数有哪些,在自主设计时,作为参考借鉴。

Python骚操作从列表推导和生成器表达式开始

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 序列 序列是指一组数据,按存放类型分为容器序列与扁平序列,按能否被修改分为不可变序列与可变序列。 容器序列与扁平序列 容器序列存放的是对象的引用,包括list、tuple、collections.deque。 扁平序列存放的是对象的值,包括str、bytes、bytearray、memoryview和array.array。 扁平序列的值是字符、字节和数值这种基础类型。 不可变序列与可变序列 不可变序列,包括tuple、str、bytes。 可变序列,包括list、bytearray、array.array、collection.deque、memoryview。 下图左边是父类,右边是子类,可以看出可变序列是从不可变序列继承来的,扩展了可变方法: 列表推导 Python语言魅力在于简洁,这能从最常见的创建列表体现出来,比如我们想把字符串"abc"转换成新列表["a", "b", "c"],常规写法: symbols = "abc" codes = [] for symbol in symbols: codes.append(symbol) print(codes) # ["a", "b", "c"] 用到了for循环和列表append方法。实际上可以不用append方法,直接: symbols = "abc" codes = [symbol for symbol in symbols] 这叫做列表推导,是更加Pythonic的写法。 无论是编写效率还是可阅读性,列表推导都更胜一筹,可以说是构建列表的快捷方式。但是不能滥用,通用原则是,如果列表推导的代码超过了两行,就要考虑用append了。这不是规定,完全可以凭借自我喜好来选择。 笛卡尔积是指多个序列中元素所有组合,我们用列表推导来实现笛卡尔积: colors = ["black", "white"] sizes = ["S", "M", "L"] tshirts = [(color, size) for color in colors for size in sizes] 一行代码搞定!Life is short,use Python,list comprehension is wonderful,amazing。 ...

SpringBoot官方笔记6消息

The Spring Framework provides extensive support for integrating with messaging systems, from simplified use of the JMS API using JmsTemplate to a complete infrastructure to receive messages asynchro

teprunner测试平台定时任务这次终于稳了

teprunner测试平台已经有一个多月没有更新了,主要原因是定时任务不够稳定,经过反复试错,找到了解决办法,这次终于稳定了。

tep支持MVC架构实现用例数据分离

大家好,我是刚哥。

2026-01-09 · 2 分钟 · 218 字 · 测试开发刚哥 · 原创项目 · #Tep

自动化用例依赖问题,是个伪命题

伪命题,是指那些表面上看似正确,但实际上是错误的、没有意义的或者根本无法验证的命题。