面向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.rhkb.cn/news/343038.html

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

相关文章

攻防实战 | 邮件高级威胁检测与自动化响应

历经三个月的时间,年度重磅直播节目Fortinet 2024年度“Demo季”近日终于迎来了备受瞩目的压轴大戏——Demo Day第三期,主题为《新邮件安全下的高级威胁检测与自动化响应》。继成功举办了前两期《企业网络中的多源威胁情报自动化整合与集成》和《应急响应…

人工智能绘画的历史

人工智能绘画的起源可以追溯到20世纪50年代。当时,艺术家和科学家开始使用计算机生成图像和图形,将绘画艺术与技术领域相结合。计算机图像可以被视为人工智能绘画的一部分。下面,我们将按照时间顺序来了解人工智能绘画发展的一些关键时间节点…

代码审计(1):CVE-2022-4957分析及复现

0x00漏洞描述: ѕрееdtеѕt iѕ а vеrу liɡhtԝеiɡht nеtԝоrk ѕрееd tеѕtinɡ tооl imрlеmеntеd in Jаvаѕсriрt. Thеrе iѕ а Crоѕѕ-ѕitе Sсriрtinɡ vulnеrаbilitу in librеѕроndеd ѕрееdtеѕt…

JeeSite 快速开发平台 Vue3 前端版介绍

JeeSite 快速开发平台 Vue3 前端版介绍: 它构建于 Vue3、Vite、Ant-Design-Vue、TypeScript 以及 Vue Vben Admin 等最前沿的技术栈之上,能助力初学者迅速上手并顺利融入团队开发进程。涵盖的模块包括组织机构、角色用户、菜单授权、数据权限、系统参数…

小牛翻译API详解:功能、优势介绍及案例实战(附完整代码)

写在前面小牛翻译是做什么的案例-调用图片翻译API进行英文翻译✔准备工作✔获取密钥✔调用API✔完整代码✔运行项目 使用建议 写在前面 随着全球化的快速发展和跨国交流的增多,翻译软件的市场需求持续增长。根据市场数据,全球语言翻译软件市场规模在过去…

Linux命令篇(六):vi/vim专项

💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝您生活愉快! 文章目录 一、什么是vim二…

Vue3入门 - vue3相比于vue2的优点,及如何创建Vue3项目

目录 一、认识Vue3 1. Vue2 选项式 API vs Vue3 组合式API 2. Vue3的优势 二、使用create-vue搭建Vue3项目 1. 认识create-vue 2. 使用create-vue创建项目 3.熟悉项目和关键文件 一、认识Vue3 1. Vue2 选项式 API vs Vue3 组合式API <script>export default …

操作系统教材第6版——个人笔记6

3.3.4 页面调度 页面调度 当主存空间已满而又需要装入新页时&#xff0c;页式虚拟存储管理必须按照一定的算法把已在主存的一些页调出去 #主存满加新&#xff0c;把已在主存一些页调出选择淘汰页的工作称为页面调度 选择淘汰页的算法称为页面调度算法 页面调度算法设计不当&a…

BERT应用——文本间关联性分析

本文结合了自然语言处理&#xff08;NLP&#xff09;和深度学习技术&#xff0c;旨在分析一段指定的任务文本中的动词&#xff0c;并进一步探讨这个动词与一系列属性之间的关联性。具体技术路径包括文本的词性标注、语义编码和模型推断。 一、技术思路 NLP和词性标注 在自然…

基于fabric封装一个简单的图片编辑器(vue 篇)

介绍 前言vue demo版本react 版本 前言 对 fabric.js 进行二次封装&#xff0c;实现图片编辑器的核心功能。核心代码 不依赖 ui响应式框架vue ,react 都适用。 只写了核心编辑相关代码便于大家后续白嫖二次开发 核心代码我就没有打包发布 会 和 业务代码一起放到项目中。 vu…

鸿蒙轻内核M核源码分析系列九 互斥锁Mutex

多任务环境下会存在多个任务访问同一公共资源的场景&#xff0c;而有些公共资源是非共享的临界资源&#xff0c;只能被独占使用。鸿蒙轻内核使用互斥锁来避免这种冲突&#xff0c;互斥锁是一种特殊的二值性信号量&#xff0c;用于实现对临界资源的独占式处理。另外&#xff0c;…

博客系统测试报告

博客系统 测试报告 一、项目背景 一个Web网站程序&#xff0c;你可以观看到其他用户博客也可以登录自己的账号发布博客&#xff0c;通过使用Selenium定位web元素、操作测试对象等方法来对个人博客系统的进行测试&#xff0c;测试的核心内容有用户登录、博客列表及博客数量的展…

pypi 发布自己的包

注册pypi个人用户 网址&#xff1a;https://pypi.org 目录结构dingtalk_utils 必须-pkgs- __init__.py .gitignore LICENSE 必须 README.md 必须 requirements.txt setup.py 必须安装依赖 pip install setuptools wheel安装上传工具 pip install twinesetup.py i…

基于ChatGLM3的本地问答机器人部署流程

基于ChatGLM3的本地问答机器人部署流程 前言一、确定文件结构1.新建文件夹储存本地模型2.下载源码和模型 二、Anaconda环境搭建1.创建anaconda环境2.安装相关库3.设置本地模型路径4.启动 三、构建本地知识库1.下载并安装postgresql2.安装c库3.配置向量插件 四、线上运行五、 全…

【全开源】JAVA打车小程序APP打车顺风车滴滴车跑腿源码微信小程序打车源码

&#xff1a;构建便捷出行新体验 一、引言&#xff1a;探索打车系统小程序源码的重要性 在数字化快速发展的今天&#xff0c;打车系统小程序已成为我们日常生活中不可或缺的一部分。它以其便捷、高效的特点&#xff0c;极大地改变了我们的出行方式。而背后的关键&#xff0c;…

从零开始学JAVA

一、编写Hello world程序 public class JavaMain1 {//主程序执行入口&#xff0c;main方法public static void main(String[] args){System.out.println("Hello world!");} } 运行结果 Hello world! java编写主程序常见错误&#xff1a; 1、System ---首字母没有…

外汇天眼:金融服务补偿计划(FSCS)确认已任命清算人为TenetConnect Services有限公司

2024年6月5日&#xff0c;Tenet Group有限公司的董事们任命了Interpath有限公司的Ed Boyle、Howard Smith和Rob Spence为联合清算人。Ed Boyle和Rob Spence也被任命为其子公司Tenet有限公司、TenetConnect有限公司和TenetConnect Services有限公司的联合清算人。Tenet Mortgage…

应对800G以太网挑战:数据中心迁移

在过去几年中&#xff0c;云基础设施和服务的大规模使用推动了对更多带宽、更快速度和更低延迟性能的需求。交换机和服务器技术的改进要求布线和架构随之调整。因此&#xff0c;800G以太网对数据中心迁移的需求&#xff0c;特别是对速率&#xff08;包括带宽、光纤密度和通道速…

突破性技术: 大语言模型LLM量化激活outliers异常值抑制

LLM过去有两种突破性技术大大提升了量化精度&#xff0c;分别是group-wise量化和GPTQ/AWQ量化。前者相比于过去的per-tensor和per-channel/per-axis量化提出了更细粒度的对channel拆分为更小单元的量化方式&#xff0c;后者通过巧妙的算法明显提升了4bit量化的精度。 LLM量化存…

接口的应用、 适配器设计模式

接口的应用 适配器设计模式 Inter package com.itheima.a09;public interface Inter {public abstract void show1();public abstract void show2();public abstract void show3();public abstract void show4();}InterAdapter package com.itheima.a09; //抽象 public abs…