面向AI应用开发实战分享 - 基础篇

“前端转AI,第一讲来了”

引言

如果你是一名前端开发,同时又对AI开发很感兴趣,那么恭喜你,机会来了。

如果不是也没关系,同样能帮大家了解AI应用的开发思路。

本文将带大家从面向AI开发的基础知识开始,再到RAG,Agent,流程编排,深入了解如何在企业内部落地AI项目。

基础篇

一、如何面向AI交互

通常,我们使用一段文字输入,AI模型都会基于大模型自身来进行回答,这个相信大家已经都非常了解。但是,如果想让AI能够基于我们所期待的内容回答,或者说是基于我们的私域信息来进行回答,我们有哪些办法?

1. 模型训练
2. 微调Fine-tuning
3. Prompt提示词工程
4. RAG检索增强生成

模型训练:

通过从huggingface下载开源模型,在本地完成部署,比如最新推出的Llama 3 8B版,小模型对GPU的要求会相对低些,后通过大量的文档资料完成模型训练。

虽说小型模型降低了GPU的算力资源但成本也不是普通企业能承担的,除了自身的硬件成本、模型优化的人力成本,也存在模型的汰换风险,一旦外部大厂出个大招,那我们训练的模型就会面临淘汰,但企业也应采取防御型战略,先拥抱,毕竟AI已是大势所趋,模型在应用层接口方面在开源社区里已经标准化,开发设计时模型与功能解耦,随时替换。

微调Fine-tuning:

很多商业AI的服务模型都提供了这一能力,允许用户针对特定的应用场景调整预训练好的模型,以获得更符合预期的输出结果。

比如,你的公司有一个内部项目代号为"Project”,您希望使用LLM模型来自动生成关于"Project"的文档或回答员工关于"Project"的查询。但预训练模型没有接触过"Project"这个术语,因此无法生成相关的准确信息。这时候就可以通过一些术语或上下文来调整模型对于这一块的理解。

最后,微调是一种付费服务,如果未来换其他模型,你需要重新进行微调以适应新模型的特性和改进。这将再次产生计算和时间成本。

Prompt提示词工程:

这个应该是刚接触AI开发的同学,最先使用的,让AI能够按照我们的期望完成指令交付的方式。比如,让模型尽量用中文回答。你需要准备一份包含角色、背景、技巧、输出风格、输出范围等的Prompt提示词,然后在每次通讯时携带在上下文里。

如果你使用chat_model(Langchain术语)方式,则会在message数组的0键位一直保持system prompt,如果是LLM(Langchain术语)方式,则是在每次通讯时的message字符串里包装prompt+question,这里我们更应该基于chat_model方案来开发。

但是当你想要正式的投入到自己的项目中时,你可能会发觉Prompt非常难优化,AI并不能完全按照你的要求去执行。总结,Prompt会有以下几个痛点:

1. 设计难度大,如果模型的输出依赖于我们的提示词反馈,这可能会形成一个循环,我们需要不断地调整提示词以获得更好的输出。
2. 长度限制,每次通讯的message通常会包含:Prompt + n轮上下文history + 本次的question,这些内容的总文字数也是计算我们单次会话的token总成本,过长的prompt很容易使AI产生幻觉,影响回复结果。
3. Prompt依然无法解决让模型面向私域,我们公司内部的知识库进行回答

RAG检索增强生成:

RAG对刚接触的同学可能会比较抽象,借用Langchain的图来介绍一下

1. 首先是embedding向量存储

我们把内部文档在提取内容后进行切片,将内容转为段落数组(chunk),然后传入大模型的embed接口,模型会返回浮点数字,这个过程就是embedding,最后我们会把浮点数存入向量库,常见的向量库有es、faiss

图片

2. 接着是内容召回

输入一个问题,先通过模型embedding把问题转为向量数据,然后在我们的文档库里进行相似度搜索,召回相似度接近的数据后再交由大模型进行总结,最后返回给用户

图片

以上就是RAG的整个过程,RAG是个非常考验技术的工作,以上的流程是无法描述出RAG复杂性的,包括我们的产品在上线后,至今还在不断尝试如何更好的提升RAG的质量,做到能用很简单,但要做好非常难。

后面讲到内部知识库时再来讨论目前我们的方案,和线上实际效果。

引用在其他文章里看到的一句话,感同身受

RAG涉及的内容其实广泛,包括Embedding、分词分块、检索召回(相似度匹配)、chat系统、ReAct和Prompt优化等,最后还有与LLM的交互,整个过程技术复杂度很高。如果你用的LLM非常好,反而大模型这一块是你最不需要关心的。而这些环节里面我们每个都没达到1(比如0.9、0.7...),那么最终的结果可能是这些小数点的乘积。

https://mp.weixin.qq.com/s/WjiOrJHt8nSW5OGe2x4BAg

二、Agent

前面主要是AI在文字内容上的交付,那如何让AI完成工作的交付呢?

当在工作汇报时,如果能用下面这张图来演示你的AI Agent功能,会不会很有吸引力?

图片

(取自QCon上的一张分享图)

目前想实现Agent,主要有以下2种方式

ReAct自我推理

Few-shot Prompt + Thought + Action + Observation 

通过构造一个内含工具、推理和规划的prompt结构,模型在内部通过与提示的互动进行自我迭代和调整,以选择适当的工具或生成更好的输出。

例如:

{    "messages": [        {            "role": "system",            "content": "Assistant is a large language model trained by OpenAI.\n\nAssistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.\n\nAssistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.\n\nOverall, Assistant is a powerful system that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist. However, above all else, all responses must adhere to the format of RESPONSE FORMAT INSTRUCTIONS."        },        {            "role": "user",            "content": "TOOLS\n------\nAssistant can ask the user to use tools to look up information that may be helpful in answering the users original question. The tools the human can use are:\n\ninfo-tool: Useful for situations where you need to retrieve content through one or more URLs from https://info.bilibili.co/. Input should be a comma-separated list in the format of \"one or more valid URLs with the domain https://info.bilibili.co/pages/viewpage.action, where the URL should include the pageId parameter\", followed by \"the information you need to summarize, or to obtain a summary\".\n\nRESPONSE FORMAT INSTRUCTIONS\n----------------------------\n\nOutput a JSON markdown code snippet containing a valid JSON object in one of two formats:\n\n**Option 1:**\nUse this if you want the human to use a tool.\nMarkdown code snippet formatted in the following schema:\n\n```json\n{\n    \"action\": string, // The action to take. Must be one of [info-tool]\n    \"action_input\": string // The input to the action. May be a stringified object.\n}\n```\n\n**Option #2:**\nUse this if you want to respond directly and conversationally to the human. Markdown code snippet formatted in the following schema:\n\n```json\n{\n    \"action\": \"Final Answer\",\n    \"action_input\": string // You should put what you want to return to use here and make sure to use valid json newline characters.\n}\n```\n\nFor both options, remember to always include the surrounding markdown code snippet delimiters (begin with \"```json\" and end with \"```\")!\n\n\nUSER'S INPUT\n--------------------\nHere is the user's input (remember to respond with a markdown code snippet of a json blob with a single action, and NOTHING else):\n\nhttps://info.bilibili.co/pages/viewpage.action?pageId=849684529\n这篇文章讲了什么"        }    ]}

我们通过Prompt告诉模型,它善于使用工具来解决问题,告诉它每一个工具的介绍,和需要填入什么参数,最后要求模型每次回复时必须遵循使用markdown code格式返回,然后我们会在Agent进程里消费返回的json-schema,是调用工具还是Final Answer

Tool-call 代理交互

很明显ReAct会导致我们的上下文过长,很容易造成模型在经过几轮迭代之后不已markdown code的格式来返回内容,最终导致Agent走不下去。

tool-call的出现解决了这一问题,我们会把Prompt里这些非结构化的工具描述转化为结构化的api字段,这样既节省了Prompt的上下文长度,也变的容易控制

例如:

// POST /chat/completions{  ...  "tools": [      {        "type": "function",        "function": {          "name": "info-tool",          "description": "打开一个或多个带有pageId的xxxx网站,完成用户需求",          "parameters": {            "type": "object",            "properties": {              "pageId": {                "type": "number",                "description": "请填写网址里的pageId,多个用逗号隔开"              },              "task": {                "type": "string",                "description": "描述需求"              }            },            "required": [              "pageId",              "task"            ],            "additionalProperties": false,            "$schema": "http://json-schema.org/draft-07/schema#"          }        }      },      ...更多其他工具  ],  ...}

此时,模型也会以结构化的方式告诉你他使用的工具

// API Response{    ...    "tool_calls": [        {            "index": 0,            "id": "info-tool:0",            "type": "function",            "function": {            "name": "info-tool",            "arguments": "{\n    \"task\": \"获取页面内容\",\n    \"pageId\": 845030990\n}"            }        }    ]    ...}

三、开发框架

再来介绍下我们选择的技术框架,之后也会介绍其优点和不足之处

Langchain

在许多讨论AI的文章里都会提到Langchain,或者很多的开源框架都在和Langchain作比较。Langchain是一个集成了商业和开源模型,并提供了一整套工具和功能,简化了开发、集成和部署基于语言模型的应用。

- 组件化:为使用语言模型提供抽象层,以及每个抽象层的一组实现。组件是模块化且易于使用的,无论是否使用LangChain框架的其余部分。
- 现成的链:结构化的组件集合,用于完成特定的高级任务

通俗的讲,它为不同的模型,不同的组件提供了统一的输入和输出规范。

在Chain里可以传入[Prompt、Model、Tool、Memory(历史会话)、OutputParser],也能将多个model进行嵌套,让上一个model的输出作为下一个PromptTemplate的输入

目前官方提供了2种语言的版本,一个是Python,另一个是Nodejs

Flowise

基于Langchain的AI流程编排系统,主语言Nodejs,为Langchain的每个模型类和组件类提供了可视化的低代码组件,通过在画布上的拖拽组件,即可完成AI的整套交付流程,组件包括Chain(进程)、Prompt、Agent Tool、Chat Module等。

同类的还有Dify,它提供了多模型对接、RAG、任务编排、等整套的产品化方案。

Flowise更像是一个毛坯房,提供了解决方案,但所有的产品化还是需要自己开发,读懂它,能让你在开发Langchain时事半功倍。Dify更像豪华大别墅,大多数的功能都已经做好了产品化,内部独立维护了与模型的api封装,主语言Python。

Flowise中的packages介绍:

- Server:express,CRUD、完成组件库内的实例运行
- Component:JavaScript,实现Langchain类的可视化和低代码
- UI:React,AI流程编排的画布,和一些维护页面

以下是一个通过Agent由AI判断选择使用哪些工具的编排展示,我们重新开发了Agent组件,已更适应我们的tool-call功能,在Bili Agent主进程中,组件会负责消费这些关联了的工具

图片

部分代码示例​​​​​​​

import { AgentExecutor } from 'langchain/agents' // 将工具的配置信息转为model接口里tools的结构化字段// 由于对齐了接口规范,所以可以直接使用formatToOpenAITool函数const modelWithTools = model.bind({    tools: [...tools.map((tool: any) => formatToOpenAITool(tool))]}) // 按顺序组合const runnableAgent = RunnableSequence.from([    // 包含了用户的指令,和将模型消息里的tool_calls format后得到的ToolMessage,和上下文聊天记录    // 以上这些都会输入给prompt    {        [inputKey]: (i: { input: string; steps: AgentStep[] }) => i.input,        agent_scratchpad: (i: { input: string; steps: ToolsAgentStep[] }) => formatToolAgentSteps(i.steps),        [memoryKey]: async (_: { input: string; steps: AgentStep[] }) => {            const messages = (await memory.getChatMessages(flowObj?.sessionId, true, chatHistory)) as BaseMessage[]            return messages ?? []        }    },    prompt,    modelWithTools,    new OpenAIToolsAgentOutputParser()]) const executor = AgentExecutor.fromAgentAndTools({    agent: runnableAgent,    tools,    returnIntermediateSteps: true,    maxIterations: 5}) executor.invoke({input: '明天是几月几号?'}) // tool_calls示例{    "tool_calls": [      {        "index": 0,        "id": "GetDate:0",        "type": "function",        "function": {          "name": "GetDate",          "arguments": "{\n    \"task\": \"获取明天的日期\"\n}"        }      }    ]}

最后通过Agent的配置,就可以让模型在通用域和私域或是工具插件里自由的选择进行聊天

图片

以上就是基础篇的全部内容,至此可以发现,为什么本篇开头会提到恭喜前端。是的,以上技术栈全部来自前端领域。

在下篇文章中,会从我们项目应用的角度,分享一下产品化的AI平台应具备哪些解决方案,同时我们也引入了前端其他领域的技术,如:低代码、云函数。

-End-

作者丨Zerooo

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/23714.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AlaSQL.js:用SQL解锁JavaScript数据操作的魔法

简介 先附上 github 地址 https://github.com/AlaSQL/alasql AlaSQL.js - JavaScript SQL database for browser and Node.js. Handles both traditional relational tables and nested JSON data (NoSQL). Export, store, and import data from localStorage, IndexedDB, or …

高德车道级安全预警再升级 10大场景全方位守护行车安全

今日起,2024年高考、端午节小长假相继到来,正值新一波出行高峰到来,高德地图车道级安全预警功能再次升级。升级后的车道级安全预警功能覆盖了10大安全风险较高的行车场景,全方位、超视距地为用户实时探测、预警行车风险&#xff0…

成都跃享未来教育咨询有限公司,值得信赖!

在浩渺的教育咨询市场中,成都跃享未来教育咨询有限公司以其独特的魅力和卓越的服务质量,成为了行业内的璀璨明星。作为一家致力于为学生提供全方位教育咨询服务的公司,成都跃享未来教育咨询有限公司始终坚持安全可靠的原则,为广大…

树莓派4B_OpenCv学习笔记4:测试摄像头_imread加载显示图像_imwrite保存图片

今日继续学习树莓派4B 4G:(Raspberry Pi,简称RPi或RasPi) 本人所用树莓派4B 装载的系统与版本如下: 版本可用命令 (lsb_release -a) 查询: Opencv 版本是4.5.1: 今日对之前的测试CSI摄像头函数进行一些理解说明&#x…

降噪是什么意思?视频如何降噪?一文了解全部

在视频制作的过程中,我们经常会遇到噪音问题,这些噪音可能来自拍摄环境、录制设备或其他源头。然而,对于初学者来说,降噪是什么意思,以及如何有效地在视频中进行降噪可能是一些疑惑的问题。本文将深入解释降噪的概念&a…

【算法】深入浅出爬山算法:原理、实现与应用

人不走空 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌赋:斯是陋室,惟吾德馨 目录 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌…

echarts学习: 绘制双y轴折线图

前言 我们公司项目中的折线图大都是双y轴的,因为这些图表往往需要同时展示水位和流量这两种不同单位的数据,因此如何绘制双y轴折线图就是就是我所面临的首要问题。 1.如何绘制双y轴 将yAxis属性的值设置为一个数组,并在数组中添加两个axis对…

AI辅助论文:探索AI查重与AI降重技术

在科研领域,AI写作工具如同新一代的科研利器,它们能够极大提高文献查阅、思路整理和表达优化的效率,本质上促进了科研工作的进步。AI写作工具不仅快速获取并整理海量信息,还帮助我们精确提炼中心思想,显著提升论文写作…

0606 作业

#include <stdio.h> #include <string.h>typedef struct usr{char unm[21];char pwd[21]; }user;int main(int argc, const char *argv[]) {FILE* userfilefopen("./user_tible.txt","r");printf("输入username:");user u;scanf(&qu…

人工智能在肿瘤预后预测中的最新研究进展|顶刊精析·24-06-07

小罗碎碎念 今天要分享的文献主题&#xff0c;大家一定非常熟悉&#xff0c;因为绝大多数AI4cancer的文章都会提到它——预后预测&#xff0c;所以今天的文献主题是——人工智能肿瘤预后预测。 在正式开始分享之前&#xff0c;我想先带着大家梳理两个问题。解决了以下两个问…

【Python】实现极致:克服PyInstaller打包挑战,解决libpython3.10.so.1.0库丢失难题

【Python】实现极致&#xff1a;克服PyInstaller打包挑战&#xff0c;解决libpython3.10.so.1.0库丢失难题 大家好 我是寸铁&#x1f44a; 总结了一篇【Python】实现极致&#xff1a;克服PyInstaller打包挑战&#xff0c;解决libpython3.10.so.1.0库丢失难题✨ 喜欢的小伙伴可以…

ai智能全自动批量剪辑软件神器,让视频创作变得简单!

随着科技的飞速发展&#xff0c;人工智能技术在各个领域都取得了突破。在视频制作领域&#xff0c;AI智能全自动批量剪辑软件神器的出现&#xff0c;为视频创作者带来了前所未有的便利。接下来咱们详细介绍这款软件的特点和优势&#xff0c;以及它如何让视频创作变得更加简单。…

【网络安全的神秘世界】Kali安装中文输入法

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 今天就手把手教你如何在kali中安装和配置输入法 首先&#xff0c;打开终端&#xff0c;输入下面这行代码&#xff1a; # sudo apt install ibus ibus-pi…

【机器学习】Python与深度学习的完美结合——深度学习在医学影像诊断中的惊人表现

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 一、引言二、深度学习在医学影像诊断中的突破1. 技术原理2. 实际应用3. 性能表现 三、深度学习在医学影像诊断中的惊人表现1. 提高疾病诊断准确率2. 辅助制定治疗方案 四、深度学习对医疗行业的影响和推动作用 一、引言 随着…

网络安全领域六大顶级会议介绍:含会议介绍、会议地址及会议时间和截稿日期

**引言&#xff1a;**从事网络安全工作&#xff0c;以下六个顶会必须要知道&#xff0c;很多安全的前沿技术都会在如下会议中产生与公开&#xff0c;如下会议发表论文大部分可以公开下载。这些会议不仅是学术研究人员展示最新研究成果的平台&#xff0c;也是行业专家进行面对面…

[洛谷] 刷题栈 队列

目录 1.后缀表达式 2.表达式括号匹配 3.表达式求值 4.表达式的转换 5.机器翻译 1.后缀表达式 后缀表达式 - 洛谷 #include<iostream> #include<cstdio> using namespace std;int stk[100]; // 用于存储操作数的栈 int index 0; // 栈顶索引int main() {c…

C++开发基础之初探CUDA计算环境搭建

一、前言 项目中有使用到CUDA计算的相关内容。但是在早期CUDA计算环境搭建的过程中&#xff0c;并不是非常顺利&#xff0c;编写此篇文章记录下。对于刚刚开始研究的你可能会有一定的帮助。 二、环境搭建 搭建 CUDA 计算环境涉及到几个关键步骤&#xff0c;包括安装适当的 C…

分析示例 | Simufact焊接工艺仿真变形精确预测汽车结构

导语 焊接是汽车制造过程中一个关键环节&#xff0c;白车身、发动机、底盘和变速箱等都离不开焊接工艺的应用&#xff0c;主要涉及气保焊、电阻点焊、激光焊、电子束焊等多种焊接工艺。由于汽车车型众多、成形结构复杂、汽车制造质量、效率、成本等方面的综合要求。如何高效、…

杰理AC632N提升edr的hid传输速率, 安卓绝对坐标触摸点被识别成鼠标的修改方法

第一个问题: 首先修改edr的hid传输速率.修改你的板级配置,里面的一个地方给注释掉了,请打开那个注释就能提升edr的hid传输效率了 第二个问题: 修改632n系别把触摸板的hid报告描述符识别成鼠标点,修改如下: 注释掉上面的pnp,改成下面的

element plus的容器组件

element-plus的容器组件主要有el-container,el-aside,el-header,el-main,el-footer,后面4个组件其父组件必须是el-container。 el-container采用flex布局&#xff0c;如果其子元素包含el-header或el-footer时会采用垂直布局&#xff0c;否则会采用水平布局&#xff0c;可设置其…