
ChatGPT的问世,大语言模型(LLM)技术引发全球关注。在大模型技术落地的最佳实践中,智能体(Agent)架构显现出巨大潜力,成为业界的普遍共识,各大公司也纷纷启动Agent技术验证项目。基于此背景,广告产研团队对Agent的应用进行了一些探索,并打造了京东广告投放Agent应用——京准通智能助手。京准通智能助手历经多个版本迭代,已经具备智能客服、数据查询、广告创编等AI能力,逐渐成为广告主的超级助手。这背后,依托于我们构建的AI工程化技术体系。本文将详细介绍京准通智能助手的构建过程,并系统化阐述AI工程能力建设中的关键技术实践与创新方法论。欢迎商家伙伴体验:https://jzt.jd.com
1.1 Agent 在京东广告投放中的应用场景
经过前期我们对Agent应用方向的探索和尝试,确定了Agent在京东广告投放中落地的两个主要的场景:' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
1.2 Agent 工程能力实现
在明确具体应用场景的基础上,依托前期技术积累与探索成果,工程实现层面需重点构建RAG和Function Call两大核心技术能力,为智能客服与智能指令场景的应用提供技术支撑。下面将深入阐述这两大核心能力的实现方案。RAG能力在实际应用中,经历过多次升级迭代,主要分为两个版本:RAG1.0、RAG2.0RAG1.0版本中完成了基础能力的建设,包含两部分:离线知识构建、在线推理引擎。' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
离线知识构建的核心工作是将知识转化为向量并存储。主要有以下几个步骤:1.产品/运营将相关业务的知识整理成文档(Markdown、Excel等)2.根据不同格式和切割方式将内容切割成若干个内容块3.调用embedding model,进行内容向量化' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
在线推理引擎提供实时在线服务,核心工作是检索相关知识并调用大模型解决问题。主要有以下几个步骤:1.收到用户Query,调用embedding 模型,进行向量化,获得向量。2.根据Query的向量,在向量库中进行相关性检索,获得和Query相关的知识[{
"_score": 0.7526149153709412,//相关性分值
"_source": {
"title": "搜索快车-定向设置-关键词定向-功能入口",
"content": " 搜索快车->新增/编辑快车推广单元->添加关键词...",
"status": 1,
//更多字段...
},
},
//更多知识...
]
3.拼接提示词,要让模型更方便理解,需要将知识处理成特定的格式//这里不方便展示业务真实的提示词,以下仅提供大致思路
请根据信息
"""
搜索快车-搜索快车投放要素-定向设置-关键词定向-功能入口
- 搜索快车->新增/编辑快车推广单元->添加关键词;
//更多知识...
"""
回答问题
"""
搜索快车关键词设置
"""
4.调用大模型接口,传入拼接好的提示词,获取结果返回给用户。{"output": "在搜索快车中进行关键词设置的步骤如下:\n\n1. **添加关键词**:\n - 进入搜索..."}
向量召回时,通常要设置最低相关分值和最大召回数量,来调控召回内容的质量和数量,以追求更好效果。然而,在RAG1.0版本的实际应用中依然遇到了无法召回和召回质量的问题,在解决问题过程中,逐步建设了向量多路召回、ES检索、重排序等能力,形成了RAG2.0版本。剖析:向量召回的分数与相关内容密度强相关,理论上密度越高,相关分值越高。同理,文档内容越短时相关内容密度也就越高。' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
方案:知识构建向量时,将同一块知识,按照【概述+内容】分别存两份向量,其中概述内容较短,也就意味着密度较高,更容易获得高相关性。在召回时,按照概述和内容两路分别召回再去重的方式,提升召回率。场景:在对用户问题分析中,发现有一部分广告主提出一些【智能计划】相关的问题(对于搜索快车或推荐广告的智能出价的计划的习惯性简称),由于广告投放产品中有一个叫做智能投放的产品,在知识召回的时候大部分召回了智能投放相关的知识,导致无法正确回答此类问题。方案:新增一路ES检索,通过自定义分词器中的同义词、专用词、禁用词的方式,来实现部分内容的召回。比如,同义词设置:智能计划 => 智能出价计划(解决用户习惯的问题)、 购物触点 => 推荐广告 京挑客 => 京东联盟 (解决产品线升级改名的问题)..场景:通过以上手段,有效提升了知识召回率,但是引发了另一个问题,召回的部分知识不相关,会误导模型,影响模型作答效果。方案:引入ReRank模型,在知识召回后,调用算法侧部署的ReRank服务,对知识进行重排序,过滤无关知识。1.2.2 Function Call 能力的构建Function Call的能力主要是为了服务智能指令,比如:提供一个计划数据查询的工具,当用户发送【查询今天ROI > 10 的计划】,模型会返回Function Call标识,包括function name 及 arguments,调用成功后,用对应的组件渲染出来报表。同样包含两部分,分别是:工具能力注册、在线推理引擎。该模块主要工作是将工具的信息管理起来,主要包含三部分信息,分别是:1.模型感知的信息:主要作用是给模型做推理,名称、参数、描述,为了让模型推理更准确,描述的内容我们做了拆分,由基本描述、扩展描述、示例指令几部分组成,下面是一个工具给模型的信息示例:{
"type": "function",
"function": {
"name": "query_xxxx_data"
"description":
"根据ROI、时间....查询广告计划数据" +
"这是一个查询计划数据的工具,可以根据..." +
"示例指令:\n- 查询今天ROI > 10的计划数据\n -查询上周..."
"parameters": {
"type":"object",
"properties":{
"startTime":{
"type":"string",
"description":"开始时间,格式yyyy-mm-dd"
},
"endTime":{
"type":"string",
"description":"结束时间,格式yyyy-mm-dd"
},
"roi":{
"type":"string",
"description":"ROI(投产比)查询条件,如:“ge|3”代表大于等于3。gt-大于,lt-小于,eq-等于,ge-大于等于,le-小于等于"
},
}
}
}
}
2.后端感知的信息:正常情况下,工具的执行其实是调用了后端的接口,那么就需要接口地址、接口入参、接口出参、成功条件等信息。其中接口的入参和模型感知信息中的参数是同一份数据。{
"url": "http://xxx.jd.local/xxx",
"success":{
"condition":{
"from":"code",
"operator":1,
"target":1
},
"data":"data"
},
"params":[
{"key":"code","type":"integer","description":"code码"},
{"key":"msg","type":"string","description":"错误信息"},
{"key":"data","type":"string","description":"返回给前端数据"}
],
"error":{"msgType":1,"msgKey":"msg","msgContent":""}
}
3.前端感知的信息:工具调用成功后,通常有多种处理方式:1.把结果直接返回给用户。2.把结果给到模型,模型继续做推理,同时可以再定义Prompt。3.将结果使用组件渲染给用户。我们为广告主提供的工具大部分都要用组件进行渲染,比如数据报表。当工具需要和组件结合的时候,需要考虑组件的配置化和复用率,这里我们打通了既有的低代码平台,会将组件的信息保存下来。{
"pageData":[
{
"name":"数据表格",
"componentName":"jad_ReportTable",
"jsUrl":"jadfe/xxx/ReportTable.6a3493f4.js", //组件CDN地址
"options":[//组件配置
{
"key":"columns",
"type":"list",
"name":"列设置",
"options":[{"key":"title","name":"列名称","type":"input"},{"key":"key","name":"字段key","type":"input"},{"key":"width","name":"宽度","type":"inputNumber"},{"key":"sort","name":"排序","type":"switch"}],
"value":[{"title":"计划名称","key":"campaignName","width":110},{"title":"产品线","key":"businessTypeStr","width":110},{"title":"时间","key":"date","sort":false},{"title":"展现数","key":"impressions","sort":true}],
}],
}
提供实时在线服务,核心作用是组装工具信息调用大模型进行推理。以下是主要步骤:2.将工具组装成模型需要的格式,组装Prompt,调用模型3.如果模型返回Function Call标识,通过标识中的 function name 找出对应的工具,调用该工具的接口' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
5.前端将返回的内容展示给用户,如需要组件,动态加载组件的CDN地址,完成渲染。经过各种能力的建设后,工程能力的全貌演变为下图。其中与模型交互的核心能力采用了Langchain框架。1.3 京准通智能助手能力展示
基于以上构建的工程化能力,支撑了京准通智能助手的落地,目前已包含:问题解答、数据查询、物料创建、物料编辑等能力。体验地址:https://jzt.jd.com(需要商家账号)在支撑京准通智能助手落地中,除了以上一些核心能力的构建,也有很多细节的优化,比如:指令中日期的准确性优化' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
以上就是京准通智能助手业务从0到1的过程,可见一个大模型应用真正应用到生产环境中,是比较复杂且有非常大的工作量的,我们在思考,如果广告内有其他的业务场景,是否能实现一些能力的快速复用?与此同时,随着业务效果的优化进入深水区,我们需要通过对工作流程更精细化的编排来进行效果的优化。综合以上考虑,我们决定在工作流能力构建的同时,将已有的能力增强并沉淀一个Agent搭建平台,来提升工程复用率和应用搭建效率。以下是整体架构:基建:主要是公司的基建,提供一些基础能力,如:向量库、ES、OSS、Mysql、CDN等等Agent设计器:主要是提供Agent可视化的设计能力,包括智能体、知识库、工具库、记忆库、工作流等核心功能。Agent引擎:主要是根据设计器产生的配置,动态运行工作流程,如:知识的召回、提示词的加工、模型的推理、工具的调用、代码的执行等等。端能力:主要是面向用户的对话式组件,这里我们沉淀了一套AI组件库,可快速组装出兼容PC、H5的对话框。与此同时,针对内部的京ME办公场景,对外如微信中的场景,我们也通过API调用的方式进行了支持。应用场景:有这些能力,就可以轻松的利用平台支撑起各种Agent应用,包括我们的京准通智能助手。同时除了业务之外,还可以做内部提效的Agent应用。下面我们将主要介绍一下Agent设计器和Agent引擎的实现。2.1 Agent设计器
团队空间为了方便协作和做业务隔离,团队空间下,可以进行智能体的搭建、知识库的管理、工具库的管理、工作流的编排等等。知识库中,可以选择不同的向量模型,方便做召回优化的实验。工具库中,可以设置每个工具的模型感知信息、接口、参数、渲染组件等。工作流中,可以随意拖拽编排工作流程,比如:召回节点可以设置召回策略、召回数量、最低分值等;大模型节点可以设置System、User提示词、历史会话轮数等。2.2 Agent引擎
Agent引擎负责和模型交互,是影响效果和性能的核心模块。我们做了重点的设计和重构。在设计阶段,我们考虑的首要问题是:Langchain的取舍。Langchain框架提出了LCEL语法,将Prompt、LLM、Tool等概念进行了抽象并高度封装,能快速上手并实现一些Demo,对新手比较友好。然而,随着业务的复杂度不断增加,以及对模型的了解不断深入,会发现,Langchain的过度封装,把很多简单的事情变的更复杂了,明显影响了业务自由度及开发效率,同时也带来了一定的性能损耗。举个例子:工具调用中,模型接受的参数是一个JSON Schema,我们只要将工具参数存成一个json用的时候就会非常方便。然而,如果使用Langchain,就需要先将json转成一个pydantic类,再使用Tool类进行工具的注册,在调用模型时,Langchain又会转换成json。本来一行代码就可以搞定,使用Langchain后需要几十行代码才能实现,并且降低了性能。最终,我们决定移除Langchain框架,直接用原生python实现,仅保留个别用起来比较方便的工具,如:文档切割。整体上,设计了一套工作流调度器,并将所有节点实现了组件化。收到请求后会初始化一个工作流调度器,调度器根据时机来操作每个节点的执行。截止目前,Agent平台已经为包括智能助手在内的多个Agent应用进行了赋能。其中,在京准通智能助手的效果调优中,基于工作流编排的能力,快速进行了各种策略的迭代,大幅提升了迭代效率。' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
以上是我们京东广告在Agent应用上的一些工程化实践,通过构建RAG、Function Call等核心能力,为京准通智能助手业务提供AI 超能力,并为广大商家赋能。下一步,我们还将推动多Agent架构升级,为更多专业的Agent能力接入铺平道路,促进智能助手能力的持续提升,为商家提供更智能化的产品。总之,道阻且长,行则将至!1秒响应、90%决策准确率!京东商家智能助手的技术探索
CIKM 2024 | 京东电商搜索:深度强化学习的探索与落地
京东大模型革命电商搜推技术:挑战、实践与未来趋势