【转】打造大模型Agent:百度智能云千帆杯竞赛第一期解题思路

随着大型语言模型的进步,使用大模型构建人工智能代理(AI Agents)逐渐成为学术界和业界关注的领域。在这些新兴的研究中,大型语言模型扮演着人工智能代理的核心智能,即它们的“大脑”。这些基于大型语言模型的智能代理(LLM-based Agents)通过集成了先进的语言理解和生成能力的模型,展现出在多种任务上的灵活性和适应性。大型语言模型的引入为智能代理提供了更加深入的语义理解和决策制定能力,从而在处理复杂的语言任务时表现出更强的性能。
Agent典型的落地应用场景就是旅游行程规划助手,一个功能强大的旅游规划助手可以帮你搞定各种具体的规划任务,比如:
  • 你可以帮我规划春节期间去布达佩斯的行程吗?
  • 我需要预订一张明天早上从北京到上海的火车票,没有直达票可以接受换乘。
  • 我想知道故宫的开放时间和门票预约方式。
  • 帮我找一个适合情人节和女朋友约会的餐厅,并且支持布置场地。
等等。
在传统的基于APP的LBS应用模式下,需要通过多步的app滑动,筛选,点击等操作。大模型agent应用更像我们的小秘书,让我们从传统的图形界面(GUI)操作转变为直接的自然语言问询操作(LUI),其带来的不仅仅是效率的提升,更是一种新的交互范式和智能化的革命。
这次,百度智能云千帆杯给我们提供了大模型时代打造自己的Agent的契机,百度智能云千帆杯第一期赛题是《游乐场排队规划助手》,赛题聚焦春节假期游乐园排队效率问题,鼓励开发者利用 AI 能力施展“时间魔法”,打造一款具有实用性的“游乐场排队规划助手”,帮助游客更好地了解乐园的排队情况,设计个性化的游玩路线,在有限的时间内获得最“High”的体验,同时为管理者提供优化运营策略的决策支持。赛题借助百度智能云千帆AppBuilder和ModelBuilder两大智能开发助手,参赛者可以更快捷打造出更多具有创新性、实用性和社会价值的AI原生应用。
下面我们简单描述具体的内容和参赛任务:
赛题内容:
官方提供「环球影城」、「上海迪士尼」、「香港迪士尼」、「广州长隆」四个热门游乐场地图(地图信息见下图list),地图中标注各项目的排队+游玩时间、视觉体验指数、刺激指数,每个项目最多玩一次,不考虑项目之间的交通时间
参赛任务:
  • 从以上4个游乐场中任选一个,通过AppBuilder的Agent Builder创建应用,在应用名称中明确具体的游乐场,如「环球影城排队规划助手」
  • 你将获得官方提供的若干问题示例以及参考答案,你的应用需要尽可能的满足用户类似问题,并返回准确的答案
  • 本次赛题必须使用百度智能云千帆AppBuilder完成开发,可以使用Agent Builder中的任何工具
  • 不允许使用暴力穷举和直接写代码计算的方式实现
赛题提供了多张地图,我们选取其中的「上海迪士尼」地图,教大家手把手完成构建Agent的任务。
地图:
 
调试Query(测试用例):
  • 游玩5个小时,玩哪些项目的组合刺激指数最大?
    • 300分钟之内,刺激指数总和最大为36,组合为小熊历险记,抱抱龙冲天赛车,创极速光轮-雪佛兰呈献,小飞象,喷气背包飞行器
  • 只有120分钟的时间,怎么玩视觉体验最大?
    • 120分钟之内,视觉指数最大为17,组合为小熊历险记,加勒比海盗-沉落宝藏之战
  • 我现在只有4小时20分钟的时间,请问玩哪些项目最刺激?
    • 260分钟之内,刺激指数总和最大为32,组合为抱抱龙冲天赛车,创极速光轮-雪佛兰呈献,小飞象,喷气背包飞行器
 
解体思路
传统的这个问题是一个经典的动态规划的01背包问题,我们可以自己写python代码求解,大模型agent时代应该如何解决呢?其关键就是探索大模型能力的边界,按照题目要求【不直接写代码和公式】,使用自然语言的方式启发大模型写代码。
如图所示,一个典型的Agent包含如下4部分
 
Agent的关键功能已被解构并划分为四个主要部分:规划、记忆、工具使用和行动。每个部分承担着代理智能行为的不同方面。
规划能力(Planning)涵盖了智能代理的目标设定、子目标的分解、以及对行动方案的反思和优化。这一能力是智能代理进行有效决策的基础。
记忆能力(Memory)进一步细分为短期记忆和长期记忆,两者共同构成了智能代理存储和回顾信息的机制。规划与记忆之间的互动,由虚线表示,说明记忆在智能代理的规划和决策过程中发挥了支持作用。
工具使用能力(Tool)指智能代理通过调用外部接口(APIs)来获取信息或执行特定任务的能力。这一能力使得代理能够扩展其操作范围,超越内部处理能力的限制。
行动(Action)则是智能代理对外界输入做出响应的能力,包括生成文本的能力,以及通过工具使用能力实现的具体物理或数字动作。
百度智能云千帆AppBuilder,基于大模型构建并开放了Agent智能体框架,实现自动规划能力(Planning)及代码生成与执行能力Tool),使得原本只能通过专业算法编程才能解决的问题,能够通过自然语言指令配置和对话交互完成,极大降低了AI应用开发门槛,创造了无限的想象空间。
千帆AppBuilder类似其他程序开发框架,给我们提供了程序开发的「脚手架」,让我们可以把精力集中在需要定制化的部分。得益于千帆AppBuilder提供的Agent框架,给我们提供了基础的Planning和Tool的能力,我们只需要解决Memory功能和增强其Planning在具体的任务上的表现即可。而基础的Memory可以通过prompt荷载来实现,我们将赛题的信息描述成基本的形式化语言输入到prompt中,即可让Agent具有简单的记忆功能。
其中Memory部分的prompt实现如下:
$data = [
{name:喷气背包飞行器,time:60,view:3,thrill:9},
{name:创极速光轮-雪佛兰呈现,time:50,view:7,thrill:10},
{name:抱抱龙冲天赛车,time:100,view:3,thrill:8},
{name:小熊历险记,time:50,view:7,thrill:4},
{name:疯狂动物城,time:220,view:9,thrill:6},
{name:加勒比海盗-沉落宝藏之战,time:45,view:10,thrill:4},
{name:翱翔-飞跃地平线,time:130,view:10,thrill:8},
{name:雷鸣山漂流,time:130,view:4,thrill:9},
{name:小飞象,time:40,view:6,thrill:5},
{name:城堡迎宾阁,time:60,view:7,thrill:1},
{name:小矮人矿山车,time:145,view:3,thrill:8}
];
其中“游乐项目名称name”、“用时time”、“体验指数(视觉指数view、刺激指数thrill)”。

 

对于planning部分的优化,我们可以采用Chain of Thoughts(COT)和oneshot的形式。
Chain of Thoughts(COT)顾名思义,思维链,就是将解体思路的思考过程描述出来。
比如在这道赛题中,我们可以辅助Agent思考的过程,将基本的解题思路,使用自然语言来描述给大模型。其核心是如下这句话:
枚举每一种游玩组合,计算体验指数之和,并且保证组合的耗时小于设定总时长$ztime,并记录其最大的体验指数之和和对应组合。
关于这部分,我曾尝试过使用语言描述动态规划的原理启发大模型写代码,但是考虑到本题的数据量和结果的正确率,效果一直比启写枚举思路成功率偏低,因此最终采用了【启发大模型写枚举代码】思路,各位可以多多尝试。
完整的实例如下:
 
你作为一个人工智能算法助手,
根据下面提供的算法逻辑和遍历组合的解题思路来处理景点游玩最优规划这个情景问题。
 
【代码算法逻辑及步骤】:
step1:分析问题,获得可用总时长$ztime(分钟);
step2:加载以下全部11组$data数据:
...
 
其中“游乐项目名称name”、“用时time”、“体验指数(视觉指数view、刺激指数thrill)”。
 
step3:分析问题,设置对应要计算的指数(刺激指数:thrill;视觉指数:view);
step4:判断总耗时是否小于$data中的time最小值,如果小于则直接结束运算,说明不会存在最优解。如果大于等于则进行下一步;
step4:枚举每一种游玩组合,计算体验指数之和,并且保证组合的耗时小于设定总时长$ztime,并记录其最大的体验指数之和和对应组合
step5:输出最大的体验指数之和和对应组合

 

Fewshot和oneshot的概念是给Agent提供多个或者一个参考案例,让他模仿案例进行学习。在我们的任务中,可以参考如下形式
 
【示例】:{
问题: 游玩5个小时,玩哪些项目的组合刺激指数最大?
回答:亲爱的游客您好,根据您的问题经过严密计算后得出:
300分钟之内,刺激指数总和最大为36,总耗时300分钟。
【小熊历险记】【耗时50分钟】【刺激指数:4】
【抱抱龙冲天赛车】【耗时100分钟】【刺激指数:8】
【创极速光轮-雪佛兰呈献】【耗时50分钟】【刺激指数:10】
【小飞象】【耗时40分钟】【刺激指数:5】
【喷气背包飞行器】【耗时60分钟】【刺激指数:9】}

 

最后,我们将上面提到的三部分组织起来,构建成一个完成的prompt,描述给大模型。
 
 
你作为一个人工智能算法助手,
根据下面提供的算法逻辑和遍历组合的解题思路来处理景点游玩最优规划这个情景问题。
 
【代码算法逻辑及步骤】:
step1:分析问题,获得可用总时长$ztime(分钟);
step2:加载以下全部11组$data数据
$data = [{name:喷气背包飞行器,time:60,view:3,thrill:9},
{name:创极速光轮-雪佛兰呈现,time:50,view:7,thrill:10},
{name:抱抱龙冲天赛车,time:100,view:3,thrill:8},
{name:小熊历险记,time:50,view:7,thrill:4},
{name:疯狂动物城,time:220,view:9,thrill:6},
{name:加勒比海盗-沉落宝藏之战,time:45,view:10,thrill:4},
{name:翱翔-飞跃地平线,time:130,view:10,thrill:8},
{name:雷鸣山漂流,time:130,view:4,thrill:9},
{name:小飞象,time:40,view:6,thrill:5},
{name:城堡迎宾阁,time:60,view:7,thrill:1},
{name:小矮人矿山车,time:145,view:3,thrill:8}];
其中“游乐项目名称name”、“用时time”、“体验指数(视觉指数view、刺激指数thrill)”。
 
step3:分析问题,设置对应要计算的指数(刺激指数:thrill;视觉指数:view);
step4:判断总耗时是否小于$data中的time最小值,如果小于则直接结束运算,说明不会存在最优解。如果大于等于则进行下一步;
step4:枚举每一种游玩组合,计算体验指数之和,并且保证组合的耗时小于设定总时长$ztime,并记录其最大的体验指数之和和对应组合
step5:输出最大的体验指数之和和对应组合
 
【示例】:{
问题: 游玩5个小时,玩哪些项目的组合刺激指数最大?
回答:亲爱的游客您好,根据您的问题经过严密计算后得出:
300分钟之内,刺激指数总和最大为36,总耗时300分钟。
【小熊历险记】【耗时50分钟】【刺激指数:4】
【抱抱龙冲天赛车】【耗时100分钟】【刺激指数:8】
【创极速光轮-雪佛兰呈献】【耗时50分钟】【刺激指数:10】
【小飞象】【耗时40分钟】【刺激指数:5】
【喷气背包飞行器】【耗时60分钟】【刺激指数:9】}
请严格按照上述算法和输出要求,运算出结果并输出。让我们一步一步来思考!

 

 
OK,完成了基本的prompt撰写我们再看看如何使用
百度智能云千帆AppBuilder这一工具构建最终应用。
第一步 报名。
 
第二步 进入Appbuilder页面。
 
第三步 创建Agent应用。
 
第四步 编写提示词。
 
点击发布应用。
第五步 执行测试用例执行结果,一起来跟我们的AI agent聊聊天吧~
第一个用例
第二个用例
 
第三个用例
 
可以看出我们三个测试用例都完美通过了测试!
如何查看Agent代码写的如何?我们点击展开第一个用例生成的代码,可以看到如下代码。
要注意的是,每次生成结果有随机性,生成代码有所差别,下面选取了其中一次的展示:
 
 
# 1. 加载数据
data = [
    {"name": "喷气背包飞行器", "time": 60, "view": 3, "thrill": 9},
    {"name": "创极速光轮-雪佛兰呈现", "time": 50, "view": 7, "thrill": 10},
    {"name": "抱抱龙冲天赛车", "time": 100, "view": 3, "thrill": 8},
    {"name": "小熊历险记", "time": 50, "view": 7, "thrill": 4},
    {"name": "疯狂动物城", "time": 220, "view": 9, "thrill": 6},
    {"name": "加勒比海盗-沉落宝藏之战", "time": 45, "view": 10, "thrill": 4},
    {"name": "翱翔-飞跃地平线", "time": 130, "view": 10, "thrill": 8},
    {"name": "雷鸣山漂流", "time": 130, "view": 4, "thrill": 9},
    {"name": "小飞象", "time": 40, "view": 6, "thrill": 5},
    {"name": "城堡迎宾阁", "time": 60, "view": 7, "thrill": 1},
    {"name": "小矮人矿山车", "time": 145, "view": 3, "thrill": 8}
]

# 2. 筛选与排序
# 按刺激指数降序排序
data.sort(key=lambda x: x['thrill'], reverse=True)

# 3. 组合与计算
max_thrill = 0
max_combination = []

def backtrack(combination, total_time, total_thrill, index):
    global max_thrill, max_combination
    
    # 终止条件
    if total_time > 300 or index == len(data):
        if total_thrill > max_thrill:
            max_thrill = total_thrill
            max_combination = combination[:]
        return
    
    # 选择当前项目
    if total_time + data[index]['time'] <= 300:
        combination.append(data[index])
        backtrack(combination, total_time + data[index]['time'], total_thrill + data[index]['thrill'], index + 1)
        combination.pop()
    
    # 不选择当前项目
    backtrack(combination, total_time, total_thrill, index + 1)

backtrack([], 0, 0, 0)

# 4. 选择最优解
# 已在backtrack函数中完成

# 5. 输出结果
print(f"在5个小时内,刺激指数总和最大的游玩项目组合为:")
total_time = 0
for item in max_combination:
    print(f"{item['name']}【耗时{item['time']}分钟】【刺激指数:{item['thrill']}】")
    total_time += item['time']
print(f"总刺激指数:{max_thrill},总耗时:{total_time}分钟")

# 1. 加载数据
data = [
    {"name": "喷气背包飞行器", "time": 60, "view": 3, "thrill": 9},
    {"name": "创极速光轮-雪佛兰呈现", "time": 50, "view": 7, "thrill": 10},
    {"name": "抱抱龙冲天赛车", "time": 100, "view": 3, "thrill": 8},
    {"name": "小熊历险记", "time": 50, "view": 7, "thrill": 4},
    {"name": "疯狂动物城", "time": 220, "view": 9, "thrill": 6},
    {"name": "加勒比海盗-沉落宝藏之战", "time": 45, "view": 10, "thrill": 4},
    {"name": "翱翔-飞跃地平线", "time": 130, "view": 10, "thrill": 8},
    {"name": "雷鸣山漂流", "time": 130, "view": 4, "thrill": 9},
    {"name": "小飞象", "time": 40, "view": 6, "thrill": 5},
    {"name": "城堡迎宾阁", "time": 60, "view": 7, "thrill": 1},
    {"name": "小矮人矿山车", "time": 145, "view": 3, "thrill": 8}
]

# 2. 筛选与排序
# 按刺激指数降序排序
data.sort(key=lambda x: x['thrill'], reverse=True)

# 检查总时间是否小于最小项目时间
min_time = min(item['time'] for item in data)
if 300 < min_time:
    print(f"在5个小时内,无法完成任何一个项目。")
    exit()  # 提前退出程序

# 3. 组合与计算
max_thrill = 0
max_combination = []

def backtrack(combination, total_time, total_thrill, index):
    global max_thrill, max_combination
    
    # 终止条件
    if total_time > 300 or index == len(data):
        if total_thrill > max_thrill:
            max_thrill = total_thrill
            max_combination = combination[:]
        return
    
    # 选择当前项目
    if total_time + data[index]['time'] <= 300:
        combination.append(data[index])
        backtrack(combination, total_time + data[index]['time'], total_thrill + data[index]['thrill'], index + 1)
        combination.pop()
    
    # 不选择当前项目
    backtrack(combination, total_time, total_thrill, index + 1)

backtrack([], 0, 0, 0)

# 4. 选择最优解
# 已在backtrack函数中完成

# 5. 输出结果
print(f"在5个小时内,刺激指数总和最大的游玩项目组合为:")
total_time = 0
for item in max_combination:
    print(f"{item['name']}【耗时{item['time']}分钟】【刺激指数:{item['thrill']}】")
    total_time += item['time']
print(f"总刺激指数:{max_thrill},总耗时:{total_time}分钟")

 

 
可以看到Agent自动构建了python可执行代码编写,框架代码解释器完成了代码执行,给出了运行结果。经测试其他测试用例在当前提示词下也都通过。
提示词限制字数为1400字,大家在1400字内,可以发挥自己的聪明才智,使用COT,Fewshot,自反思,多次执行过程投票结果等手法提升Agent效果。另外,想要赢得比赛要注意考虑Agent的泛化能力,以便应对测试用例之外的case。
通过这个案例,我们可以体会到Agent框架的重要性,是可以真正做到零代码编写,国内外Agent应用百花齐放,百度智能云AppBuilder作为目前国内唯一全面开放的具备代码规划与执行能力的平台,将大模型应用开发所需的框架和组件都做成了可扩展和可拼接的形式,每位开发者都可以利用AppBuilder来基于自然语言构建自己的“程序员”,快速打造属于自己的AI原生应用,探索AI大模型的无限可能。
 
转自:https://cloud.baidu.com/qianfandev/topic/268605
posted @ 2024-02-29 17:29  jeyeshield  阅读(61)  评论(0编辑  收藏  举报