AI 大模型应用开发与实践(一)-Agent 智能体

Agent营销AI项目

从整个系统的角度来看,就是通过 Agent 智能体升级我们原来的营销平台,即原有广告平台 + AI = 营销平台 2.0。

营销 Agent 开发思路

Agent 平台应用的范式说来并不复杂,交互上,是聊天机器人为基础的交互界面,架构上,支持低成本开发和分享新的 AI 智能体应用,也可以快速复用原有的成熟应用逻辑。市场上有一些低代码的 Agent 开发平台,比如斑头雁扣子等等。我们基于这些平台就可以开发自己的 Agent 智能体应用,也可以直接把这些应用分享给用户。

  • Agent
  • 工作流
  • 知识库

为什么需要Agent ?

你可能会奇怪 Agent 是怎么具备业务逻辑的,Agent 和大模型是什么关系呢?我的答案是,助理可以看做 Agent 应用的界面,比如例子里的客服助理。但你其实就是在和大模型在聊天,只不过在你和大模型之间还有一个代理程序,它就是 Agent。我们可以把 Agent 看做大模型的代理人

file

在 Agent 平台里还有一个重要概念就是工作流。助理负责识别具体的业务逻辑并调取工作流,一个工作流其实就是一个原有业务逻辑。比如客服里的退货业务,实际上工作流是被动配合助理的。几个概念综合起来,内部的实现就很容易理解了,由外到内一共四层关系:助理 -> 工作流 -> 插件 -> 知识库。

file

可以这样理解,工作流就是传统应用里的独立功能的函数或程序,那插件呢,就是传统程序里的系统库函数,知识库就是传统数据库。

file

总结一下,助理通过提示词配置具体的沟通能力以及业务能力,具体业务能力的承接通过工作流实现,其他的模块都是配合工作流的,有了这些部件,我们就可以基于 Agent 平台开发一个实际的营销 Agent 应用了。

营销 Agent 开发过程

Agent(助理)的设计分为三个部分。其一是配置助理的系统提示词,其二是配置 Agent(助理)的工作流能力,其三就是设计具体的工作流逻辑。

扣子创建智能体(初体验)

file

案例总结

如果我们回顾这几个简单的例子,会发现 Agent 平台提供了什么价值呢?

对传统应用来说,Agent 平台提供了统一的界面,也就是助理聊天界面。这种交互模式几乎可以替代传统的应用交互界面。因为传统界面交互需要大量的选项、按钮、输入框等,新的交互呢,用户通过自然语言就可以说清需求;而且这个交互界面,随时可以通过我们配置的提示词调整具体的交互逻辑,也就是 Agent(助理)设计的第一,二步。本质是因为大模型具有很强的可塑性,这让交互界面的开发成本直接降为零。

而工作流和插件的低代码开发模式,也就是 Agent(助理)设计的第三步,复用现有业务和复用现有云计算能力,这些都非常方便,至少有 10-20 倍的业务开发速度提升。而且你开发的工作流可以直接分享,进一步提高了别人的开发效率。

file

营销 Agent 优化有哪些额外考虑?

我们初始的目标,是要实现营销 AI 2.0 版本,并且将自定义能力开放给我们的客户。如果是单个新增应用,基于 Coze 这类 Agent 开发平台来开发,由于 Coze 平台本身提供了整套的基础设施,开发效率有很大的提升。但是当我们想基于它构建一整套系统时,遇到了不少困难。

第一个挑战是数据和能力复用问题。
其一,数据私有化这是企业的常见需求,利用现有 Agent 平台开发营销 AI 2.0 平台,不可避免地要将私有数据和现有 Agent 平台打通,企业客户不一定能接受这个方案。

其二,在能力复用方面,我们现有的营销平台功能非常多,如果用现有 Agent 平台来开发,就需要适配 Agent 平台重新开发一遍,开发成本很高。现有 Agent 平台对创建新应用更友好,这也是我这节课没有细讲标签功能的原因。

而且,我们发现,想要搭建一个完整的营销平台 2.0 版本,会有很大的成本问题。用现有的 Agent 平台本身需要成本,使用它代理的大模型也需要 token 成本。为了解决这些问题,我们团队只好从底层实现一套类似 Coze 平台的架构。

file

从我们之前开发这些单体的智能体应用经验看,如果搭建一个营销 Agent 平台,可以用极低的成本将原有运营逻辑变为自动化的过程,提升效率,同时意味着成本也会降低。

这是我们接触 Coze 这类的 Agent 开发平台的原因,如果你使用过 Coze 平台,同时具备一定的编程能力,你可能会惊呼,这样开发一个 Agent 应用也太简单了吧!几乎人人都可以开发自己的 Agent 智能体了。

Agent 智能体在平台的核心其实就两个,一是用于限定机器人交互的系统提示词,二是用于实现业务逻辑的工作流。工作流开发在系统插件、LLM 能力以及知识库、Memory 系统记忆等大量系统能力的加持下,能够提升不小的开发效率。

但是当你深入到 Agent 开发中,又会发现同样的问题。这个平台作为个人开发完全足够,但是对于我们团队这类的系统整体升级需求而言,还要做适配,开发成本不小。最后我们意识到,我们要做的是整体的营销 AI 2.0,又因为我们有自研能力,所以开始自研 Agent 平台底层,这部分内容,我会在下节课详细展开。

file

自建Agent智能体

我们回想一下上节课的 Agent 助理,可以配置的部分是不是只有助理提示词和工作流节点的输入输出参数呢?我想告诉你的是,这些配置就是用于让大模型做意图识别和参数识别的。

下面是我做的 Agent 底层的架构流程图。

file

技术实现最后,我们说技术实现。意图识别和参数识别的具体实现方法有两种,可以通过微调大模型实现,也可以通过提示词实现,思想都是想通的。

下面是一个 Demo 级别的核心架构代码演示,这个代码就是上述 Agent 底层架构的核心逻辑实现例子。这个 Demo 以一个用餐业务为例,分为提示词和核心代码两个部分。理解了这个例子,剩下的一万个 Agent 也就理解了。首先是核心提示词。

首先是核心提示词。

现在有3个角色,sys 代表应用程序系统,user 代表用户,你的角色是一名餐厅服务员,你的目的是服务用户,请你根据上下文决定是否调用 sys应用程序系统。
调用系统则输出 to_sys: 应用程序参数
回复用户则输出 to_user: 回复的消息

规则:
1,要一句一句的和我沟通,每次只能选择和to_sys或to_user其中之一,我会代为转达和处理消息,并且用sys 或 user开头的消息回复你
2,调用程序的具体参数要在上下文中确定,比如我们应用程序有个参数a,上下文里用户或系统没有提供,你就不能擅自决定a的具体数值,调用程序用json格式
3,当我用sys:开头给你回复的时候,表示本次应用程序返回,你要结合这个返回信息继续和用户沟通,你直接用to_user和用户沟通,要注意影藏程序系统这个信息,让用户感知不到

反例:
1,类似下面的回复是错误的,错误原因是在消息里同时出现to_sys 和 to_user
"""
to_sys: {
‘app’ : '点餐应用',
'usernum' : 1,
'caiming' : '包子',
'cainum' : 3
}

to_user: 好的,三个包子已经为您下单了,稍等片刻就会上菜。是否还需要点其他菜品或者饮料呢?
"""

[应用程序列表如下]
1,点餐应用,当用户点餐时调用,
请你和用户沟通确定这些参数:用户人数,菜名(必填),数量(必填)
输出json格式例子:{
    ‘app’ : '点餐应用', #应用名字(必填)
    'usernum' : 1,  #用户人数
    'caiming' : '包子', #菜名
    'cainum' : 5 #数量
}
2,菜单应用,在点餐之前调用,
参数:无
输出json格式例子:{
    ‘app’ : '菜单应用', #应用名字(必填)
}
3,结账应用,当用户用完餐需要结账时调用,
参数:无
输出json格式例子:{
    ‘app’ : '结账应用', #应用名字(必填)
}

接下来用to_user给用户开始第一条消息
你的餐厅名字是: 成都小吃

我们可分析一下这个核心提示词,有三个层次。其一是定义角色,提示词里表明了代理、系统、用户三者的关系,让大模型根据上下文来决定具体的回复,这也就解决了意图识别的问题。其二是对 sys 类参数的限定提示词,让大模型按插件和工作流的参数格式来回答。其三是将应用的工作流和具体参数注入提示词,让大模型理解应用。

这段提示词的作用就是告诉大模型我们的具体场景以及助理的具体能力,将上下文交给它处理。需要注意的是,各个插件和工作流的参数都是大模型来组织的,我们给于引导即可。

和提示词对应的 Demo 程序代码如下。

import json
def deal_app(app, params):
    print(">>> " + app)

    if app == "菜单应用":
        return '菜单 1包子 2饺子 3 可乐或雪碧'

    if app == "结账应用":
        return '一共消费100元'

    if app == "点餐应用":
        if 'caiming' not in params or  params['caiming'] == None:
            return "请先选择菜品和数量"
        if params['caiming'] == '面包':
            return '面包卖完了'

        return "已下单"

    return "没有这个应用"

def deal_answer(answer):

    if answer.find("to_user:") >= 0 and answer.find("to_sys:") >= 0:
        print(answer)
        return xf_ai('user', "请不要同时回复to_user 和 to_sys, 两者只能选一个,也不要[等待系统回复]这样的说明", "sys:")

    if answer.find("to_sys:") >= 0 and answer.find("\nsys:") >= 0:
        print(answer)
        return xf_ai('user', "请不要同时回复to_sys 和 sys, 只回复to_sys的数据", "sys:")

    if answer.find("to_user:") == 0:
        return answer.replace("to_user:", "")

    if answer.find("to_sys:") == 0:
        # print(answer)
        j = answer.replace("to_sys:", "")
        j = j.strip()
        end = j.find("}")
        j = j[0:end+1]
        print(j)
        jj = json.loads(j)
        app = jj['app']
        s = deal_app(app, jj)
        o = xf_ai('user', s, "sys:请告诉用户:")
        return o
    # print(answer)
    return ""
def get_input_from_command_line():
    """
    Get input string from command line using input function.
    """
    input_string = input("用户: ")
    return input_string

def out_user_message(s):
    if s == False:
        return

    print('服务员:'  + s)

if __name__ == '__main__':

    o = xf_ai('user', prompt)
    out_user_message(o)

    while True:
        s = get_input_from_command_line()
        if s  == 'quit':
            exit()
        o = xf_ai('user', s, "user:")
        out_user_message(o)

file

千万不要小看这个提示词和底层 Demo,实际上麻雀虽小,五脏俱全。我们整个系统都是在这个基础代码上构建的,你可以把这部分的实现单独作为一个实验来做,一定会对大模型开发有更深入的体会。

如果要更好地理解整套 Agent 系统,我想可以从我们最终的助理创建界面继续给你分析。


相关文章:
极客时间|如何在Agent平台上构建一个AI营销智能体

为者常成,行者常至