AI Agent(从 Chatbot 到生产级 Agent)

AI Agent(从 Chatbot 到生产级 Agent) AI Agent是LLM应用的高级形态,能够自主规划、执行任务并与环境交互。 经典论文: Yao, S., et al. (2022). “ReAct: Synergizing Reasoning and Acting in Language Models.” ICLR. [论文链接] - ReAct框架,Agent核心范式 Wei, J., et al. (2022). “Chain-of-Thought Prompting Elicits Reasoning in Large Language Models.” NeurIPS. [论文链接] Wang, G., et al. (2024). “A Survey on Large Language Model based Autonomous Agents.” arXiv. [论文链接] - Agent综述 一、整体演进路径 Chatbot → Tool Use → Agent → Production Agent(工业级) 演进说明: Chatbot: 仅能对话,无法执行外部操作 Tool Use: 能调用单一工具 Agent: 能自主规划并执行多步骤任务 Production Agent: 工业级,具备错误处理、权限控制、监控等能力 二、核心概念拆解 1️⃣ Chatbot LLM + Prompt ...

2026年3月14日 · Xiao Xiangtao

Prompt Engineering

Prompt Engineering https://www.coursera.org/learn/chatgpt-prompt-engineering-for-developers-project/home/welcome Prompt Engineering(提示工程)是设计和优化输入提示(prompts)以引导大语言模型生成期望输出的技术。这一领域随着GPT-3的发布而兴起,是连接用户意图与模型能力的关键桥梁。 经典论文: Brown, T. B., et al. (2020). “Language Models are Few-Shot Learners.” NeurIPS. [论文链接] - GPT-3论文,首次系统展示了prompt engineering的潜力 Wei, J., et al. (2022). “Chain-of-Thought Prompting Elicits Reasoning in Large Language Models.” NeurIPS. [论文链接] 1. Prompting Principles(提示原则) Principle 1: Write clear and specific instructions(编写清晰具体的指令) 清晰性(Clarity)和具体性(Specificity)是prompt设计的核心原则。研究表明,模糊的指令会导致模型输出不确定性增加,而具体的指令能显著提升输出质量。 Tactic 1: Use delimiters to clearly indicate distinct parts of the input 分隔符(如 ```、"""、—、<>)能帮助模型识别输入的不同部分,避免混淆。这在处理包含多段文本或代码的任务时尤为重要。 Tactic 2: Ask for a structured output 要求结构化输出(如JSON、HTML、Markdown表格)便于后续程序处理,是构建AI应用的最佳实践。 Tactic 3: Ask the model to check whether conditions are satisfied 让模型先验证条件再执行任务,可以减少错误输出。 Tactic 4: “Few-shot” prompting - give examples Few-shot prompting通过提供少量示例来引导模型理解任务格式和期望输出。 经典论文: Brown, T. B., et al. (2020). “Language Models are Few-Shot Learners.” NeurIPS. [论文链接] - 首次提出few-shot learning概念 Min, S., et al. (2022). “Rethinking the Role of Demonstrations: What Makes In-Context Learning Work?” EMNLP. [论文链接] ...

2026年3月12日 · Xiao Xiangtao

RAG (Retrieval-Augmented Generation)

RAG RAG (Retrieval-Augmented Generation) 是一种结合信息检索与文本生成的AI架构,通过检索外部知识库来增强LLM的回答能力。 经典论文: Lewis, P., et al. (2020). “Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks.” NeurIPS. [论文链接] - RAG开山之作 Guu, K., et al. (2020). “REALM: Retrieval-Augmented Language Model Pre-Training.” ICML. [论文链接] Izacard, G., & Grave, É. (2021). “Leveraging Passage Retrieval with Generative Models for Open Domain Question Answering.” EACL. [论文链接] - RAG的另一种实现 1. Context Window(上下文窗口) 概念 Context Window 指的是 大语言模型在一次推理时能够读取和理解的最大文本长度。 经典论文: Dai, Z., et al. (2019). “Transformer-XL: Attentive Language Models Beyond a Fixed-Length Context.” ACL. [论文链接] - 突破固定上下文长度的开创性工作 通常包含: ...

2026年3月8日 · Xiao Xiangtao

Transformer概念与理解

Transformer:从入门到产品视角 📚 导论:为什么Transformer如此重要? Transformer模型是由Vaswani等人在2017年发表的论文《Attention Is All You Need》中提出的神经网络架构。它彻底改变了自然语言处理领域,成为现代大语言模型(如GPT、BERT、LLaMA等)的基石。 核心创新:完全抛弃传统的CNN/RNN架构,仅使用注意力机制来捕捉序列依赖关系,实现了两大突破: 并行计算:解决了RNN无法并行的问题,大幅提升训练速度 长程依赖:解决了RNN/LSTM在处理长序列时的梯度消失问题 ...

2026年2月20日 · Xiao Xiangtao

Gensim训练词向量与Embedding相关知识

在进行文本分类的时候,预处理我们可以自己做一个词向量模型,也可以采用预训练的模型。采用预训练的模型比如谷歌基于goole news训练的Word2vec模型,由于在大量文本数据中训练过,所以词的概率分布会比较准确,当自己的数据集比较小的时候,用预训练数据有利于提升模型的准确度。 以下内容使用了tensorflow。 训练文本生成word2vec模型 自己训练模型一般有以下几步: 处理数据集,首先gensim的Word2Vec()方法需要的输入是句子顺序的单词,比如 我 爱 你 而不是我爱你,所以要将文本数据分词处理,在这个过程中,我们可以去除停用词,英文全部小写,语法统一等处理,可能对词向量的训练比较有帮助。 完成文本的处理以后,我们得到一个分词后的文本数据集,比如一个列表[‘she’, ‘is’, ‘beautiful’],在gensim模块中可以简单的使用model=gensim.models.word2vec.Word2Vec()得到训练的模型。 该方法有一些参数: sentences-即数据集;sg-设置训练算法,0代表CBOW,1代表skip-gram算法; size-指特征向量的维度,默认为100,大的size需要更多数据,效果更好,但是过大则浪费资源,效果提升不明显; window-当前词与预测词在一个句子中的最大距离,默认是5,比如 我 今天 成功 完成 工作,对于 成功,如果设置窗口为2,可能去预测的词就是我 今天 完成 和 工作,注意是最大值而不是一定选取四个词。最后模型输出的是一个概率分布,即一个词出现在其他词边的概率是多少,我们也就可以据此去发现相似的词。 min_count-去除词频小于min_count的词; hs-1采用hierarchy softmax,0采用negative sample; iter-迭代次数 workers-参数控制训练的并行数¨C9C 更多参考: //www.cnblogs.com/kjkj/p/9825418.html 其他训练词向量有相似的方法和思路,网上有很多资料。 使用预训练词向量 首先加载获取到准备好的模型,然后我们的目标是得到一个embedding_metrics即词向量矩阵,词向量矩阵的shape为(vocab_size, embedding_dim),它是我们要用于训练的数据的每个词(更具体的说是词表中的词)在训练好的模型中的词向量组成的矩阵。 接下来处理训练数据,即用tokenizer处理训练后的数据得到词表,然后将每条文本数据转变为用词表索引数字代替各单词表示的列表,这里给词编码的顺序是词频由高到低,再进行padding使句子输入变为定长,最后我们利用word_index和模型生成embedding_metrics,数据的准备就基本完成了。这些步骤使用tensorflow提供的api可以很简单的实现。 生成代码及相关解释如下: embedding_matrix = np.zeros((len(word_index) + 1, word2vec.vector_size)) # len(word_index) + 1,加1是因为word_index的标记是从1开始而非0,这样词索引与词向量刚好对应,并且对于padding后为 # 0的填充位置可以有对应的映射。 for word, index in word_index.items(): try: embedding_vector = word2vec.wv.getitem(str(word)) embedding_matrix[int(index)] = embedding_vector except KeyError: print("vector not found for word - %s" % word) Embedding层做了什么? Embedding层就是以one hot为输入、中间层节点为词向量维数的全连接层!而这个全连接层的参数,就是一个“词向量表”即我们的embedding_metrics,也就是说,其实onehot的作用就是查表,选择onehot表示的词对应的词向量,然后输出到下一层去。如果我们不用预处理的词向量,就是放一个空矩阵在embedding层(或者说是随机初始化参数),然后在训练网络过程中更新参数。 Embedding(len(vocab) + 1, embedding_dim, input_length=50, weights=[embedding_matrix], trainable=False) # (len(vocab) + 1, embedding_dim)与embedding_matrix的shape是一致的。 参考: ...

2020年5月22日 · Xiangtao XIAO

NLP分类效果衡量指标(F1/p/r)

概念 为什么要计算F1:避免样本分布带来的偏差,综合考量分类效果,假如有100个样本,其中1个正样本,99个负样本,如果模型的预测只输出0,那么正确率是99%,这时候用正确率来衡量模型的好坏显然是不对的。 真实 1真实 0预测 1True Positive(TP)False Positive(FP)预测 0False Negative(FN)True Negative(TN) 查准率(precision),预测正确的样本在所有预测为1的样本中的比例,该值反映有多少其他类被错误的归为该类。 召回率(recall),预测正确的样本在所有真实为1的样本中的比例,该值反映有多少该类被预测为其他类了。 F1(F1-Score), 精准率和召回率的调和平均数。 Micro-F1与Macro-F1 针对多标签分类而言衡量分类效果 Micro-F1:直接计算所有类别的Precision和Recall,然后计算F1。(类别有权重,分到样本数多的类别有更大的影响力) Macro-F1:计算出每一个类的Precision和Recall并分别计算F1,最后将F1平均。(各类别的F1权重相同) 代码实现 二分类 def f1(y_hat, y_true): ''' 输入张量y_hat是输出层经过sigmoid激活的张量 y_true是label{0,1}的集和 model指的是如果是多任务分类,single会返回每个分类的f1分数,multi会返回所有类的平均f1分数(Marco-F1) 如果只是单个二分类任务,则可以忽略model ''' epsilon = 1e-7 y_hat = tf.round(y_hat)#将经过sigmoid激活的张量四舍五入变为0,1输出 # 输入的数据是矩阵,标签为单行矩阵,预测值为单列矩阵,如果不是需要转换 tp = tf.cast(tf.matmul(y_true,y_hat), 'float') #tn = tf.sum(tf.cast((1-y_hat)<em>(1-y_true), 'float'), axis=0) fp = tf.cast(tf.matmul(1-y_true,y_hat), 'float') fn = tf.cast(tf.matmul(y_true,1-y_hat), 'float') print('tp: ', tp[0][0].numpy(),'fp: ', fp[0][0].numpy(),'fn: ', fn[0][0].numpy()) p = tp/(tp+fp+epsilon)#epsilon的意义在于防止分母为0,否则当分母为0时python会报错 r = tp/(tp+fn+epsilon) f1 = 2</em>p<em>r/(p+r+epsilon) result = [f1[0][0].numpy(), p[0][0].numpy(), r[0][0].numpy()] return result 多标签 import tensorflow as tf def f1(y_hat, y_true, model='multi'): ''' 输入张量y_hat是输出层经过sigmoid激活的张量 y_true是label{0,1}的集和 model指的是如果是多任务分类,single会返回每个分类的f1分数,multi会返回所有类的平均f1分数(Marco-F1) 如果只是单个二分类任务,则可以忽略model ''' epsilon = 1e-7 y_hat = tf.round(y_hat)#将经过sigmoid激活的张量四舍五入变为0,1输出 #tf.cast()转换张量数据类型 tp = tf.reduce_sum(tf.cast(y_hat</em>y_true, 'float'), axis=0) #取axis维数据求和 #tn = tf.sum(tf.cast((1-y_hat)<em>(1-y_true), 'float'), axis=0) fp = tf.reduce_sum(tf.cast((1-y_hat)</em>y_true, 'float'), axis=0) fn = tf.reduce_sum(tf.cast(y_hat<em>(1-y_true), 'float'), axis=0) p = tp/(tp+fp+epsilon)#epsilon的意义在于防止分母为0,否则当分母为0时python会报错 r = tp/(tp+fn+epsilon) f1 = 2</em>p*r/(p+r+epsilon) f1 = tf.where(tf.is_nan(f1), tf.zeros_like(f1), f1) if model == 'single': return f1 if model == 'multi': return tf.reduce_mean(f1) 参考 //blog.csdn.net/zjn295771349/article/details/84961596 ...

2020年5月22日 · Xiangtao XIAO

多标签分类(multi-label)分类方法笔记

概述 multi-label是相较multi-class的概念,有关研究相对较少,multi-label指一个数据可以被分为多个类,一个输入对应多个输出,例如一篇新闻可以被同时打上娱乐、体育等多个类,类的数目也不确定; 对于multi-label问题的处理,主要看到三种思路: 当类别之间没有较强的联系时,将multi-label转化为多个二分类问题,对于每个类专门训练一个分类器,然后将多个分类器对同个样本进行分类输出结果达到多标签的效果。 当类别之间有一定联系的时候,将multi-label转化为multi-class问题,比如用二进制编码表示三个类:[‘人’, ‘猫’, ‘狗’],0表示不是该类,1表示是,则对于多标签分类可能有[0, 1, 1]的情况比如一张图片上既有猫又有狗,那么我们可以将每一个向量作为一个类别,比如[0, 1, 1]作为一个类,将[1, 0, 1]作为一个类,这样一来我们得到一个23个类,对单一样本输出的结果一定在这个类别空间中,这样就是一个多分类问题了,总共8个类,可以用长度为8的独热编码表示。 当然对于类别特别多(n个类)的数据集,这时候类别空间就是2n,显然类别太多了运算压力大,可以选择将类别输出的种类限制在训练集数据中存在的类别中,比如[1, 0, 0]在训练集中没有这个输出,就把他从类别中去除,当然这会影响模型的准确程度,因为它不再识别那些被踢出的可能性。 最后一种就是改进算法使其能够直接处理多标签问题,输出多个类。 多标签分类算法 对于神经网络,简单的做法是在最后输出层使用sigmoid激活函数,输出数目为类别数,每个输出都是一个概率,注意输出的多个类别的概率总和不再是1,因为是多标签问题,然后损失函数用binary_crossentrophy,相当于对每个输出分别判断属不属于该类,从而使每一个可能属于的类的概率都趋近1。 在简单的单层CNN算法的实验上效果并不是很好,确实得到了多输出的结果,但是出现了某个类概率接近1,另一个所属类概率虽然也比较突出但数值偏小,比如0.5左右的样子,同时属于3个或4个类效果就更差些,可以通过修改阈值比如threshold=0.3,大于0.3就算做该类,但改善不明显。应该和数据集不同类对应存在的样本不同有关。

2020年5月22日 · Xiangtao XIAO

Natural Language Processing相关概念理解

NLP一般流程 文本预处理->词向量与文本表示->特征选择与特征抽取->分类算法 词向量与文本表示 词袋模型(BOW) 将所有词汇放进一个袋子里,假设有n个词,则每个句子表示为一个长度为n的词频向量,词频即对应词在句子里出现的次数,如果没有出现就是0。这种方法句子里的语义信息被完全遗失了。 word based encodings 另一种思路是表示句子,这样就可以把词在句子中的位置关系考虑进去,例如 “我 喜欢 猫”和 “我 喜欢 狗”分别表示为(0 1 2)和(0 1 3),这里的数字不再是词频,而是对应单词被分配的编码,如果词重复了,显然在数组中对应的数字也会重复。 padding 句子长度不同时,需要将他们转化为统一长度的向量输入到神经网络中训练,这时就要padding,设置一个长度n,如果句子长度小于n,就在数组左侧或右侧填充0,如果句子长了,就把左侧或右侧多余的部分忽略,具体方位由自己选择。 词向量模型(word embedding) 考虑词与词之间的位置关系。原本用随机分配的数字代表每一个词,词与词之间是完全独立的,而embedding使得每一个词成为了一个n维空间中的向量,如果两个词的含义相近,那么相应的向量距离也就进,这样就考虑到了词的含义。 word2Vec : 底层采用基于CBOW和Skip-Gram算法的神经网络模型。 CBOW模型: CBOW模型的训练输入是某一个特征词的上下文相关的词对应的词向量,而输出就是这特定的一个词的词向量。由于CBOW使用的是词袋模型,因此上下文的几个词都是平等的,也就是不考虑他们和我们关注的词之间的距离大小,只要在我们上下文之内即可。 这样我们这个CBOW的例子里,我们的输入是上下文选定的词向量,输出是所有词的softmax概率(训练的目标是期望训练样本特定词对应的softmax概率最大),对应的CBOW神经网络模型输入层有4个神经元,输出层有词汇表大小个神经元。隐藏层的神经元个数我们可以自己指定。通过DNN的反向传播算法,我们可以求出DNN模型的参数,同时得到所有的词对应的词向量。这样当我们有新的需求,要求出某4个词对应的最可能的输出中心词时,我们可以通过一次DNN前向传播算法并通过softmax激活函数找到概率最大的词对应的神经元即可。 Skip-Gram模型: Skip-Gram模型和CBOW的思路是反着来的,即输入是特定的一个词的词向量,而输出是特定词对应的上下文词向量。 这样我们这个Skip-Gram的例子里,我们的输入是特定词, 输出是softmax概率排前几的词,对应的Skip-Gram神经网络模型输入层有1个神经元,输出层有词汇表大小个神经元。隐藏层的神经元个数我们可以自己指定。通过DNN的反向传播算法,我们可以求出DNN模型的参数,同时得到所有的词对应的词向量。这样当我们有新的需求,要求出某1个词对应的最可能的4个上下文词时,我们可以通过一次DNN前向传播算法得到概率大小排前4的softmax概率对应的神经元所对应的词即可。 词向量模型突出特点: 在词向量模型中,词向量与词向量之间有这非常特殊的特性。例如现在存在国王、男生、女人、皇后四个词向量,那么一个完善的词向量模型,就存在“国王-男人+女人=皇后”这样的关系。 参考: 词袋模型(BOW,bag of words)和词向量模型(Word Embedding)概念介绍

2020年5月21日 · Xiangtao XIAO

卷积神经网络(CNN)理论与实现

一、理论 卷积神经网络结构:(卷积层+(可选)池化层)*N+全连接层*M(M>=0),卷积层的输入输出是矩阵,全连接层输入输出是向量,在卷积层的最后一层做一个展平。 主要用于分类任务 全卷积神经网络:(卷积层+(可选)池化层)*N+反卷积层*K,可以做物体分割类任务 卷积操作 解决参数过多导致的计算资源不足,容易过拟合的问题。解决方法:局部连接(基于图像的区域性)、参数共享(基于图像特征与位置无关) 卷积核是反向传播计算出的参数,卷积:卷积核与输入做点积乘法。步长:卷积核每次在输入上滑动的距离。padding:使输出size不变。 池化操作 类似卷积,计算方式不同,最大值池化:池化核滑动覆盖区域的最大值作为结果输出。 特点:常使用不重叠(kernal-size=步长)、不补零的操作。参数即为步长和池化核大小。用于减少图像尺寸,从而减少计算量。一定程度平移鲁棒。损失了空间精度。 二、实现 embedding_dim = 16 batch_size = 128 cnn_model = keras.models.Sequential([ keras.layers.Embedding(vocab_size, embedding_dim, input_length=max_length), keras.layers.Conv1D(filters=256,kernel_size=2,kernel_initializer='he_normal', strides=1,padding='SAME',activation='relu'), keras.layers.GlobalMaxPooling1D(), keras.layers.Dropout(rate=0.5), keras.layers.Dense(12, activation='sigmoid') ]) cnn_model.summary() cnn_model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) Conv1D 在文本中,卷积的某一维大小往往为embedding长度,即在宽度上不需要窗口移动,宽度就是整个窗口,所以conv1d默认卷积的宽度就为embedding维度,长度通过kernel_size来指定的,此处为2,即卷积核的大小为2*embedding_size。strides为步长,此处为1,即卷积核每隔一个单词移动一次。filters是卷积核的个数,即输出的维度。padding有valid和same两种选择,valid在长度方向(宽度方向不padding)不进行padding,而same则在长度方向进行padding,保证输入句子长度和卷积后输出的句子长度一致。 //blog.csdn.net/bobobe/article/details/87923618 tensorflow fit()方法:参考 //blog.csdn.net/crazyman2010/article/details/103705318 TextCNN //blog.csdn.net/u014732537/article/details/79573174

2020年5月21日 · Xiangtao XIAO

MNIST手写数字识别实践

from __future__ import absolute_import, division, print_function, unicode_literals import tensorflow as tf mnist = tf.keras.datasets.mnist (x_train, y_train), (x_test, y_test) = mnist.load_data() # 加载数据 x_train, x_test = x_train / 255.0, x_test / 255.0 # /255:将RGB数值归一化 #%% print(y_train.shape) #%% model = tf.keras.models.Sequential([ tf.keras.layers.Flatten(input_shape=(28, 28)), # 张量扁平化,将28*28的图片矩阵转化为784的向量 tf.keras.layers.Dense(128, activation='relu'), # 全连接层,128个神经元,激活函数为relu(The Rectified Linear Unit) # y=max(0,x) tf.keras.layers.Dropout(0.2), # 防止过拟合,drop out 80% of inputs,使用0.2*cell_size个神经元进行训练 tf.keras.layers.Dense(10, activation='softmax') # 全连接层输出 softmax激活函数 ]) model.compile(optimizer='adam', # 梯度下降策略 adam loss='sparse_categorical_crossentropy', # 损失函数 sparse:y独热化编码 交叉熵 metrics=['accuracy']) # metrics 列表,包含评估模型在训练和测试时的性能的指标,典型用法是metrics=[‘accuracy’]。 # 如果要在多输出模型中为不同的输出指定不同的指标,可向该参数传递一个字典,例如metrics={‘output_a’: ‘accuracy’} model.fit(x_train, y_train, epochs=5) # 训练5轮 model.evaluate(x_test, y_test, verbose=1) # Verbosity mode. 0 = silent, 1 = progress bar. # fit()用于使用给定输入训练模型. # evaluate()用于评估已经训练过的模型.返回损失值&模型的度量值.

2020年5月20日 · Xiangtao XIAO