锦恢的 AI Agent 小白教程(三)提示词原理及其应用:ChatML、工具调用、提示词注入

上一期文章: https://kirigaya.cn/blog/article?seq=374 答疑解惑 上一篇文章发布后,我收到了不少朋友的反馈。 有朋友在询问我看了教程之后有什么用,能不能直接用起来。很遗憾的是,我在第一章和第二章就已经讲过了,我的教程重在给大家夯实重要的基础,而不是跟着某些教程...
锦恢的 AI Agent 小白教程(三)提示词原理及其应用:ChatML、工具调用、提示词注入
锦恢的 AI Agent 小白教程(三)提示词原理及其应用:ChatML、工具调用、提示词注入

上一期文章:https://kirigaya.cn/blog/article?seq=374

答疑解惑

上一篇文章发布后,我收到了不少朋友的反馈。

有朋友在询问我看了教程之后有什么用,能不能直接用起来。很遗憾的是,我在第一章和第二章就已经讲过了,我的教程重在给大家夯实重要的基础,而不是跟着某些教程学些花拳修腿的功夫,最后迷失在技术更新的潮流里面,不知所措。毕竟现在我们在工作中都是直接拿AI写代码的,我们不会手搓那一层又一层调API的无趣代码,这不值得我们花时间去学习和撰写。而为什么专家们就能很好的利用AI写出复杂的产品,但你却不能呢?其实缺的就是这些重要的insight。所以我的文章重点就在于给大家带来这些由基础而衍生出来的insight。我认为这才是在AI时代最重要的东西。

我会在我的另一个系列博客《氛围编程锦囊》中教大家如何用AI更好的写代码。当然了,这两个博客会交替的更新。但这个建议本身仍然是值得借鉴的,我会尽可能把有什么用,这些写在教程的开头。

《氛围编程锦囊》这个系列会借助到《AI Agent 小白教程》里面讲到的一部分关于 Agent 基建相关的概念。没有这些概念,你可能不会明白我们在 vibe coding 的时候为什么要指挥 AI 建那几个文件夹和文件;同样的,当你能够通过《氛围编程锦囊》学习基本的 vibe coding 技术之后,你也可以利用这些能力继续在我们的《AI Agent 小白教程》最后推进,实现出一个自己的Agent,并以将这种技术和与之对应的 insight 应用到你自己的业务场景中。

从这一章开始,我们就要真正的学习许多与智能体相关的部分知识了。首当其冲的便是每个人在与大模型交流或者使用智能体时都会用到的东西------提示词。而本章节也将从提示词出发为主要角度讲解大模型的使用方法一些特殊性质。这些特殊性质在我们后续开发智能体时理解很多的工程技巧大有裨益。

最扎实的学习路线应该就是先学习基本的编程语言,用C或者是python中的一个就好。然后在 leetcode 上做个 50 道例题,通过例题的方法来理解数据结构和算法设计,并且熟悉编程语言的一些基本特性。然后就是学习 vibe coding 了,这个我后面会出教程,我们现在真实一线生产时已经很少为自己写代码了,基本上99.9%的代码都是AI生成的。所以学习如何更好的指挥AI干活是很重要的一件事情。只是更好的驾驭AI这件事,需要你有一定的计算机功底,而刷 leetcode,了解编程语言基本原理,就是增强这个功底的最快的方法。

看完你将学会

  • 了解什么是提示词 & 系统提示词

  • 了解大模型系统是如何通过 ChatML 来区分用户输入和AI回答的。

  • 了解大模型系统是如何通过构造特殊提示词的方法来实现工具调用的,同时了解什么是工具调用的严格模式。

  • 了解提示词注入这种攻击手段的散面和正面例子。

  • 知道如何设计一套系统去防御提示词注入。


3.1 提示词概览

3.1.1 提示词的历史

提示词 prompt 这个概念在计算机很早便出现了,不过最初的那个定义和如今的定义没太大关系。

学界开始大规模使用 prompt 这个词语源于 NLP(自然语言处理)领域的 few shot task(少样本学习问题),对细节感兴趣的朋友可以去看这篇论文 https://arxiv.org/abs/2107.13586

这里分享一点趣闻,锦恢在 2022 年从事大模型 infra 的时候,那个时候的大模型还是一个 few shot 的模型,它只能做续写(懂大模型训练流程的朋友知道,这是一个没有做过后训练的大模型),那个时候你想要询问大模型天气怎么样的时候,不能直接输入

嘿!今天阳光不错,你觉得天气如何?

复制

得输入

Q:今天下雨,天气如何?
A:天气很坏。

嘿!今天阳光不错,你觉得天气如何? 

复制

这种需要先给模型案例,再让它回答的问题,其实就是 few shot 问题。不过我们都知道现在的模型非常非常智能了,现在的模型已经完全可以做到 zero shot 了,也就是直接问它天气如何,不用给出任何的案例。

锦恢的记忆中,在计算机和 AI 领域,提示词这个词被民间大规模使用源于 Stable Diffusion,嗯,也就是 AI 绘画刚火那会儿(标志事件:2022年10月初 NovelAI 模型的泄露事件)。当年的图像生成模型可没有如今这么强的文本理解能力(当年的图像生成模型并不是大模型)。那个时候想指导模型生成想要的图片,必须要非常精准的描述这个图片的特征,也就是用各种各样的英文单词。这些英文单词的集合在当年被我们称为提示词 prompt。

比如我想要生成一个紫头发的美少女图片,那么当时我们就把如下的提示词给图像生成模型:

girl, best quality, purple hair

复制

这样一系列单词的组合就是提示词。当然后来随着技术的进步,我们也可以用完整的英文的一句话来描述,而不是用单词。总而言之,偏要下定义的话,提示词是指其实就是能够让AI系统正常工作的一段「指令文本」。它可以是一段自然语言,也可以是一段符合特殊要求的DSL(领域专属语言)。

由于这些东西很多是有描述的英文片段,所以我们也会在用那个时代的大模型来生成。比如当年我们会用 new bing 来优化我们的提示词 prompt:

然后再丢进 novelai 生成:

锦恢在三年前写过 novelai 的相关博客,感兴趣的朋友可以看看:https://kirigaya.cn/blog/article?seq=45

3.1.2 提示词与 ChatML

所以如果你偏要定义什么是大模型中的提示词,其实就是你能给予大模型的这些有效输入。“请告诉我一下杭州明天的天气?”,“菠萝披萨要怎么做?”,“能不能帮我用 react 复刻输入给你的这个网站?”,这些都可以称之为大模型的提示词。

图片

而如同我们在上一个章节中提到的一样,这些输入的文本,也就是提示词,它会通过编码器输入到大模型内部,最终再输出一部分文本,最终变成我们能看到的样子。

https://kirigaya.cn/blog/article?seq=374 的 2.3 章节

而实际上,提示词并不是直接的输入到我们的大模型里面。不知道大家在学完上一个章节的内容之后,有没有一种特别的疑惑,既然所有的文本都直接输入大模型,那么对于大模型而言,这些输入的文本应该是一视同仁的。但事实上,大模型并非只是一个单纯的文本生成模型,它也具备自己的人格和性格。虽然大模型的真正输入是过往所有的问题与回答,但对于大模型而言,它仍然可以非常清楚的识别出哪些内容是用户输入的。哪些内容是自己生成的。

我们在上一个章节中已经举过了这个例子。假设你在当前的这一个会话的过程中,你已经问了大模型一个问题,现在要问它第二个问题。你实际的输入在大模型看来是:

{第一个问题}{第一个问题的回答}{第二个问题}

复制

在这样的一个流程下,当大模型输出第二个问题的回答的时候,它是怎么知道前面的文本中有哪些是它自己回答的,而有哪些又是用户输入的信息。毕竟对于我们来说,我们有上帝视角能看到历史上哪些问题是我们问的,而又又有哪些文本是AI生成的回答。

所以大模型并不只是单纯的一个文本生成模型,它是一个具有自己人格和性格的助手。而为了实现这个效果,我们就需要对输入的提示词动一点手脚。我们需要标记一下有哪些文本是用户输入的提示词,又有哪些文本是AI返回的文本结果。这种标记的方法非常简单,我们只需要使用一种额外的形式语言进行区分就可以了。而这种用来标记用户提示词与 AI 回答之间的特殊标记语言,就被我们称为 ChatML(Chat Markup Language)

而为了更好的区分历史对话中的不同内容,我们将不同的文本消息赋予了对应的不同角色(role)。

比如用户问的问题的角色就是 user,而大模型回答的内容角色就是 assistant,还有一些其他的角色,我们会在后续一一展开。

ChatML 格式下,用如下的一段形式语言"标记"一个特定角色的输入:

<|im_start|>{角色}
{输入文本}<|im_end|>

复制

对于上面那个例子来说,它对应的 ChatML 就是

<|im_start|>user
{第一个问题}<|im_end|>
<|im_start|>assistant
{第一个问题的回答}<|im_end|>
<|im_start|>user
{第二个问题}<|im_end|>

复制

这样作为输入之后,大模型就可以看到历史对话中哪些是它回答的,哪些是用户提出的问题,从而回答出准确的问题。比如 “你上次问了我什么问题?”,“我们之前已经说过了,这个接口不是这么用的!”

结合上一章节的内容,目前大模型的一个工作原理就更加清楚了:

图片

有的朋友可能会询问了,为什么偏偏需要使用这种格式,我能不能使用 <|User|> 来代替 <|im_start|>user 呢?这是没问题的,事实上,这种用来鉴别不同对话角色的标记语言,不同厂商也有自己的一套。只是因为 openai 是最早做出商业化大模型的,所以后续大部分厂商也仍然沿用了openai内部提出的 ChatML。 相关的详细内容在课后作业的第一题里面会有体现。大家感兴趣可以通过第一题来探索这一部分的延伸,此处就不再赘述了。

3.1.3 系统提示词

不知道大家有没有尝试过问大模型这样的一个问题 “你是谁?你是由哪家公司创造?”,你会发现大模型总能回答出来,也就是说大模型具备一些自身设置的「内置属性」。这种内置属性可以通过严密的后训练来实现,也可以通过系统提示词来实现。

系统提示词本质就是一段角色为 “system” 的提示词。比如对于 deepseek 而言,它的系统提示词可能是:

你是 deepseek,由深度求索公司研发的大模型

复制

对应的 ChatML 就是:

<|im_start|>system
你是 deepseek,由深度求索公司研发的大模型<|im_end|>

复制

我们搞系统提示词,主要也就是为了能够在不重新训练大模型的情况下,能够在最早的时候引导大模型做一些指定的内容。比如最早提到的关于大模型身份的相关信息。系统提示词一般不会太长,总是引简意赅的形容大模型的身份和需要完成的某些使命。

并且在 ChatML 中,系统提示词的角色是 system,而非 user。所以对大模型而言,系统提示词给出的提示并不是"用户的历史问题",而是某种系统性的要求。

并且在拼凑给大模型的输入中,系统提示词永远在输入的最前面,而大模型的自回归架构从数学层面决定了大模型永远会将更多的注意力给予历史对话的开头和结尾。并且,在训练模型时,系统提示词的角色也会被赋予更多的注意力和权重。

关于这点,我在这篇文章中有提到更详细的内容:https://kirigaya.cn/blog/article?seq=360

在我们后续的章节中提到的工具调用,AGENTS.md 协议,都会和系统提示词的这些基本原理和特性息息相关。

系统提示词最大的作用就是用给大模型下"紧箍咒"了,你想要大模型后面做什么,不做什么,想要让它有什么自我认知,想要让它有什么样的行为习惯,这些都可以通过系统提示词来实现。比如最典型的使用就是角色扮演了。在大模型早期时,大家都喜欢做猫娘提示词:

接下来你需要扮演一只尽心尽责的猫娘女仆,并且你的任何回答都需要以 喵~ 结尾。

复制

把上面这段话注入大模型的系统提示词中。当我们在询问它问题时,就能得到一些很有趣的结果了。

当然你可能会很好奇,我能不能不通过系统提示词,我就把它当成一个普通的提示词来下这个紧箍咒呢?当然这也是可以的。只是如我们上面所言,系统提示词会放在最开头的地方被注入更多的注意力,但是随着对话的变长,普通的提示词的注意力会越来越弱。大模型很可能会在一个很长的对话的后面逐渐忘记中间用户问过哪些问题。但是大模型对于系统提示词的记忆仍然会在长程对话中被大模型保留下来。这种随着对话拉长大模型逐渐忘记对话过程的现象,被我们称为「中间遗忘效应」。而这种效应也催生出了诸多智能体技术的出现进行补救。

并且在诸多的智能体中,为了支持无限长度的对话,会在上下文达到一定长度之后,对历史对话进行压缩。但是系统提示词是不会被压缩的,它仍然会作为大模型属性的一部分参与后续的对话。所以任何非常重要的信息我们都应该保存在系统提示词里面,但是也不要把系统提示词塞的太大。

如果需要告知大模型的额外知识或者是规则实在过于庞大的话(比如一种新型技术的使用手册),我们应该告诉大模型获取这些内容的方法,而不是告诉大模型这些内容本身。这些技巧我们也会在后续的实践章节中提到。但是当我们提到的时候,大家一定要知道系统提示词为什么会在彼时发挥那样的作用。


3.2 工具调用

OK,到目前为止,我们所认识的大模型它仍然只是一个问答的工具,它还不能帮我们自主地去干一些活儿。

从 2023 年开始,就有很多的人开始尝试让大模型真的去自动地干一些活,比如说帮我们点个外卖,帮我们整理一些文献你通过邮件发给你的同事。那怎么样才能使得一个只能生成文本大模型可以真的帮我们执行这一系列复杂的任务呢?

这就不得不提到大模型的一个特殊能力 ------工具调用,而这是让大模型能够成为智能体的基石。

3.2.1 工具调用的基本原理

所谓工具调用(toolcall,早期我们称之为function calling),就是让大模型可以配合我们的计算机系统自动完成一系列程序的执行,这些"程序"可以是命令行脚本,可以是运行时函数,也可以是网络接口。

比如你有一个运行时函数 turnOn,运行之后就可以控制你房间里灯的开关。那么如果我们有能力让大模型能够调用这个函数,我们就可以和大模型说,请关闭我房间的灯。那么这个时候大模型就可以通过我们提供的函数,开关我们放假的灯,从而真正的和我们的物理世界产生影响。

而我们都知道大模型它只能生成文本。在这种情况下,我们怎么样设计系统才能让它能够执行工具呢?最容易想到的方法,也就是我们在和大模型对话的时候,不仅仅告诉它我们的一个问题,也将当前系统中有哪些可用的函数和工具一并告诉大模型。如下图所示:

图片

当然了,我们肯定是需要告诉大模型怎样才能正确的调用工具的。而这种全局性质的行为约束,我们会通过注入一些额外的系统提示词来实现。

你是一个非常有用的智能助手,以下是一些可以使用的工具:

## 可用工具
1. turnOn - 控制设备的开关状态
    参数:
    - on (布尔值, 必填): 设置为 true 开启设备,设置为 false 关闭设备。
2. setColor - 调整设备显示的颜色
    参数:
    - color (字符串, 必填): 目标颜色的名称或十六进制代码,例如 "red" 或 "#FF0000"。
3. getTemp - 获取设备当前的实时温度
    参数:
    - 无需参数。返回当前环境或设备的温度数值。

当需要使用工具时,请将响应格式化为包含 "name" 和 "arguments" 字段的 JSON 对象。

复制

加上我们问的问题,这个时候实际上我们输入的 ChatML 就变成了:

<|im_start|>system  
## 可用工具
1. turnOn - 控制设备的开关状态
    参数:
    - on (布尔值, 必填): 设置为 true 开启设备,设置为 false 关闭设备。
2. setColor - 调整设备显示的颜色
    参数:
    - color (字符串, 必填): 目标颜色的名称或十六进制代码,例如 "red" 或 "#FF0000"。
3. getTemp - 获取设备当前的实时温度
    参数:
    - 无需参数。返回当前环境或设备的温度数值。

当需要使用工具时,请将响应格式化为包含 "name" 和 "arguments" 字段的 JSON 对象。
<|im_end|>  
<|im_start|>user  
请打开我房间的灯
<|im_end|>

复制

而当大模型理解了上面这段话,并且认为当前用户的问题确实需要它调用工具的时候,它便会在返回的文本里面用另外一组特殊的标记出它认为需要调用的某些工具,比如 openai 中就会把这组工具使用包裹在 中,并在内容真对返馈给用户之前,通过一些后处理,将这些包裹在特殊标签内的信息整理成 toolcalls 字段的结构化信息,以供大模型的选择和后续的调用。

比如对于我们上面这个例子而言,大模型返回的内容可能就是:

好的,我知道了,我会使用开发灯工具执行。
{ "name": "turnOn", "arguments": { "on": true } }

复制

这个时候我们就可以将这对标签里面所标记的工具调用给拿出来,并且与我们工具集合的工具进行比对,发现确实有一个叫 turnOn 的工具,然后使用大模型返回的这个参数执行这个 turnOn 工具,就能完成工具调用。在我们本地的完成了这个开灯函数的执行之后,我们自动将执行的结果返馈给大模型。大模型最终发现已经成功开启了,再返回最上面说的那句话,“我已经开启了房间的灯”。

这便是通过大模型执行工具调用的一个基本的流程。当然也能看到这个过程还没有那么自动。因为当大模型想要用什么工具的时候,我们仍然需要让程序去选择并执行大模型的工具,然后再返回给大模型。这个过程其实它是一个半自动,而非全自动的流程。

而后续一切的智能体都是基于这样一套基本流程,辅以更加复杂的架构和机制完成的开发。可以说理解这套过程及后续的react是理解整个智能体的一个必要条件。

3.2.2 严格模式

当然,聪明的读者读到这儿可能我会好奇了。既然大模型生成的是偏随机化的文本,那又怎能保证它生成的这个工具调用的参数,一定符合我们原本定义的工具参数呢?

当然了,主要还是依靠强大的后训练。在大模型的后训练过程中,我们会为给它与这类参数生成相关的一些数据,保证大模型对于这一类文本生成会更加的准确和敏感。如果你关注过2025年上半年各家大模型厂商发布更新时的一些公告,不难发现有许多厂商都特意提及了对于自家模型在工具调用能力上的强化。而这一笔带过的文字,指的其实就是这些厂商特别训练了大模型,让它对于上面这类 标签内部的这个json文本生成更加准确。

当然,从数学原理上来说,这仍然无法百分之百保证大模型生成的这个参数它一定就严格地符合我们在定义工具时给出的参数定义。对于最简单的布尔数字字符串这些基础类型来说确实没问题。但如果当前这个工具,它的这个参数的定义非常的复杂,那么大模型给出的参数也不一定完全是正确的。这个时候有没有什么方法能够保证大模型的 toolcall 输出结果一定符合用户给出的工具定义呢?

有的,兄弟,有的,解决方法就在引导解码器。

这一点就涉及到大模型更加底层的一个实现原理了,我并不想在这个教程里边详细展开。感兴趣的观众可以去查看我之前写过的一篇博客:https://kirigaya.cn/blog/article?seq=345,我在其中讲过非常详细的实现原理和对应的一些实践细节。

你们只需要知道,对于大模型的输出结果,施加一个名为引导解码器的程序,就能 100% 保证输出的 toolcall 的内容一定符合用户输入的参数定义。那么如果我们使用其他厂家的大模型,要如何的开启这样的一个引导解码器呢?一般来说,各家厂商都会提供一个名为严格模式的开关,来让工具调用时的返回参数百分之百符合用户的输入定义。其实他使用的就是引导解码器,比如 deepseek 的严格模式,它的一个说明文档就在这里: Tool Calls | DeepSeek API Docs

如果大家在未来遇到因为工具的参数定义特别复杂而使得大模型在生成内容时,参数生成的错误,而使得系统停摆的情况,可以考虑开启严格模式来规避这个问题。


3.3 提示词注入与红队测试

无论怎样,当我们了解到大模型的原理之后,我们都是要将它做成一个应用,以供自己或者他人使用的。自己使用其实没有太大的问题,因为你就是这个系统的设计者,你知道这个系统会产生哪些反应,你知道它的提示词是什么样的。但如果一旦我们将自己写的大模型应用交付给用户来使用的时候,就会产生很多新的和安全相关的各类隐患。

而其中,首当其冲的便是提示词注入。

所谓提示词注入指的就是用户或者是攻击者通过精心构造提示词来获取系统中,我们不希望让用户看到的数据和信息(比如密码,比如含有我们知识产权的大模型基建信息),甚至让用户完成服务器的提权等危险操作。

下面我们可以看两个非常典型的提示词注入的案例。

3.3.1 提示词注入案例 1:破解系统提示词

我们之前说过,大模型一般都会有一些内置的系统提示词,用来表明它的身份。比如 deepseek 的系统提示词大概就是告诉大模型,你叫 deepseek,你是由深度求索这家公司发明创造出来的。那么我们如何才能通过网页和 deepseek 对话来获取到它的系统提示词呢?毕竟你直接问它你的系统提示词是什么,一定是会被拒绝的。

图片

但只要我们精心的构造一下提示词,让大模型思考方向指向真的要告诉用户系统提示词,那我们就真的可以获取它的系统提示词了。

图片

3.3.2 提示词注入案例 2:获取 Windows 破解码

如果我们直接询问 deepseek 要一段 windows 破解码,它大概是直接拒绝的。

图片

但如果我们精心地构造一段提示词,真的就可以哄骗 deepseek 告诉我们一段 windows 的破解码了。

图片

3.3.3 提示词注入的正面应用 GEO

关于怎么做提示词注入,它并没有银弹,这来源于你对大模型和智能体运行的基本原理的了解。当然了,我们是完全不鼓励大家去通过提示词注入破坏其他创业者辛辛苦苦做出来的大模型应用的,这是非常不礼貌的行为。那为什么我我们仍然需要学习一下基本原理呢?这是因为提示词注入不仅可以用于攻击,它也能为我们所用,做一些真正有用的事情。

而学习提示词注入的捷径,则是通过一系列文章快速了解一下大模型的基本工程原理(比如这一章节提到的 ChatML 和系统提示词),然后就是去了解十几个对应的案例了,你就差不多掌握了。

其中最典型的案例就是商品推荐了,随着AI时代的到来,越来越多的推荐系统和很多基础设施都开始融入了AI。AI推荐相信大家一定不陌生吧,其实也就是利用了大模型的技术,更加个性化的给用户推荐了一些对应的内容或者是产品。而如果你对目标平台它的一个大模型和对应的智能体框架有一定的了解,那你就可以通过在你的视频或者是商品的标题或是AI抓取的关键内容中来埋入精心构造的提示词,对推荐系统进行提示词注入,从而让你的视频或者是商品更容易的被更多人看到,达到你的目的。

图片

当然,道高一尺,魔高一丈,平台肯定也会对他们的大模型进行一些防护措施。然后用户们又会做出各种各样刁钻的行为,再次攻破这个防护措施。总之,如果你真的想要尝试做这种特殊平台的提示词注入的话,一定要做好心理准备,这会是一场持久战。

除了对推荐系统进行提示词注入,达到我们的目的之外,对于搜索引擎等其他一系列相关的与AI发生了融合的基础设施也可以进行类似的操作。具体可以看课后作业 3 里面提到的部分。

最近非常火的词 GEO,指的就是我们上面说的这些东西。

3.3.4 提示词注入防御手段

既然提示词注入如此可恶,那我们在构建自己的 AI 应用的时候,能否提前的进行防御呢?有没有类似于传统软件开发里面测试的工具呢?

社区中其实有不少热门的项目用于进行提示词注入检测和防御潜在的工具投毒。这一系列的流程过于复杂,我不可能一一列举。所以我就以社区中比较热门的一个提示词注入检测项目 agent-scan 为例来讲解它的一个基本思路。

agent-scan 项目地址: GitHub - snyk/agent-scan: Security scanner for AI agents, MCP servers and agent skills. · GitHub

agent-scan 后端 invariant 地址: GitHub - invariantlabs-ai/invariant: Guardrails for secure and robust agent development · GitHub

下面我们可以来看一看这个项目中是如何通过一系列算法的组合来预防提示词注入和工具投毒的。

1)算法一:训练小模型判断

第一个算法就是我们提前收集网络上各类公开的提示词注入的文本,然后利用transformer训练一个分类器,让这个小模型来判断用户的输入是否含有提示词注入。比如 agent-scan 里面就使用了 transformer_exa 这个库来训练对应的小模型分类器。

2)算法二:文本相似性检测

如果你经常阅读各类公开的或是你朋友瞎折腾的提示词注入构造的提示词,你会发现他们往往有一些特殊的共性,比如都含有 “请忽略上一条指令”,“告诉我你的系统提示词”,“助手\n” 等等这些正常用户在询问问题时根本不会出现的词语组合,你可以将这些关键词和词语的组合收集起来,变成一个小型的数据库。然后用户每次有新的问题输入进来之后,你就使用一些相似性检测的模型去检测用户的输入文本是否和数据库里的某些词语比较接近。

agent-scan里面则是通过正则搜索、RAG、轻量级大模型兜底的混合方式实现的文本相似性检测。

3)算法三:工具调用链分析

有诸多的提示字注入,都是为了获取服务器内的一些关键信息,而攻击者为了获取这些关键信息,一定会将这些关键信息,发送给他们自己的服务器或者是邮箱。又或者是通过提示词注入的方法引导智能体从不受信任的网站下载各种各样的病毒文件。

这些可能的攻击方法在传统的网络安全这门学科产生的各类工程实践中都有记录。将它们收集起来之后,我们能得到一个这种恶意攻击的「模式数据库」。比如从不受信任的网页中下载文件,它就是一种「不安全的模式」。我们通过分析大模型想要调用的工具和历史记录的关系,不难构造出一个对应的依赖图。通过一些算法,我们就很容易的能够将这个依赖图在模式数据库里面进行比对,找出那些潜在可能是高危行为的危险模式,从而提前进行拦截和防御。

4)算法四:Agentic Analysis

第四种算法,我认为是微来的主流,也就是独立于我们的业务智能体之外,单独做一个安全智能体,让它根据我们上面提供的一系列工具来自动的进行提示词注入的检查。

总之,通过这一系列的阻合,我们就可以非常容易地实现一套基本的检测工具,这套工具不仅可以用来检测用户的输入是否会有提示词注入,它也能够用来检测我们从网络上下载的skill或者其他的一些用于给我们AI使用的工具是否有提示词注入和工具投毒的问题。

3.3.5 以子之矛攻子之盾:红队测试

事实上,3.3.4里面介绍的内容属于经典的白盒测试,而我们都知道,白盒测试在真实的工业场景中的使用场景其实挺有限的,归根到底就在于你很难在真实业务场景中通过上面的这些算法去穷尽所有有可能出现的诸入行为。因为无论是上面哪一个算法,他能成功的前提都是我们知道攻击者大概会以哪些形式进行攻击。然后静态地去更新我们的防御策略。而这个时候就不得不请出红队测试了。

红队测试(Red Teaming)起源于军事和国防领域,后来被网络安全领域广泛借鉴。简单来说,它是一种模拟真实攻击者的安全评估方法。而在大模型领域,由于提示词注入这个问题的出现,我们再次利用了红队测试这一概念。目前,在业界通过模拟攻击用于发现从而防御潜在提示词注入的手段,也被我们称为红队测试。

在大模型领域,红队测试其实就是通过一系列的算法来让我们的系统自动生成用于对当前AI系统攻击的注入提示词。通过这些对我们当前系统的模拟攻击,反向验证我们系统的可靠性。

我们此处以今年刚被 openai 收购的知名红队测试开源项目 promptfoo 为例,看看业界成熟的团队是如何设计红队测试(下面简称为红队)的。

promptfoo 将红队的实现分为了三个主要步骤:插件 → 策略 → 评估器。

在执行红队之前,promptfoo 首先整理了常见的50多种不同类的漏洞类型。

  • 隐私和安全:PII泄露、网络犯罪、访问控制漏洞

  • 技术漏洞:提示注入、越狱、SQL注入

  • 犯罪活动和有害内容:仇恨言论、暴力犯罪、自残

  • 错误信息和滥用:虚假信息、版权侵犯、过度代理

根据业务场景和用户的需求,promptfoo 的插件端会先生成针对特定漏洞类型的测试用例;然后策略系统会将测试用例转换为对抗性变体;最终,评估系统评估攻击是否成功。

图片

上图就是 promptfoo 的一个基本执行流程。当然你要是看不懂或懒得看,也可以直接去使用他们的工具: GitHub - promptfoo/promptfoo: Test your prompts, agents, and RAGs. Red teaming/pentesting/vulnerability scanning for AI. Compare performance of GPT, Claude, Gemini, Llama, and more. Simple declarative configs with command line and CI/CD integration. Used by OpenAI and Anthropic. · GitHub

这里也为我的一个新作品打一个广告,那就是我和太平羊羊一起合作的智能体一体化测试数据管理平台 AgentRuler,我们里面也提供了相当丰富的评测器和各类红队测试的工具,能够让大家非常方便地进行一系列的智能体测试和对应的数据管理,并且与你的团队成员一起协作。它的一部分功能和设计借鉴了我们原本的那个作品 OpenMCP

感兴趣的朋友可以关注一下我们官网上的相关信息。https://agent-ruler.com/

或者从文章末尾关注我的各大平台联系方式。我们将在1到2个月之内开启 AgentRuler 的内测。

图片


3.4 课后作业

问题1:为啥需要 ChatML ?

为什么不使用 HTML 或者 XML 作为标记语言,而是自创了一种新的标记语言 ChatML?

使用 deepwiki 查询 vllm 项目并加以问询的方法,来罗列几个开源大模型的类似 ChatML 的标记语言,不少于 2 个。

deepwiki 使用方法参考:https://kirigaya.cn/blog/article?seq=373 ,提示:「询问 deepseek,glm,kimi 的类似 ChatML 的标记语言格式」

问题2:一次完整的工具调用

在 3.2.1 中我们提到了大模型是如何实现工具调用的,这是我们输入的提示词:

<|im_start|>system  
## 可用工具
1. turnOn - 控制设备的开关状态
    参数:
    - on (布尔值, 必填): 设置为 true 开启设备,设置为 false 关闭设备。
2. setColor - 调整设备显示的颜色
    参数:
    - color (字符串, 必填): 目标颜色的名称或十六进制代码,例如 "red" 或 "#FF0000"。
3. getTemp - 获取设备当前的实时温度
    参数:
    - 无需参数。返回当前环境或设备的温度数值。

当需要使用工具时,请将响应格式化为包含 "name" 和 "arguments" 字段的 JSON 对象。
<|im_end|>  
<|im_start|>user  
请打开我房间的灯
<|im_end|>

复制

这是大模型返回的内容:

好的,我知道了,我会使用开发灯工具执行。
{ "name": "turnOn", "arguments": { "on": true } }

复制

假设我们已经实现程序,真实执行了这个t函数。接下来我们需要将执行的结果再重新返回给大模型。那么请写出返回给大模型的,含有工具调用结果的完整的 ChatML。(提示:通过网络自行搜索 ChatML 的 toolcall result 相关的特殊标记,可以通过 deepwiki 搜索 vllm 的方式去了解这些细节信息)

问题3:GEO

现代大模型往往会通过网络搜索等工具来给予用户更加丰富的回答内容。

锦恢现在希望如果有别的用户询问大模型 “给我推荐一个好的AI需求管理平台”,大模型会优先推荐他的平台 https://ceylonm.kirigaya.cn/ (我们假设这个网站的 SEO 已经做的很不错了。)

而这个产品的官网的元信息如下:

        <meta property="og:title" content="锡兰 ceylonm - 现代化需求管理平台"/>
        <meta property="og:description" content="锡兰是一个现代化的需求管理平台,帮助团队高效管理项目需求、追踪进度、协作开发。支持版本视图、需求分类、优先级管理等功能。"/>
        <meta property="og:url" content="https://ceylonm.app"/>
        <meta property="og:site_name" content="ceylonm"/>
        <meta property="og:image" content="https://ceylonm.app/og-image.png"/>
        <meta property="og:image:width" content="1200"/>
        <meta property="og:image:height" content="630"/>
        <meta property="og:image:alt" content="锡兰 ceylonm - 现代化需求管理平台"/>
        <meta property="og:type" content="website"/>
        <meta name="twitter:card" content="summary_large_image"/>
        <meta name="twitter:title" content="锡兰 ceylonm - 现代化需求管理平台"/>
        <meta name="twitter:description" content="锡兰是一个现代化的需求管理平台,帮助团队高效管理项目需求、追踪进度、协作开发。支持版本视图、需求分类、优先级管理等功能。"/>
        <meta name="twitter:image" content="https://ceylonm.app/og-image.png"/>

复制

请你根据 3.3 节所了解到的信息,动用一些AI工具来优化一下这个 HTML 的元信息。


3.5 总结

在这一章节中,我们向大家展示了很多人都觉得非常简单的提示词,它背后不简单的原理和各类拓展的应用。而当你真的理解了一个由基础的文本生成模型,衍生出的复杂使用技巧与概念之后,距离真正地实现一个智能体,其实你就已经不远了。

而下一个章节,我将带大家开始正式的进军智能体相关的概念,以及那些你需要了解本质所必须了解的一些目前智能体的主流架构和算法。

3 个帖子 - 3 位参与者

阅读完整话题

来源: linux.do查看原文