上下文工程

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 4.1 提示词工程 提示词工程,不是简单的提问,而是一套涵盖指令设计、上下文注入、角色设定和格式控制的综合性技术。 4.1.1 优秀提示词的核心实践 明确角色与目标 范例:“假设你是一位拥有10年经验的市场营销总监,请为一款新型智能手表起草一份面向年轻专业人士的产品介绍文案。” 提供清晰指令与完整上下文 范例:“请总结以下技术文章的核心观点(不超过200字),并列出其中提到的三个关键数据。不要添加个人评论。文章内容如下:[在此处粘贴文章]” 运用范例进行引导 范例:“请分析以下句子的情感及关键对象。范例:输入:‘我喜欢这部电影的剧情。‘输出:{‘sentiment’: ‘positive’, ‘aspect’: ‘plot’}。现在,请分析这个句子:‘这台相机的画质很棒,但电池续航太短。’” 定义结构化输出格式 范例:“请将你的回答组织成JSON格式,包含’product_name’和’key_features’两个字段,其中key_features是一个包含至少三项功能的数组。” 4.1.2 提示词工程的固有局限性 应对动态及长流程任务的局限 应对模型固有的无状态特性 无法突破模型固有的知识边界 长上下文中的信息利用不均衡 正是因为提示词工程有诸多局限性,上下文工程(Context Engineering)应运而生。 4.2 上下文工程 上下文工程的核心理念,在于将AI应用开发的焦点从优化单次交互的指令,转向为模型的每一次推理动态构建一个完整、准确且高效的认知环境。它不再局限于设计静态的提示词模板,而是致力于创建一个系统,确保模型在执行任务时,能够实时获取并利用完成该任务所需的所有相关信息,包括外部知识、历史记忆、可用工具及执行环境。 4.2.1 上下文工程与提示词工程的核心区别 4.2.2 上下文工程的关键组成部分 外部知识库的动态供给 长期与短期记忆系统 工具与能力的扩展 运行时的上下文管理 4.3 RAG技术原理与挑战 4.3.1 RAG的基础范式:三阶段工作流 1、第一阶段:索引(Indexing) 将原始的外部知识转化为机器可高效检索的格式。文档解析与提取,文本分块(Chunking),语义向量化(Embedding),构建向量索引库。 2、第二阶段:检索(Retrieval) 根据用户的自然语言查询,从已构建好的向量索引库中,快速、准确地找出最相关的N个知识块(Top-K)。 3、第三阶段:生成(Generation) 将前一阶段检索到的多个相关知识块与用户的原始查询进行整合,构建一个增强的提示词(Augmented Prompt)。比如: 4.3.2 RAG在工程化落地中面临的挑战 知识单元的完整性与信息密度的抉择 难以精准捕捉模糊、多样的用户意图 召回匹配时难以兼顾语义相关性与关键词精确性 需要探索如何在检索精度与完整性之间取得平衡 应对需要多知识点综合推理的查询实现 4.4 RAG系统优化实践:索引构建 4.4.1 基础文本分块策略 1、固定大小分块 2、基于句子或段落分块 3、语义分块:引入Embedding技术计算相邻文本单元间的语义相似度,在相似度得分显著下降的位置进行切分,从而识别出文本中的语义边界。 4.4.2 高级分块优化策略 1、滑动窗口(Sliding Window) 2、小块检索,大块生成(Small-to-Big) 3、元数据标注与过滤 4.4.3 处理复杂文档的索引策略 文档除了纯文本,还包括表格、图片、代码、脚注等复杂结构。 ...

AI应用开发框架

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 3.1 智能体的定义与主流开发范式 3.1.1 什么是智能体 智能体(Agent)可以理解为一个具备自主理解、规划、记忆和工具使用能力的数字化实体。 我们在前面了解到LLM、MCP,它们和Agent是啥关系呢?LLM是“大脑”,Agent是“身体”,Agent通过MCP协议访问外部能力(Tools / Resources)。 【纯LLM交互】 用户:帮我分析main.py文件 LLM:我无法直接访问文件,请您将文件内容粘贴给我 【Agent交互】 用户:帮我分析main.py文件 Agent:我来读取并分析这个文件 → 调用文件读取工具 → 分析代码结构 → 提供详细分析报告 智能体让AI从一个只会内容生成的语言模型,进化成一个具备自主规划能力的行动者。 3.1.2 智能体的主流开发范式 简单LLM应用:直接调用模型API实现内容生成 单智能体:增加RAG、Tool、Memory等,让模型具备与特定环境交互的能力 工作流:将应用拆分,形成多个独立子智能体,再按照预定义的流程编排起来 多智能体系统:相比于工作流,多智能体系统采用的是模型驱动的、对话式的流程编排,各个子智能体具备更多的自主决策权 3.1.3 单智能体 典型的单智能体架构如下: 单智能体非常依赖底层模型能力。 3.1.4 工作流 1、Chain - 链式工作流 每一步由一个独立的LLM调用完成,并将上一阶段的输出作为下一阶段的输入。 2、Routing - 路由工作流 对输入进行分类,将它们分派到专门设计的下游任务或处理路径。 3.1.5 多智能体系统 由多个具备一定自治能力的Agent组成,每个Agent有自己的角色、能力或工具使用范围。它们之间可以通过消息或上下文进行交互,协同完成复杂目标。 3.2 开发一个简单的智能体 3.2.1 智能体框架选型 Python:LangChain、LlamaIndex、AutoGen、CrewAI,开源的Google ADK、Strands等,阿里云开源的AgentScope等 Java:Spring AI Alibaba等 这本白皮书是阿里出的,后面就用Spring AI Alibaba为例进行介绍。 3.2.2 Spring AI Alibaba中的Agent定义 React Agent,采用ReAct模式,将推理(Reasoning)和行动(Action)交错进行,形成一个动态的“思考-行动-观察”循环。 思考(Thought):LLM分析当前的任务目标、已有的信息和可用的工具,然后生成一个关于下一步应该做什么的推理过程或计划。这个思路过程通常会以自然语言文本展示,解释了它的决策逻辑。 行动(Action):智能体决定调用的外部工具(如搜索引擎、数据库查询API或自定义函数)。它会生成结构化的指令,明确指出要调用的工具名称和所需的参数。 观察(Observation):应用程序执行工具调用,并将返回的结果(如搜索结果、API响应或函数返回值)作为观察信息反馈给智能体。 ...

Allure测试报告完整学习笔记

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 目录 简介 安装Allure Allure测试报告的结构 Java TestNG集成Allure Report Python Pytest集成Allure Report 简介 假如你想让测试报告变得漂亮一点,那你一定会在搜索引擎中找到Allure测试报告的。Allure官方给出了个在线网站,访问以下链接就能一睹为快: https://demo.qameta.io/allure/ 可以在左下角切换为中文报告: 如此好看的测试报告,哪个老板不喜欢呢? 安装Allure 1.在GitHub releases: https://github.com/allure-framework/allure2/releases 或者Maven Central: https://repo.maven.apache.org/maven2/io/qameta/allure/allure-commandline/ 下载安装包并解压。 2.找到bin目录,Windows使用allure.bat,Unix使用allure: 3.为了后续方便使用,可以把bin完整路径添加到系统环境变量PATH中,然后在命令行直接输入allure命令。 官方也给出了通过Linux的ppa、Mac的brew、Windows的scoop的安装方式,不过对于咱们老百姓来说,不如手动下载包来安装实在。 安装后就可以检查是否安装成功了: $ allure --version 2.17.2 因为Allure是用Java写的,所以如果无法运行,那么要检查下有没有安装Java。 Allure测试报告的结构 Overview Categories Suites Graphs Timeline Behaviors Packages Java TestNG集成Allure Report 集成 在Maven的pom.xml中添加: <properties> <aspectj.version>1.8.10</aspectj.version> </properties> <dependencies> <dependency> <groupId>io.qameta.allure</groupId> <artifactId>allure-testng</artifactId> <version>LAST_VERSION</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.20</version> <configuration> <argLine> -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar" </argLine> </configuration> <dependencies> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>${aspectj.version}</version> </dependency> </dependencies> </plugin> </plugins> </build> 然后执行命令: ...

Flask项目发布流程

本文继续对Flask官方教程进行学习,我就直接跳过Templates、Static Files、Blog Blueprint三小节了,因为基本不会在实际项目中用到这些技术,有时间多学习下前端才是。这篇文章把Make the Project Installable、Test Coverage、Deploy to Production这三小节汇总来学习。我觉得这是官方给出的一个Flask项目发布流程,

2026-01-07 · 4 分钟 · 649 字 · 测试开发刚哥 · Python生态 · #Flask

JavaWeb开发基础ServletSession

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 Session是什么 在Web应用程序中,Session(会话)是用于在多个请求之间保持用户状态的一种机制。由于HTTP协议是无状态的,每个请求都是独立的,服务器无法直接知道两个请求是否来自同一个用户。Session通过在服务器端存储用户状态信息,并在客户端使用一个唯一的Session ID来标识用户,从而实现状态保持。 Session工作原理如下: 创建Session:当用户第一次访问Web应用程序时,服务器创建一个新的Session,并生成一个唯一的Session ID 发送Session ID:服务器将Session ID发送给客户端,通常通过HTTP响应头中的Set-Cookie字段 存储Session ID:客户端浏览器将Session ID存储在Cookie中,并在后续请求中将其发送回服务器 识别Session:服务器通过接收到的Session ID识别用户的会话,并从服务器端存储中获取相应的Session数据 四种主要技术 Cookies Hidden Form Field URL Rewriting HttpSession 1. Cookies(Cookie) Cookie是存储在客户端浏览器中的小数据片段。它们会随着每个HTTP请求一起发送到服务器,可以用来存储会话标识符。 工作原理 当用户第一次访问网站时,服务器生成一个唯一的会话ID,并将其作为Cookie发送到客户端浏览器 浏览器存储这个Cookie,并在后续请求中将其发送回服务器 服务器使用Cookie中的会话ID来检索用户的会话数据 优点 对用户透明 由浏览器自动管理 可以存储少量数据 缺点 用户可以在浏览器中禁用Cookie 存储容量有限(通常每个Cookie大约4KB) 如果处理不当,可能存在安全问题(例如Cookie盗窃) 示例 import javax.servlet.http.Cookie; // 在Servlet中设置Cookie Cookie sessionCookie = new Cookie("JSESSIONID", session.getId()); sessionCookie.setMaxAge(30 * 60); // 30分钟 response.addCookie(sessionCookie); // 在Servlet中检索Cookie Cookie[] cookies = request.getCookies(); // 从请求获取Cookie if (cookies != null) { for (Cookie cookie : cookies) { if ("JSESSIONID".equals(cookie.getName())) { String sessionId = cookie.getValue(); // 使用会话ID检索会话数据 } } } Cookie有两种类型: ...

Java官方笔记4类和对象

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 创建类 定义类Bicycle: public class Bicycle { // the Bicycle class has // three fields public int cadence; public int gear; public int speed; // the Bicycle class has // one constructor public Bicycle(int startCadence, int startSpeed, int startGear) { gear = startGear; cadence = startCadence; speed = startSpeed; } // the Bicycle class has // four methods public void setCadence(int newValue) { cadence = newValue; } public void setGear(int newValue) { gear = newValue; } public void applyBrake(int decrement) { speed -= decrement; } public void speedUp(int increment) { speed += increment; } } 创建子类MountainBike继承类Bicycle: ...

JMeter关联陌生又熟悉

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 JMeter关联是什么 JMeter关联,这几个字看着可能会有点陌生,实际上却是工作中经常会做的一件事情,尤其是接口自动化,它指的是把一个接口的响应作为另一个接口的参数,从而把接口关联起来。 JMeter关联是通过后置处理器来实现的,本文将介绍两个主流提取器:正则表达式提取器和JSON JMESPath提取器。 正则表达式提取器 Name 最好有业务含义的名称。 Comments 可以为空的注释。 Apply to 匹配范围。 Main sample and sub-samples 匹配当前父取样器及其子取样器。 Main sample only 仅匹配当前父取样器。 Sub-samples only 仅匹配子取样器。 JMeter Variable Name to use 匹配JMeter变量。 Field to check 匹配响应的字段,共七个选项。 Body:主体,最常用。 Body(unescaped) :替换了所有的html转义符的响应主体内容,注意html转义符处理时不考虑上下文,因此可能有不正确的转换,不太建议使用。 Body as a Document:从不同类型的文件中提取文本,注意这个选项比较影响性能。 Response Headers:响应Headers。 Request Headers:请求Headers。 URL:请求URL。 Response Code:响应代码,比如200、404返回码。 Response Message:响应信息,比如“成功”、“OK”字样。 Name of created variable 创建的变量名,比如变量名为token,通过${token}进行访问。 Regular Expression 正则表达式。 正则表达式可阅读这篇文章进一步了解:https://dongfanger.gitee.io/blog/未分类/001-5分钟轻松学正则表达式.html Template($i$ where i is capturing group number, starts at 1) 用$$引用起来,如果在正则表达式中有多个正则表达式(多个括号括起来的),则可以是$1$、$2$等等,$1$指第一个模板,$2$指第二个模板,依次类推,$0$指全文匹配,$1$$2$指同时取第一个和第二个模板。 ...

JUnit5依赖注入与测试接口

本书作者:测试开发刚哥,文章版权归个人所有,未经授权请勿转载。 依赖注入 以前的JUnit的类构造方法和测试方法都是不能有参数的,JUnit Jupiter有一个颠覆性的改进,就是允许它们有入参,这样就能做依赖注入了。 如果你对pytest的fixture有了解的话,就知道这个技术是多么的强大。 ParameterResolver是一个接口类,类构造方法和测试方法在运行时,必须由被注册的ParameterResolver进行解析。JUnit Jupiter有三个自动注册的内置解析器: TestInfoParameterResolver 参数类型为TestInfo RepetitionInfoParameterResolver 参数类型为RepetitionInfo TestReporterParameterResolver 参数类型为TestReporter TestInfo TestInfo包含the display name, the test class, the test method, and associated tags等信息。 示例: import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInfo; @DisplayName("TestInfo Demo") class TestInfoDemo { TestInfoDemo(TestInfo testInfo) { assertEquals("TestInfo Demo", testInfo.getDisplayName()); } @BeforeEach void init(TestInfo testInfo) { String displayName = testInfo.getDisplayName(); assertTrue(displayName.equals("TEST 1") || displayName.equals("test2()")); } @Test @DisplayName("TEST 1") @Tag("my-tag") void test1(TestInfo testInfo) { assertEquals("TEST 1", testInfo.getDisplayName()); assertTrue(testInfo.getTags().contains("my-tag")); } @Test void test2() { } } RepetitionInfo ...

pytest用例查找原理

当执行pytest命令时,pytest会从project中查找test来执行。本文先从几个路径相关的概念讲起,这样便于理解pytest在遍历路径时的走向。

SpringBoot官方笔记4Web

Most web applications use the spring-boot-starter-web module to get up and running quickly. You can also choose to build reactive web applications by using the spring-boot-starter-webflux module.