
1. 引言使用 AI 大模型提示词的重要性毋庸置疑。不管是向 AI 大模型问问题还是围绕 AI 大模型构建应用设计高效的提示词都是其中最重要的一个环节。尤其当你想要在一些具体的业务场景下使用 AI 大模型时你不可能真的像聊天一样慢慢跟大模型软磨硬泡这时一个高效的提示词就显得尤为重要了。即便像 LangChain4j、SpringAI 这些纯面向程序员的 AI 大模型框架其各种工具的背后也是通过定制各种各样的提示词从而让 AI 大模型帮助实现某种功能。如何构建好的提示词呢最好的方式当然是具体情况具体分析。比如这个网站https://www.promptingguide.ai/zh 上面分享了非常多针对不同场景的提示词设计思想和样例。还有阿里云百炼提供了专门优化 Prompt 的应用插件https://bailian.console.aliyun.com/#/prompt-manage。这么多场景这么多模板给你组个 899 的提示词工程课不过分吧但是如此复杂的提示词工程只怕还没开始问 AI自己已经先头晕了。那么有没有一套简单有效的提示词设计模板能够应付大部分的应用场景提升与 AI 交互的质量呢这次楼兰就以 SQL 智能助手场景为例给你分享一套简单有效的提示词设计模板。2. 五步提示词大法其实以 AI 的超强理解力我们完全可以把他当成一个身边的专家来使用。而当你想要向一个专家进行咨询时最类似的生活场景就是你去医院看病要医生给你专业的治疗。去医院看病之前首先要找准科室和医生。这样才能保证医生有足够的专业知识能够看准你的病因。要是你肚子疼结果跑去了口腔科那结果只能是闹个笑话。与此类似当你有问题要咨询 AI 时就要先想清楚你是想要跟谁咨询。这时候给 AI 一个明确且特色鲜明的角色定位可以让 AI 更好的理解你的需求从而提供更专业的帮助。下面我们就用「看病」这个生活场景来类比拆解一套简单有效的五步提示词大法。2.1 第一步指定 AI 角色就像去医院要先挂对科室一样向 AI 提问的第一步就是给它一个明确的角色定位。例如你可以这样指定“你是一位经验丰富的数据库管理员擅长编写高效、准确的 SQL 查询语句。”这样 AI 就知道自己应该以什么身份、什么专业背景来回答你的问题输出的内容也会更加专业和聚焦。2.2 第二步说明问题症状见了医生后你不能一上来就要医生开药当然需要先跟医生描述清楚你面临的问题。比如我最近感觉胸闷偶尔感觉喘不上气。但是这一步也是很多人难以把握的因为你当然是知道很多你自己相关的信息但是这时的根本目的是需要考虑医生需要知道哪些信息才能有助于确定你的症状。这时你就还需要提供一些必要的上下文信息比如持续时间、严重程度等这样医生才能有足够的信息帮你确定症状。与 AI 交互时也同样。你需要明确告诉 AI你有些什么信息需要解决什么样的问题。例如你需要告诉 AI“我现在有三张表Authors 作者表表结构 xxxxPublishers 出版社表表结构 xxxBooks 书籍表表结构 xxx。我要根据这三张表查询在某一出版社出版书籍最多的作者。”这一步可以说是整个提示词中最为关键的部分。你给出的上下文信息越精准就越有助于 AI 理解背景信息为后续的解决方案打下基础。对于简单的问题可以依靠你的经验来尽量优化信息。但是如果你有一些后端编程的能力那么这一步就是你大展身手的时候了。例如如果你希望统计到昨天为止的结果这时 AI 大模型并不知道昨天是哪一天你就可以给 AI 大模型提供一个可以计算日期的本地接口这样 AI 大模型可以通过调用本地接口获得昨天的日期。另外如果问题相关的知识太多太复杂了。你还可以使用大模型提供的文本向量化模型去寻找跟用户的问题匹配得更精确的上下文信息。2.3 第三步详细描述目标跟医生说明了病症接下来就需要医生给你治病了。去看医生那当然目标明确是要治好病。大家心知肚明。但是跟 AI 交互问题就往往没有那么明确了。在这一步你就需要明确你的最终目标是什么让 AI 清楚的知道你期望的结果。在提目标时不用担心 AI 大模型的理解能力把目标提得越明确越能减少不必要的歧义。例如如果你的后端数据库是 MySQL那么你可以明确告诉 AI“帮我写一个能够在 MySQL 中顺利执行的 SQL 语句。”2.4 第四步指定期望的结果跟医生说明了目标那么医生已经可以基本帮你治疗。不过更加细致的情况是你想怎么治。比如你自己估计可能没什么大问题但是医生上来就跟你说我们打个针或者动个手术吧你估计是不容易接受的。你可以明确的跟医生说不我只接受口服而且我只接受西药中药太苦了我吃不下。这一步就是你告诉 AI你所希望的结果格式是什么。当然如果只是要写一个 SQL 语句或许没有太多格式上的要求。但是如果是答案比较多的问题比如**“帮我写几个不同的 SQL 语句并比较他们的执行性能”**那么对格式上就可以做更多的补充了。比如整理成一个表格。2.5 第五步解决边界问题最后如果医生动手给你开药了你会想到一些预防性的要求比如你钱包紧张就需要跟医生说让医生开便宜一点的药这样当医生在给你开药方时自然就会谨慎一点。对于 AI你也可以尽量规避一些明显不合理的特殊情况。比如最典型的如果你给了 AI 大模型足够精确的信息那么可以明确告诉 AI 大模型就用你提供的信息回答问题而不要用其他莫名其妙的信息。或者在写 SQL 这个场景你可以明确要求 AI 大模型就写一个 Select 查询语句而不要生成 update、delete、insert 这一类 SQL 语句。这样你就可以尽量放心的把 AI 大模型提供的 SQL 语句扔到 MySQL 执行而不用担心数据被改得乱七八糟了。或者可以要求他不要使用多层嵌套等等要求。或者如果你想不出这些边界问题那么另外有个最好的办法就是给出一些案例让他直接参考你的案例。3. 环境准备与项目初始化3.1 创建 Spring Boot 项目使用 Spring Initializrhttps://start.spring.io/创建一个新项目选择以下依赖Spring WebSpring AI(需要添加 Spring Milestone 或 Snapshot 仓库)在pom.xml中添加 SpringAI 的 BOM 和相关依赖dependencyManagementdependenciesdependencygroupIdorg.springframework.ai/groupIdartifactIdspring-ai-bom/artifactIdversion1.0.0-SNAPSHOT/versiontypepom/typescopeimport/scope/dependency/dependencies/dependencyManagementdependencies!-- Spring AI OpenAI 支持 --dependencygroupIdorg.springframework.ai/groupIdartifactIdspring-ai-openai-spring-boot-starter/artifactId/dependency!-- PDF 文档读取 --dependencygroupIdorg.springframework.ai/groupIdartifactIdspring-ai-pdf-document-reader/artifactId/dependency!-- 向量存储SimpleVectorStore 内置 --dependencygroupIdorg.springframework.ai/groupIdartifactIdspring-ai-core/artifactId/dependency/dependencies3.2 配置 API Key在application.yml中配置你的 OpenAI API Key或阿里云百炼的 API Keyspring:ai:openai:api-key:${OPENAI_API_KEY}# 从环境变量读取不要硬编码chat:options:model:gpt-4o-miniembedding:options:model:text-embedding-ada-0024. 核心代码实现4.1 构建 RAG 服务我们将创建一个RagService它负责整个 RAG 流程。importorg.springframework.ai.document.Document;importorg.springframework.ai.reader.pdf.PagePdfDocumentReader;importorg.springframework.ai.transformer.splitter.TokenTextSplitter;importorg.springframework.ai.vectorstore.SimpleVectorStore;importorg.springframework.ai.vectorstore.VectorStore;importorg.springframework.ai.vectorstore.SearchRequest;importorg.springframework.ai.chat.client.ChatClient;importorg.springframework.ai.chat.prompt.PromptTemplate;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.core.io.Resource;importorg.springframework.stereotype.Service;importjava.util.List;importjava.util.Map;ServicepublicclassRagService{privatefinalChatClientchatClient;privatefinalVectorStorevectorStore;publicRagService(ChatClient.BuilderchatClientBuilder){this.chatClientchatClientBuilder.build();// 使用内存向量存储生产环境建议替换为 pgvector 或 Redisthis.vectorStorenewSimpleVectorStore();}/** * 加载并索引 PDF 文档 * param pdfResource PDF 文件资源 */publicvoidindexPdf(ResourcepdfResource){// 1. 加载文档PagePdfDocumentReaderpdfReadernewPagePdfDocumentReader(pdfResource);ListDocumentdocumentspdfReader.get();// 2. 切分文档TokenTextSplittertextSplitternewTokenTextSplitter();ListDocumentsplitDocumentstextSplitter.apply(documents);// 3. 向量化并存储SimpleVectorStore 会自动调用配置的 EmbeddingModelvectorStore.add(splitDocuments);System.out.println(PDF 文档索引完成共 splitDocuments.size() 个文本块。);}/** * 基于用户问题从知识库检索并生成答案 * param query 用户问题 * return AI 生成的答案 */publicStringaskQuestion(Stringquery){// 1. 检索相关文档SearchRequestsearchRequestSearchRequest.query(query).withTopK(5);// 返回最相似的 5 个块ListDocumentsimilarDocumentsvectorStore.similaritySearch(searchRequest);// 2. 构建上下文StringBuildercontextnewStringBuilder();for(Documentdoc:similarDocuments){context.append(doc.getContent()).append(\n\n);}// 3. 构建提示词模板StringpromptTemplate 你是一个智能问答助手。请根据以下提供的上下文信息回答用户的问题。 如果上下文中没有足够的信息请直接说“我无法从提供的知识库中找到答案”。 不要编造信息。 上下文 {context} 用户问题 {question} 请给出详细且准确的回答 ;PromptTemplatepromptnewPromptTemplate(promptTemplate);MapString,ObjectpromptParametersMap.of(context,context.toString(),question,query);// 4. 调用 LLM 生成回答returnchatClient.prompt(prompt.create(promptParameters)).call().content();}}4.2 创建 REST API 控制器创建一个控制器来暴露两个接口一个用于上传并索引 PDF另一个用于提问。importorg.springframework.http.ResponseEntity;importorg.springframework.web.bind.annotation.*;importorg.springframework.web.multipart.MultipartFile;importjava.io.IOException;RestControllerRequestMapping(/api/rag)publicclassRagController{privatefinalRagServiceragService;publicRagController(RagServiceragService){this.ragServiceragService;}/** * 上传 PDF 文档并构建索引 */PostMapping(/upload)publicResponseEntityStringuploadPdf(RequestParam(file)MultipartFilefile){if(file.isEmpty()){returnResponseEntity.badRequest().body(请上传一个 PDF 文件。);}try{ragService.indexPdf(file.getResource());returnResponseEntity.ok(PDF 文档已成功索引。);}catch(Exceptione){returnResponseEntity.internalServerError().body(索引失败e.getMessage());}}/** * 向知识库提问 */GetMapping(/ask)publicResponseEntityStringaskQuestion(RequestParam(question)Stringquestion){if(questionnull||question.isBlank()){returnResponseEntity.badRequest().body(问题不能为空。);}StringanswerragService.askQuestion(question);returnResponseEntity.ok(answer);}}5. 实战测试启动应用运行你的 Spring Boot 应用。上传 PDF使用curl或 Postman 发送 POST 请求上传一个 PDF 文档。curl-XPOST-Ffile/path/to/your/document.pdfhttp://localhost:8080/api/rag/upload提问发送 GET 请求进行提问。curlhttp://localhost:8080/api/rag/ask?question这篇文档主要讲了什么内容你会看到 AI 基于你上传的 PDF 文档内容给出精准的回答。6. 总结与进阶本文我们成功实现了一个基于 SpringAI 的 RAG 智能问答系统它能够读取 PDF 文档并将其转化为可供自然语言查询的知识库。这只是一个开始在实际生产环境中你还可以考虑以下优化替换向量数据库将SimpleVectorStore替换为Pgvector、Redis或Milvus等生产级向量数据库以支持大规模数据存储和持久化。优化文档切分策略根据文档类型如代码、表格、长文本选择不同的切分器如SentenceSplitter、RecursiveCharacterTextSplitter以保留更好的语义完整性。引入多轮对话将历史对话信息也作为上下文的一部分实现多轮对话的 RAG。混合检索结合关键词检索如 Elasticsearch和向量检索提高检索的准确率和召回率。文档预处理在索引前对 PDF 进行 OCR 识别、表格提取等预处理提升数据质量。通过 SpringAI我们可以用非常简洁的代码快速搭建出强大的 RAG 应用。希望这篇实战能为你打开一扇新的大门让你能更好地利用 AI 技术解决实际问题。