大模型 aZent 框架,让大模型真正成为你的同事(1)

背景

通常大模型出现,如何有效地将大模型引入业务提供几种方式切入企业级开发

  • 知识库
  • agent
  • prompt engineering
  • 微调

为什么我要选择 Agent 这方式呢?

agent 这种方式是大模型进入企业,落地一个比较可行方案,每一个 Ai 大模型都有自身特点和擅长的领域。没有一个可以覆盖所有任务模型。大模型缺乏专业性,并且难于控制,缺乏确定性。对于没有经验人,很难通过 prompt 来控制大模型得到想要效果。针对这个问题有了 azent 的想法,agent 作为大模型的代理,通过现有信息化系统切入实际业务,真正发挥减员增效。

目标

整合大模型资源,让大模型能和业务紧密联系,发挥其应有作用。通过 azent 并有效控制大模型的输出与我们期望输出对齐。

azent 框架

  • model wrapper 和 tool wrapper 分别对模型和应用进行包裹,通过 Api 形式调用和通信
  • Api 层提供接口,可以 Api 接口来控制项目和观察项目

azent 框架的特点

  • azent 是通讯框架,更好将资源有效整合来完成任务
  • 可视化也是 azent 一个显著的特点,动态显示框架运行的状态,更加直观观察整个系统运行,跟踪系统运行
  • 人的参与: agent 也可以代理人,让人直接参与到整个流程,以达到对流程的控制,让 agent 框架更符合
  • 提示词引擎: prompt engine 可以帮助普通人写出高质量的 prompt,这块强化学习和遗传算法少不了
  • 多工具的封装,也就是工具的扩展
  • 分布式高并发,高可用,提升稳定性

相关技术

相关技术,整个框架和外部通讯依赖于 Api 调用,系统间可以 rpc 来实现跨语言调用,这个框架有点类似自动驾驶领域 Ros,对成熟模型进行封装,也支持可扩展,因为各个单位业务五花八门,各不相同,所以想设计之初考虑到灵活性,可扩展性。还有就是需要支持高并发和稳定性,就此先用 python 以后随着自己技术提升,迁移到 rust 。

设计到相关技术比较多

  • 这是通讯架构,会借鉴 ROS
  • 事件驱动框架,还是采用微服务,还在调研中,希望大佬给与指点
  • agent 是框架核心,agent 设计是重点也是难点,
  • 希望这也是一次强化学习应用,和落地的场景

agent

在框架中 agent 可以看作最小的可执行(或计算)的最小单元,不仅可以代理大模型,也有人类代理,agent 是整个框架的最小计算单元,通常 agent 还有记忆模块

  • assistantAegent 代理大模型,例如 chatGPT
  • decisionAgent 来代理人类

task

task 是对业务的抽象,对应实际实际一个一个的任务

  • task 中是由 agents 组成的
  • task 之间可以通讯,task 层级通讯为主,那么 task 看做通讯最小单元

proj

proj(office) 可以看作一个作用域概念,创建一个 project ,project 是对业务抽象,也是 task 的容器,这些 task 共同协作完成一个项目,例如设计产品,搭建网站。完成 excel 数据的统计操作等。

iprompt

好的 prompt 让我们可以更好控制大模型,prompt 生成可以进化,也就是不断学习中进步,可以 self-learning 或者 meta learning 来实现让 prompt 不断进步,设想将生成 prompt 和反馈一并输入到 update 来进行提升 prompt 生成,以及会沉淀 prompt pool 用于提供 prompt 的采样

TWrapper

  • 对工具的包裹,也就为 agent 提供可使用,例如 office 的包裹
  • 可扩展,框架中仅仅提供主流的工具,例如常用 office
  • 将 office 等应用基本操作抽象为 Api

Agent

python 复制代码
from abc import ABC,abstractmethod
class Agent(ABC):
    @abstractmethod
    def run(self,prompt):
        pass
  • 这是 Agent 抽象类
  • Agent 现在暂时代理一个大模型,可能代理人,准备按行为划分
python 复制代码
import json
from engine.agent import Agent

class AssistantAgent(Agent):
    
    def __init__(self,name,client,prompt) -> None:
        super().__init__()
        self.name = name
        self.client = client
        self.prompt = prompt
        self.type = "assistant"


    def run(self, input):
        return self.client(self.prompt.format(input))
    
    def __str__(self) -> str:
        agent_dict = {
            "name":self.name,
            "prompt":self.prompt,
            "type":self.type
        }
        return json.dumps(agent_dict); 

扩展一些基于基础类常用的 Agent

DecisionAgent

python 复制代码
class DecisionAgent(Agent):
    def __init__(self,name,tasks) -> None:
        super().__init__()
        self.name = name
        self.tasks = tasks

    def run(self,input):
        return {
            "output":input,
            "tasks": self.tasks
        }
        

关于 decisionAgent 设计,decisionAgent 是决定是否启动下一个 Task,所以 descisionAgent 需要 run 方法实际启动一个 task 那么 decisionAgent 存放是一个 taskid 也就是接下来要执行的 task

Task 代码

python 复制代码
from collections.abc import Iterable
import uuid
import json

class Task:
    def __init__(self,name) -> None:
        self.name = name
        self.id = uuid.uuid1()
        self.agents = []
        self.deps = []

    def addAgent(self,agent):
        self.agents.append(agent)

    def run(self,input):
        pass
    
    def __str__(self) -> str:
        task_dict = {
            "name":self.name,
            "agents":self.agents
        }
        return json.dumps(task_dict)
    

现在关于 Task 和 Agent 设计略显简陋,通过不断迭代更新 Task 和 Agent 代码以实现目标

测试

用 flask 搭建一个简单任务,来看一看效果,这里我们用 task 封装了一个 agent 然后用一个 input 来测试

  • fasks 作为服务端提供 restful 服务
  • /tasks 获取 tasks 列表
  • /task/<task_name>: 启动某一个指定的任务
python 复制代码
class Task(Resource):
    def get(self,task_name):
  
        input = """
        When I was 6 my sister was half my age. Now
        I'm 70 how old is my sister?
        """
        return {'task_name':task_name,'reply':tasks[task_name].run(input)}

api.add_resource(Task, '/task/<string:task_name>')
json 复制代码
{
    "task_name": "two",
    "reply": "When you were 6, your sister was half your age, so she was 3 years old. This means your sister is 3 years younger than you. So, if you are now 70, your sister would be 70 - 3 = 67 years old."
}

可视化既然重点,一定要下点功夫,简单右侧是 task 列表,每一个任务下显示其所属的 agent 每一个 agent 有类型和 prompt,因为这些 agent 都是大模型的 agent 所以将 prompt 显示出来,prompt 也是我们关心的,关于 prompt 应该如何更新,这部分内容还要随后仔细想一想。

Demo

任务描述: 有一段文本,关于样本检测的工作流程,需要从中提前流程以结构化数据表示,最后输出格式为 html 格式 阅读指导文件,生成路程的 html 视图的任务。

项目是这样首先分解为两个动作,也就是 2 次请求大模型,第一次是让 LLM 阅读输入文本,以列表形式将其中流程总结出来对应(agent one),然后将输出结果作为下一个动作的输入,也就是将列表转换 html ul li 标签表示输出的形式,其实之前想是一步到位,不过发现效果不好。

所以才将 1 步细化为 2 步,以后希望关于任务的划分和 agent 调度也希望交给 agent 去做

然后 preview agent 节点,返回结果给 review 如果不满意可以打回,或者向下输出想要格式,有点类似 check 流程。

python 复制代码
taskOne = SequenceTask('taskone')
taskTwo = SequenceTask('tasktwo')

agent_one_prompt = "#role\n作为熟悉项目流程人员\n#workflow\n仔细阅读input的内容,分析内容提到项目工作流程,以层级列表来将工作流程描述清楚\n#input\n{} #output 输出工作流的列表"
agent_two_prompt = "#role\n作为熟悉 css 和 html 的前端开发人员\n#workflow\ninput 中列表转换 html,ul 和 li 标示输出来,如果可能添加 css 来修饰 html 呈现出精美的列表\n#input\n{}#outputFormat\n可以显示在浏览器端 html 文件"

taskOne.addAgent(ChatGPTAgent('agentone',agent_one_prompt))
taskOne.addAgent(ChatGPTAgent('agenttwo',agent_two_prompt))

taskOne.addAgent(PreviewAgent('previewagent',['taskone']))

taskTwo.addAgent(ChatGPTAgent('agentthree',agent_one_prompt))

tasks = {'taskone':taskOne,'tasktwo':taskTwo}
相关推荐
中杯可乐多加冰25 天前
【AI落地应用实战】Amazon Bedrock Converse API + Amazon Titan构建一个RAG应用(Retrieval-Augmente
人工智能·掘金·金石计划
边中之城1 个月前
如何从0到1开发自己的npm包
掘金·金石计划
中杯可乐多加冰1 个月前
Text to image论文精读PDF-GAN:文本生成图像新度量指标SSD Semantic Similarity Distance
人工智能·掘金·金石计划
Sword991 个月前
Rust 所有权理解与运用
前端·rust·掘金·金石计划
冯志浩1 个月前
Harmony Next - 图形绘制
harmonyos·掘金·金石计划
中杯可乐多加冰2 个月前
【AI落地应用实战】HivisionIDPhotos AI证件照制作实践指南
人工智能·掘金·金石计划
冯志浩2 个月前
Harmony Next - 多线程技术 TaskPool
harmonyos·掘金·金石计划
宇宙之一粟2 个月前
设计快速并发哈希表
后端·rust·掘金·金石计划
宇宙之一粟2 个月前
【译】Go 迭代器的乐趣
后端·go·掘金·金石计划
雨绸缪2 个月前
ABAP 的 “小技巧 ”和 “陷阱 ”以及新语法
后端·代码规范·掘金·金石计划