2024年7月

热点随笔:

·
程序员失业日记1:工作五年,交接半天
(
小码A梦
)
·
学习.NET 8 MiniApis入门
(
tokengo
)
·
C#/.NET/.NET Core优秀项目和框架2024年6月简报
(
追逐时光者
)
·
需求变更,代码改的像辣鸡 - 论代码质量
(
2J
)
·
如何找到并快速上手一个开源项目
(
crossoverJie
)
·
炎炎夏日,清凉上线:博客园T恤丝光棉款上架预售
(
博客园团队
)
·
C#的多线程UI窗体控件显示方案 - 开源研究系列文章
(
lzhdim
)
·
不单独部署注册中心,又要具备注册中心的功能,咋不让我上天?
(
青石路
)
·
博客园商业化之路:全园求偶遇,懂园子懂商业的创业合伙人
(
博客园团队
)
·
基于Bootstrap Blazor开源的.NET通用后台权限管理系统
(
追逐时光者
)
·
WPF在.NET9中的重大更新:Windows 11 主题
(
mingupupup
)
·
开发一个题库系统App和小程序的心得
(
Vrapile
)

热点新闻:

·
全球首个神经连接机械腿,截肢者恢复自然行走,还带空间感
·
社保连涨192%,打工人开始逃离深圳
·
Meta 推出文生 3D 模型AssetGen,一秒生成 3D 素材
·
全员降薪 60%、300亿市值几乎跌成零!这个曾剑指英伟达的国产芯片公司被曝造假,业内评其“老鼠屎”
·
“微信收款码拍下来没法付款”引热议,官方回应“不支持截图 / 拍摄使用”
·
比亚迪引发了一场战争
·
多益成都员工被关小黑屋强制辞退,仲裁拿了38万,创始人徐波大怒:关闭成都公司、成都不适合经商
·
周鸿祎:一个漏洞最贵可卖到三亿,360挖来的漏洞都贡献给了国家
·
别逗了,你真以为所有商家都赚不到钱了?
·
28000人不给钱就不上班!三星遭成立55年来第一次总罢工
·
神经元新计算模型或产生更强大AI
·
58亿美元售卖篮网,蔡崇信狠赚了一笔

AI Agent技术的最新进展与改变世界的典型项目巡礼

1. AI Agent 技术发展以及典型项目

1.0 前 AI Agent 时代

在学术探索的浩瀚星空中,机器人技术领域的璀璨明珠莫过于Agent技术的深入研究,这一领域历来是创新与突破的温床。回溯至大模型浪潮兴起之前,Agent技术的辉煌篇章便已悄然铺展,诸如Alphago这样的里程碑式案例,以其卓越的环境感知、精准决策与高效行动能力,生动诠释了Agent技术的闭环魅力。同时,DeepMind的Agent57在强化学习领域的游戏挑战中崭露头角,而随后问世的Gato则展现了更为广泛的适用性,乃至OpenAI在“躲猫猫”游戏中展现的多智能体协作,无不预示着Agent技术的无限潜力。

展望未来,我们坚信Agent技术将成为驱动社会全面自动化的核心引擎。与以往侧重于结构化环境下通过既定算法实现的自动化不同,大模型的兴起为Agent技术赋予了前所未有的通用性与灵活性。这一转变,意味着Agent将能够跨越传统界限,深入人类脑力劳动的复杂长尾领域,从体力到脑力,全方位推进自动化的深度与广度。

大模型与Agent技术的融合,正引领我们步入一个全面自动化的新纪元。大模型作为知识海洋中的自主学习者,为Agent提供了前所未有的智慧源泉,激发了其快速发展的新动能。当前,尽管我们仍处于这一变革的初期,Agent技术更多以实验性、探索性的面貌呈现,但展望未来,其发展前景之广阔,变化速度之迅猛,或将超乎所有人的预料。随着技术的日新月异,我们或许会发现,所谓的“天花板”不过是通往更高境界的阶梯,而Agent技术的极限,正等待着我们共同去探索与定义。

1.1 AI等级划分

基于Agent(智能体)能力的AI等级划分,可以借鉴类似自动驾驶级别的划分方式,将AI智能体的能力从低到高进行分级。以下是一个简化的AI Agent能力划分描述:

AI Agent能力划分:

  • L0 - 没有人工智能
    在这一级别,Agent并不具备人工智能特性,只能执行预定或固定的任务,没有感知、决策或学习的能力。

  • L1 - 规则符号智能
    Agent开始具备基于规则的决策能力,能够根据预设的规则和符号进行简单的判断和执行。这种智能体通常只能处理特定情境下的任务,且缺乏灵活性和适应性。

  • L2 - 推理决策智能
    Agent能够利用逻辑推理能力来解决问题,不再仅仅依赖于预设的规则。它能够根据当前的环境信息和目标,进行一定程度的推理和决策,以选择最合适的行动方案。

  • L3 - 记忆反思智能
    在L3级别,Agent不仅具备推理决策能力,还开始拥有记忆和反思的能力。它能够记住过去的经验和教训,并在未来的决策中加以利用。这种智能体能够自我优化和改进,以适应不断变化的环境和任务。

  • L4 - 自主学习智能
    自主学习是L4级别Agent的主要特征。它能够自主地从数据中学习新知识和技能,无需人类的明确指导。这种智能体能够处理更复杂的问题,并在面对新情境时展现出更强的适应性和创造力。

  • L5 - 个性群体智能
    在最高级别,Agent不仅具备高度自主的学习和决策能力,还展现出个性化的特征。它能够根据自身的特点和偏好来执行任务,并与其他Agent进行协作和沟通。此外,L5级别的Agent还能够理解和适应人类社会的复杂性和多样性,与人类实现更加紧密和自然的交互。

  • AI 等级划分

  • AI apps building blocks

1.2 Prompt 工程

  • 通过描述角色技能、任务关键词、任务目标及任务背景,告知大模型需要输出的格式,并调用大模型进行输出

为了将 LLM 的能力发挥到极致,发展出了多种 prompt 工程

  • 角色扮演
  • 零样本分析
  • 少样本分析

在大模型初露锋芒之际,业界掀起了一股“Prompt工程”的热潮,将这一先进技术视为一种创新的编程范式加以探索。从业者们巧妙地将大模型转化为高度可定制的“智能工具”,通过精心构建的角色设定、技能描述、任务关键词的精准提炼、目标导向的明确阐述,以及详尽的任务背景铺设,构建起与模型沟通的桥梁。这一系列精心设计的指令,不仅界定了大模型需完成的任务范畴,还细化了输出结果的格式要求,随后通过直接调用大模型,实现知识的生成与输出的无缝衔接。

这一过程,被业界形象地称为“工具模式”,它深刻体现了大模型作为高级认知工具的价值所在。在此模式下,大模型不再仅仅是静态的数据处理器,而是转变为能够根据用户意图灵活应变、高效执行复杂任务的智能助手。这种将大模型工具化的探索,不仅极大地拓宽了技术的应用边界,也为人工智能领域的研究与实践开辟了新的思路与方向。

案例:15000 字符的 prompt 工程,扮演人类导师

https://github.com/JushBJJ/Mr.-Ranedeer-AI-Tutor

刚兴趣的同学可以用自己尝试一下:
https://chat.openai.com/share/53b38605-68e5-4922-81fe-e4588fb28d8a

prompt 强化了 LLM 的能力,但以下的问题依然无法解决:

  • 不能及时更新知识
  • 上下文有限等等为了解决以上的问题,人们又发展出了很多的方法

1.2.1 Prompt 外挂 - RAG(Retrieval Augmented Generation)

  • 引入向量数据库
  • 数据索引进入向量数据库
  • 召回数据
  • 在提交给 LLM 做提示词工程

1.2.2 分而治之 - 古老的思想依然有效

  • 解决 context 不够的问题
  • 拆分成小段,分别摘要

1.2.3 step-by-step

  1. 思维链(Chain of Thought,CoT):要求模型展示其思考过程,而非仅给出答案
  2. 思维树(Tree of Thought,ToT):它会根据当前的问题分解出多个可能,然后每一个树节点就是父节点的一个子问题,逐层扩散,遍布整个解空间,一些节点就直接会发现不合适而终止掉,达到了有效剪枝的作用
  3. 思维图(Graph of Tree,GoT):基于思维树,既可以分解,也可以合并
    ......
  • 思维链(Chain of Thought, CoT)的深化

思维链的引入,标志着人工智能模型解答问题方式的重大转变。它强调模型需展现其内在的逻辑推理过程,而非仅仅呈现最终答案。这一过程可通过双轨并行实现:一是详尽阐述法,即模型被要求逐步、细致地展示其思考轨迹,确保每一步推理的透明度与逻辑性;二是范例引导法,通过提供包含完整思考路径的示例问题与答案,引导模型在面临新问题时模仿此过程,循序渐进地推导答案。随着实践的深入,我们进一步探索了CoT的潜力,发现当单一思维链遭遇障碍时,通过发散性思考,即CoT-SC(Chain of Thought with Strategic Convergence),模型能尝试多种解题路径,并通过投票机制筛选出最优解,从而增强了解的鲁棒性与多样性。

  • 思维树(Tree of Thought, ToT)的萌芽

面对CoT-SC在某些复杂问题(如24点游戏)上的局限性,我们转而探索思维树的构建。ToT策略将问题视为一个根系庞大的树木,其主干代表核心问题,而每一分支则是对该问题的不同分解路径。每个节点代表一个子问题,随着树的层层展开,解空间被细致划分,同时,不合适的分支被有效剪除,以优化搜索效率。然而,ToT在处理需要高度整合子问题结果的任务(如排序算法中的合并步骤)时仍显不足。

  • 思维图(Graph of Tree, GoT)的革新

为解决ToT的整合难题,思维图应运而生。GoT不仅继承了ToT的分解能力,更增添了灵活的合并机制,使得模型能够在复杂问题中自由穿梭于分解与整合之间,构建出既全面又精确的解决方案图。这一创新,标志着AI在复杂问题求解能力上的又一飞跃。

  • 累计推理:迈向新高度的探索

清华姚期智团队在思维推理领域取得了突破性进展,提出了累计推理方法。该方法在解决24点问题上已展现出高达98%的成功率,树立了新的技术标杆。其核心理念与主流Agent的实现方式相契合,强调通用性与实用性。累计推理首先孕育一个初步假设,随后通过不断验证与迭代,逐步构建并完善推理图。每个新节点都建立在稳固的已有基础上,通过发散、合并或修正,直至达成最终目标状态。这一过程不仅增强了推理的完备性,还赋予了模型前所未有的灵活性,为人工智能在更广泛领域的应用开辟了新的可能性。

1.2.4 基于反馈的 ReACT-Synergizing Reasoning and Acting

上述的讨论主要是任务分解和组合,他们尽管强大,却不能与外界进行互动,这就不得不讲到反馈机制了。

ReACT机制的核心在于将推理和行动紧密结合,使语言模型能够交替地产生推理路径(Thought)和文本动作(Action),以解决不同的语言推理和决策任务。具体来说,ReACT通过以下几个步骤实现这一目标:

  • 推理路径生成:模型首先基于当前的环境或上下文生成推理路径(Thought),这些推理路径包含了对问题或任务的逐步分析和理解。
  • 文本动作生成:在推理路径的指导下,模型生成文本动作(Action),这些动作可以是查询外部数据源、执行特定操作或生成最终答案等。
  • 环境交互与反馈:文本动作被发送到外部环境或数据源,以获取新的观测值(Observation)。这些观测值用于更新模型的内部状态,并作为后续推理和行动的基础。
  • 循环迭代:上述过程不断循环迭代,直到达到任务目标或满足某个终止条件

1.2.5 Reflexion

  • 背景与动机

传统的强化学习方法在训练大型语言模型时面临诸多挑战,如需要大量的训练样本和昂贵的模型微调成本。此外,传统的标量或向量奖励信号往往难以准确反映智能体在执行任务过程中的具体表现。Reflexion方法通过引入语言反馈机制,旨在解决这些问题,使语言智能体能够快速有效地从错误经验中学习。

  • 核心原理

Reflexion方法的核心在于将传统强化学习中的奖励信号转化为语言反馈信号(Verbal Reinforcement),并将其作为附加的上下文信息嵌入到大型语言模型中。具体来说,Reflexion框架包含以下几个关键组件:

  • Actor:由大型语言模型(LLM)担任,主要负责基于当前环境生成下一步的动作。

  • Evaluator:用于评估Actor生成结果的质量,类似于强化学习中的奖励函数。Evaluator将生成的轨迹作为输入,计算在给定任务上下文中的奖励分数。

  • Self-Reflexion:自我反思模块,也由LLM担任。该模块负责分析Actor的执行结果和Evaluator的奖励信号,生成具体且详细的语言反馈信号。这些反馈信号会储存在Memory中,以便在未来的决策中提供参考。

  • Memory:提供短期记忆和长期记忆功能。短期记忆存储当前实验中的上下文信息,而长期记忆则存储Self-Reflexion模块生成的反思结果。

  • 执行过程

Reflexion的执行过程是一个迭代过程,包括Actor生成动作、Evaluator评估动作、Self-Reflexion生成反思并存储结果等步骤。通过不断重复这个过程,智能体能够逐渐从错误经验中学习,并在未来的任务中做出更好的决策。

2. AI Agent

  • 定义

在 LLM 语境下,Agent 可以理解为某种能自主理解、规划决策、执行复杂任务的智能体。Agent 并非 ChatGPT 升级版,它不仅告诉你 “如何做”,更会帮你去做。如果 CoPilot 是副驾驶,那么 Agent 就是主驾驶。

2.1 AI Agent 系统组成

  • Planning(规划):


    • 子目标和分解:AI Agents 能够将大型任务分解为较小的、可管理的子目标,以便高效的处理复杂任务
    • 反思和细化:Agents 可以对过去的行为进行自我批评和反省,从错误中吸取经验教训,并为接下来的行动进行分析、总结和提炼,这种反思和细化可以帮助 Agents 提高自身的智能和适应性,从而提高最终结果的质量
  • Memory(记忆):


    • 短期记忆:所有上下文学习都是依赖模型的短期记忆能力进行的
    • 长期记忆:这种设计使得 AI Agents 能够长期保存和调用无限信息的能力,一般通过外部载体存储和快速检索来实现
  • Tool use(工具使用):


    • AI Agents 可以学习如何调用外部 API,以获取模型权重中缺少的额外信息,这些信息通常在预训练后很难更改,包括当前信息、代码执行能力、对专有信息源的访问等

2.2 Agent 项目(单/多智能体)

多智能体系统相较于单智能体系统(如AutoGPT)在多个方面展现出显著的优势,这些优势使得多智能体在处理复杂任务时更为高效、灵活和稳定。

  1. 信息处理与记忆容量优势


    • 多智能体优势:每个Agent在多智能体系统中仅需关注与自身角色或任务直接相关的信息,这种模块化的信息处理方式极大地减轻了单个智能体需要记忆和处理的数据量。因此,在面对长历史或复杂任务时,多智能体系统无需像单智能体那样维护庞大的记忆容量,降低了对模型序列长度的依赖,提高了系统的可扩展性和实用性。

    • 单智能体局限:单智能体如AutoGPT需要记住并处理所有历史信息以做出决策,这对模型的记忆容量和计算能力提出了极高的要求。在长历史任务中,这种需求可能导致性能瓶颈,限制了单智能体系统的应用范围。

  2. 稳定性与观点排除


    • 多智能体优势:通过角色扮演机制,多智能体系统能够模拟不同角色的视角和立场,从而有效排除某些偏见或错误观点的影响。这种机制使得系统输出更加客观、稳定,提高了决策质量。此外,不同智能体之间的交互还可以促进新想法的产生和验证,进一步增强了系统的创新性和适应性。

    • 单智能体局限:单智能体在执行多任务时,由于所有任务信息都混合在一起处理,容易受到各种因素的干扰,导致输出结果的不稳定。同时,单智能体难以有效区分和排除不同任务之间的潜在冲突或错误观点。

  3. 可拓展性与任务分解


    • 多智能体优势:多智能体系统通过分工协作的方式将复杂任务分解为多个相对简单的子任务,每个智能体专注于完成一个或几个子任务。这种任务分解策略不仅降低了单个智能体的处理难度,还提高了系统的整体效率和可拓展性。随着任务复杂度的增加,只需增加相应的智能体数量或调整智能体之间的协作策略即可应对。

    • 单智能体局限:单智能体在处理复杂任务时,通常需要依赖记忆节省策略(如token压缩、关键信息提取等)来减少输入给模型的context长度。然而,这些策略在极端情况下可能无法完全避免性能下降的风险,因为长序列处理仍然是大型语言模型面临的一个挑战。

  4. 并行探索与最优解选择


    • 多智能体优势:多智能体系统能够并行地探索多种解决方案,并通过比较和评估来选择最优解。这种并行探索机制不仅提高了问题求解的效率,还有助于发现更多潜在的优秀解。此外,不同智能体之间的探索结果可以相互借鉴和补充,形成更加全面的解决方案集合。

    • 单智能体局限:单智能体在探索解决方案时通常只能采用串行或有限的并行方式(如分支预测、多线程等),其效率受到模型处理能力和计算资源的限制。同时,由于单智能体缺乏多视角的评估机制,其选择的解决方案可能不是全局最优的。即使通过增加计算资源来提高并行度,也可能面临资源分配不均、协调困难等问题。

Auto-GPT

  • 简介:虽然内部设计为单个智能体,但其自我批判的逻辑被视为多智能体策略的简化版本。AutoGPT能够根据反馈调整其行为,体现了智能体自我改进的能力。
  • 应用:自动化任务执行、问题解决、基于指令的编程任务。

例子:
https://twitter.com/SullyOmarr/status/1644750889432027136

  • created login/sign up page
  • styled it with bootstrap+ created flask api for login / logout
  • created a local json database
    Took ~10 minutes at a cost of $0.50

框架结构简单,但其设计理念具有重要意义,后续框架设计的思路都有这个的影子

  • 创建一个初始的计划,然后进入主循环
  • 系统会让模型判断在当前计划下该进行何种行动,接着会执行行动
  • 执行完毕后,结果会写入下一次循环中
  • 如此,每次决策都会基于之前的结果、记忆和计划,从而制定出新的行动方案
  • 优点:


    • 内存和上下文管理:与 AutoGen 一样,AutoGPT 在内存和上下文等领域也表现出色,为需要这些功能的 LLM 应用程序提供了优势。
  • 缺点:


    • 可视化构建器依赖性:应用程序设计依赖于可视化构建器,这可能会限制那些宁愿用代码定义设计的团队的灵活性。

AutoGen

  • 简介:AutoGen是一个开源框架,它通过多智能体对话来构建下一代大型语言模型应用。这个框架允许智能体通过对话相互协作,完成复杂任务,体现了智能体间的高度互动性和任务的灵活性。
  • 应用项目:AutoGen被设计为一个通用平台,可以应用于自动代码生成、复杂问题解决、自动化工作流程设计等领域。

论文链接:
https://arxiv.org/abs/2308.08155

项目链接:
https://github.com/microsoft/autogen


user_proxy (to assistant):

What date is today? Compare the year-to-date gain for META and TESLA.

--------------------------------------------------------------------------------
assistant (to user_proxy):

First, let's get the current date. We can do this using Python's built-in datetime module. Here is the Python code to get the current date:


import datetime

 Get the current date
current_date = datetime.date.today()

print("Today's date is:", current_date)


Next, we need to get the year-to-date (YTD) gain for META (Facebook) and TESLA. We can do this by using a financial data API such as Yahoo Finance. We will need to get the stock price at the start of the year and the current stock price, then calculate the percentage change.

However, as an AI, I'm unable to execute real-time web requests or access external APIs. I recommend using the `yfinance` library in Python to download the stock data. Here is an example of how you can do it:


import yfinance as yf

#Download stock data
meta_data = yf.download('META', start='2022-01-01', end=current_date)
tesla_data = yf.download('TSLA', start='2022-01-01', end=current_date)

#Calculate YTD gain
meta_ytd_gain = ((meta_data['Close'][-1] - meta_data['Close'][0]) / meta_data['Close'][0]) * 100
tesla_ytd_gain = ((tesla_data['Close'][-1] - tesla_data['Close'][0]) / tesla_data['Close'][0]) * 100

print("META YTD gain: ", meta_ytd_gain)
print("TESLA YTD gain: ", tesla_ytd_gain)


Please note that you need to install the `yfinance` library before running the above code. You can install it using pip:


pip install yfinance


Please replace `current_date` in the above code with the actual date you got from the first code.

--------------------------------------------------------------------------------

>>>>>>>> EXECUTING CODE BLOCK 0 (inferred language is python)...

>>>>>>>> EXECUTING CODE BLOCK 1 (inferred language is python)...
user_proxy (to assistant):

exitcode: 1 (execution failed)
Code output: 
Today's date is: 2023-10-17

Traceback (most recent call last):
  File "", line 4, in <module>
    meta_data = yf.download('META', start='2022-01-01', end=current_date)
NameError: name 'current_date' is not defined


--------------------------------------------------------------------------------
assistant (to user_proxy):

I apologize for the confusion. The `current_date` variable was defined in the first script and it's not available in the second script. Let's combine the two scripts into one so that the `current_date` variable can be used in the second part of the script. Here is the combined script:


import datetime
import yfinance as yf

#Get the current date
current_date = datetime.date.today()
print("Today's date is:", current_date)

#Download stock data
meta_data = yf.download('META', start='2022-01-01', end=current_date)
tesla_data = yf.download('TSLA', start='2022-01-01', end=current_date)

#Calculate YTD gain
meta_ytd_gain = ((meta_data['Close'][-1] - meta_data['Close'][0]) / meta_data['Close'][0]) * 100
tesla_ytd_gain = ((tesla_data['Close'][-1] - tesla_data['Close'][0]) / tesla_data['Close'][0]) * 100

print("META YTD gain: ", meta_ytd_gain)
print("TESLA YTD gain: ", tesla_ytd_gain)


Please run this script to get the current date and the year-to-date gain for META and TESLA.

--------------------------------------------------------------------------------

>>>>>>>> EXECUTING CODE BLOCK 0 (inferred language is python)...
user_proxy (to assistant):

exitcode: 0 (execution succeeded)
Code output: 
Today's date is: 2023-10-17

[*********************100%%**********************]  1 of 1 completed

[*********************100%%**********************]  1 of 1 completed
META YTD gain:  -5.136767947511282
TESLA YTD gain:  -36.50836025922416


--------------------------------------------------------------------------------
assistant (to user_proxy):

The current date is October 17, 2023. 

The year-to-date (YTD) gain for META (Facebook) is approximately -5.14%, indicating a decrease in value since the start of the year.

The YTD gain for TESLA is approximately -36.51%, indicating a significant decrease in value since the start of the year.

Please note that these values are based on the closing prices of the stocks and can vary slightly depending on the source of the data.

TERMINATE

--------------------------------------------------------------------------------

  • 优点:
    • 完善:AutoGen 拥有一个非常活跃的社区,非常适合寻求支持和协作的开发人员。
    • 可定制的代理:它还提供可定制的代理,可以集成 LLM、工具和人工反馈,使任务执行高度灵活。
  • 缺点:
    • 复杂性:这是一个相当复杂的框架,对于新用户来说可能是一个挑战,需要陡峭的学习曲线才能有效利用其功能。
    • 结构性较差:一些开发人员可能会发现 AutoGen 与其他框架相比结构性较差,这可能会影响实施的难易程度。

XAgent

项目链接:
https://github.com/OpenBMB/XAgent

官方博文:
https://blog.x-agent.net/blog/xagent/

  • 双循环机制
  • 外循环负责宏观规划,而内循环则负责细节的执行
  • 效果碾压 AutoGPT

  • 总结:
  1. 能力强大,但极耗 token,上述例子消耗了 10 刀 token
  2. 运行极慢,单次执行 30min
  3. 可扩展性比较强,可基于 ToolServer(基于智谱的另外一个项目 ToolBench)扩展自定义接口

OPENAI Assistants

MetaGPT

MetaGPT是一种创新的多智能体协作框架,其名字来源于“GPT-based Meta-Programming framework”,旨在通过分配不同的角色给生成式预训练变换器(GPTs),形成一个协作的软件实体以完成复杂任务。

  • 多智能体协作:MetaGPT的核心在于其多智能体协作的框架设计,每个GPT模型都被赋予特定的角色和任务,通过协作解决复杂问题,从而提高整体效率和性能。
  • 标准化操作程序(SOP):MetaGPT利用SOP来协调基于大语言模型(LLM)的多智能体系统,实现元编程技术,增强问题解决能力。
  • 高度可扩展性:随着任务复杂度的增加,可以通过添加更多的GPT模型来扩展MetaGPT系统的能力,使其能够适应不断变化的需求和环境。

论文链接:
https://arxiv.org/abs/2308.00352

GitHub地址:
https://github.com/geekan/MetaGPT

  • 优点:


    • 复杂的代理交互:MetaGPT 在支持代理之间的复杂交互方面表现出色,使其适用于复杂的多代理任务。
    • 丰富的库:它还附带一个丰富的预定义代理库,无需进行大量自定义开发即可实现一系列功能。
  • 缺点:


    • Asyncio 依赖性:严重依赖 asyncio,这对于网络密集型 I/O 来说可能很好,但与其他 python 原生并行处理方法相比,它有一些相当严重的限制。
    • 有限的通用性:MetaGPT 中的代理角色可能缺乏通用性,可能会限制其在需要高度可定制代理的场景中的使用。

适合人群:需要复杂的多代理交互和预定义复杂行为的项目。非常适合网络密集型异步操作和需要高级协作功能而无需大量定制的项目

AutoAgents

项目链接:
https://github.com/Link-AGI/AutoAgents

AutoAgents的过程是分为两个关键阶段:Drafting 阶段和Execution阶段。Drafting阶段包括三个预定义agent(Planner、Agent Observer和Plan Observer)之间的协作讨论来综合定制的agent团队和适合输入问题的执行计划或任务。Execution阶段通过agent间协作和反馈完善计划,以及产生最终结果。论文提出self-refinement ,通过个体agent和协作进行自我完善通过多个agent进行细化,以提高agent的熟练程度并促进各agent之间的知识共享agents。为了促进合成团队中agents之间的具体分工,作者引入预定义的agent(Action Observer)以协助agents团队共享信息,协调行动,达成共识,适应环境。

crewAI

项目代码:
https://github.com/joaomdmoura/crewAI
官网博文:
https://docs.crewai.com/

  • 基于角色的Agent设计:使用特定的角色、目标和工具来定制Agents。
  • 自动化的Agents间委托:agents可以自主地委托任务并在彼此之间进行询问,从而提高问题解决效率。
  • 灵活的任务管理:使用可定制的工具定义任务,并将其动态分配给agents。
  • 流程驱动:目前仅支持顺序任务执行,但正在研究更复杂的流程,如协商一致和分层。

  • 优点:


    • 生产重点:CrewAI 的设计考虑到了生产用途,具有干净的代码和注重实际应用。
    • 代理委派:强调代理委派,允许在代理之间采用结构化的方法分配任务。
  • 缺点:


    • 重新委派限制:重新委派和使用外部代理的限制可能会限制分配和执行任务的灵活性。
    • 数据收集:收集匿名使用数据,这可能会引起某些团队的隐私问题。

更多项目

BabyAGI、CAMEL、DSPy、OpenAgents、Agents、AgentVerse、ChatDev、LangGraph

更多优质内容请关注公号:汀丶人工智能;会提供一些相关的资源和优质文章,免费获取阅读。

一、WTM是什么

WalkingTec.Mvvm框架(简称WTM)最早开发与2013年,基于Asp.net MVC3 和 最早的Entity Framework, 当初主要是为了解决公司内部开发效率低,代码风格不统一的问题。
2017年9月,将代码移植到了.Net Core上,并进行了深度优化和重构,推出了基于Asp.net Core和EF Core的全新框架,新框架在架构,稳定性,速度上都有长足进步,真正成为一款高效开发的利器。
经历了四年间数十个项目的考验,框架逐步的完善,推出了四个主要版本。
WTM框架设计的核心理念就是”尽一切可能提高开发效率“。
WTM框架把常规编码结构化,重复编码自动化,它不仅是一个框架,它是强有力的生产力工具!
在不分离的模式下,它连通了前台UI和后台代码。你不需要前后台分离,不需要两个人配合,减少成本,缩短工期。
在前后端分离的模式下,同样可以使用代码生成器同时生成前台和后台的代码,极大的降低了前后端人员的沟通成本,从本质上提升了开发效率,让“分离”不再复杂和昂贵。
框架特点:
一键生成WTM项目
一键生成增删改查,导入导出,批量操作代码
支持一对多,多对多关联模型的识别和代码生成
支持React+AntD,Vue+Element,LayUI,Blazor等多种前端模式
支持sqlserver,mysql,pgsql,sqlite,Oracle等多种数据库
封装了Layui,AntD,Element的大部分控件,编写前台更加简便
提供了很多基类,封装了绝大部分后台常用操作
提供了用户,角色,用户组,菜单,日志等常用模块
支持数据权限的开发和配置
支持读写分离和数据库分库

开源地址:
(GitHub) https://github.com/WalkingTec/WalkingTec.Mvvm
(Gitee) https://gitee.com/liuliang-wtm/WTM

二、人大金仓是什么
人大金仓数据库管理系统[简称:KingbaseES]是北京人大金仓信息技术股份有限公司[简称人大金仓]的核心产品,具有大型通用、"三高"(高可靠、高性能、高安全)、"三易"(易管理、易使用、易扩展)、运行稳定等特点,是唯一入选国家自主创新产品目录的数据库产品,也是国家级、省部级实际项目中应用最广泛的国产数据库产品。
人大金仓数据库管理系统 KingbaseES(KES) 是面向全行业、全客户关键应用的企业级大型通用数据库管理系统,适用于联机事务处理、查询密集型数据仓库、要求苛刻的互联网应用等场景,提供全部应用开发及系统管理功能,提供性能增强特性,可支持主备集群、读写分离集群、多活共享存储集群等全集群架构,具有高性能、高安全、高可用、易使用、易管理、易维护的特点,支持所有国内外主流CPU、操作系统与云平台部署。
下载试用地址:
https://www.kingbase.com.cn/xzzx/index.htm
可在下载页面申请开发试用授权文件,授权时间365天。
安装过程比较简单,
唯一需要注意的就是在安装过程中可以选择数据库兼容类型,这里选择的是UTF8字符集,兼容MySql,大小写不敏感。

三、迁移注意事项

项目用的是.NET6框架,在项目里引用(或者NuGet安装)人大金仓官方的EFCore的Kdbndp驱动Kdbndp.EntityFrameworkCore6.KingbaseES。

1、工作流使用的数据库所属模式手动创建

WTM集成了Elsa的工作流,在迁移的过程中需要把Elsa所需要的几个表迁移到特定的模式下面,否则运行会提示找不到Elsa.xxxx的错误提示;

模式右键-->新建-->Elsa,然后把所需要的这几个表迁移到它下面。

2、字段类型转换

绝大部分的Mysql字段可以无缝迁移到人大金仓,对于mysql的bool类型的字段需要特别关注一下,会迁移成bit或者int类型,需要手动调整成人大金仓的bool类型;

mysql的datetime类型,迁移到人大金仓后对应的类型是timestamp。这个需要在DataContext的OnConfiguring中指定一下参数,否则会报以下错误:

System.InvalidCastException: Cannot write DateTime with Kind=Local to PostgreSQL type 'timestamp with time zone', only UTC is supported. Note that it's not possible to mix DateTimes with different Kinds in an array/range. See the Npgsql.EnableLegacyTimestampBehavior AppContext switch to enable legacy behavior.

具体参考:https://www.npgsql.org/doc/types/datetime.html#timestamps-and-timezones

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
		{
			if (DBType == DBTypeEnum.PgSql)
			{
				AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
				AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true);
			}
			base.OnConfiguring(optionsBuilder);
		}

2、自增字段实现

在mysql、sqlserver等数据库中,只要把字段设置为int,然后打开自增选项后,字段就会实现自增功能。在人大金仓中,默认没有这种字段类型,官网中称这种为
序数类型
,类似于Oracle的SEQUENCE:

small serial、serial 和 bigserial类型不是真正的类型, 它们只是为了创建唯一标识符列而存在的方便符号(类似其它一些数据库中支持的 AUTO_INCREMENT 属性)。 这是 KingbaseES 特有的创建一个自增列的方法。

因为 small
serial、serial 和 bigserial 是用序列实现的,所以即使没有删除过行,在出现在列中的序列值可能有“空洞”或者间隙。如果一个从序列中分配的值被用在一行中,即使该行最终没有被成功地插入到表中,该值也被“用掉”了。例如,当插入事务回滚时就会发生这种情况。更多信息参见序列操作函数中的 nextval()。

在人大金仓中需要通过序列类型实现字段自增的方式,需要我们在数据库的Public模式下的序列中,创建一个序列(这里设置的最大值为bigint的最大值附近,具体可自己决定):


随后,在需要自增的字段,给它的默认值设置为 nextval('USER_SEQUENCE'::regclass)  ,这样在每次insert数据的时候,这个字段会自动从序列中获取最新的值来填充(不需要代码中进行赋值)。

至此就基本完成了mysql到人大金仓的数据库迁移。

目录

一、简介

二、GTKSystem.Windows.Forms框架的优势

三、支持界面皮肤主题定制

四、多种控件支持

五、支持Dock、Anchor、SplitContainer布局缩放

六、支持扩展控件


一、简介

微软原生的.net winform只支持在windows平台下运行,只中一个原因是windows用的视窗是GDI+绘制的,主要原因是微软不想支持linux或macos平台。VC.Net winform软件是windows系统软件环境和开发环境最大的优势之一,是微软占据电脑主流系统的利器!

GTKSystem.Windows.Forms框架是C# winform应用程序跨平台(windows、linux、macos)界面开发框架,基于GTK组件开发,该框架的核心优势是兼容C#的原生winform表单控件窗体控件,相同的属性、方法、事件,C#原生开发即可,无需学习。

一次编译,跨平台运行。 便于开发跨平台winform软件,便于将C#升级为跨平台软件。

二、GTKSystem.Windows.Forms框架的优势

使用GTKSystem.Windows.Forms框架开发winform软件至少有8大优势:

1、框架开源,可以自由定制程序。

gitee:https://gitee.com/easywebfactory/gtksystem-windows-forms

github:https://github.com/easywebfactory/gtksystem-windows-forms

2、完全支持visual studio工具开发,支持可视化窗体设计器设计form界面。

3、与c#原生控件相兼容,相同的方法、属性、事件,软件工程可以直接原生开发,可以在原生与GTKSystem.Windows.Forms框架相互切换。

4、微软官方支持.net控制台程序在linux上运行,本框架使用.net控制台,完美运行。

5、GTK官方支持微软windows平台,可以在windows系列版本系统上运行。

6、视窗图形框架使用GTK,同时支持windows、linux、macos平台,GTK具有优秀稳定的性能,几乎所有主流linux的可视化操作视窗都是基于GTK开发,包括ubuntu、debian、kylin、deepin等主流系统,国产操作系统如统信、麒麟、深度、红旗等,GTK与linux可以无缝支持。

7、支持linux的主题界面样式,与linux操作系统融为一体,同时支持自定义界面样式。

8、支持macos,gtk或.net sdk都官方支持macos,让GTKSystem.Windows.Forms框架可以在macos完美运行。

三、支持界面皮肤主题定制,如:

四、多种控件支持

五、支持Dock、Anchor、SplitContainer布局缩放

六、支持扩展控件

可以自由扩展控件,将提供多功能的报表数据表格、折叠面板、属性网格、折叠卡片、步骤条、开关控件等常见控件。

你想让软件同时在windows下运行、在linux上运行、在苹果电脑上运行、在国产操作系统上运行吗? 那么选择GTKSystem.Windows.Forms框架!甚至,当你不想用GTKSystem.Windows.Forms框架时,直接切换回.net框架,你的软件也可以直接编译发布。

在电商平台上,会有很有榜单的信息,比如新品榜、畅销榜。通过这些榜单,可以让用户直观的对比各个商品之间的销量对比,促使更多的用户下单或者加购。本文介绍如何实现一个简单的榜单功能

榜单定义

在某多 app 上,可以看到下面的小米手表排行榜:

需要实现几个功能:

  • 榜单是针对某类商品进行统计,比如手机排行是统计品类为手机的商品。
  • 排行统计可以是按照某一个维度,比如订单量、一个月回购量、或者几个指数汇总成一个分数进行排行。上图就是根据热卖指数进行排行。
  • 除了排行之外,还需要展示霸榜的天数,比如霸榜榜首 n 天、霸榜前三 n 天。上面排名第一就展示了霸榜榜首的天数。

榜单实现思路

统计榜单至少需要两张表,榜单主表和榜单明细表。

  • 主表记录榜单信息,比如
    xx月xx手机畅销榜
    ,统计维度、统计时间范围等等。
  • 明细表主要记录,商品有信息、排行、统计销量、分数等信息。

创建好榜单之后,每天定时跑统计任务,将更新榜单明细表中。统计的维度,需要根据具体需求来查询数据库,然后在计算分数,最后计算排名。

以上实现比较简单,主要是去除相关数据进行汇总计算。最重要的一个功能就是霸榜天数的求解。

霸榜天数

霸榜分成两种:霸榜榜首 n 天、霸榜前三 n 天。这就需要多加一个表,榜单明细日志表,记录每天榜单明细。比如以下记录三天的榜单明细日志记录:

霸榜天数是
从后往前
统计,需要统计连续的天数,首先定位到最后一天,也就是4日,前三的商品 C、A、B 三个商品。统计榜首,就一直排在榜首,直到前面不是榜首的商品。比如上面的图中,4日榜首是商品 C,这就往前推算,3日是不是商品 C,如果不是霸榜1天。如果是的话,就继续往前查,天数累加,直到统计的是非商品。

霸榜前三就相对复杂一点,需要统计两个数据,也就是排名三的往前统计,因为榜首已经统计了,所以只需要统计第2和第3的商品,也就是商品 A 和商品 B。往前找数据:

统计榜首

创建榜单明细日志类:

  @Data
  @AllArgsConstructor
  class RankDetailLog{

      /**
       * 商品
       */
      private String product;

      /**
       * 排行
       */
      private Integer rank;

      /**
       * 时间
       */
      private String createTimeStr;

  }

创建模拟数据:

RankDetailLog detailLog7 = new RankDetailLog("C",1,"7月4日");
RankDetailLog detailLog8 = new RankDetailLog("A",2,"7月4日");
RankDetailLog detailLog9 = new RankDetailLog("B",3,"7月4日");
RankDetailLog detailLog1 = new RankDetailLog("D",1,"7月2日");
RankDetailLog detailLog2 = new RankDetailLog("B",2,"7月2日");
RankDetailLog detailLog3 = new RankDetailLog("C",3,"7月2日");
RankDetailLog detailLog4 = new RankDetailLog("B",1,"7月3日");
RankDetailLog detailLog5 = new RankDetailLog("C",2,"7月3日");
RankDetailLog detailLog6 = new RankDetailLog("A",3,"7月3日");

List<RankDetailLog> detailLogList = new ArrayList<>();
detailLogList.add(detailLog1);
detailLogList.add(detailLog2);
detailLogList.add(detailLog3);
detailLogList.add(detailLog4);
detailLogList.add(detailLog5);
detailLogList.add(detailLog6);
detailLogList.add(detailLog7);
detailLogList.add(detailLog8);
detailLogList.add(detailLog9);

分组排序:

// 按日期分组并排序
Map<String, List<RankDetailLog>> sortedCreateTimeMap = detailLogList.stream()
        .collect(Collectors.groupingBy(RankDetailLog::getCreateTimeStr, () -> new TreeMap<>(Comparator.reverseOrder()), Collectors.toList()));    

统计榜首:

String topProduct = null;
Integer topProductNum = 0;
for (Map.Entry<String, List<RankDetailLog>> entry : sortedCreateTimeMap.entrySet()) {
    List<RankDetailLog> rankDetailLogList = entry.getValue();
    if (!rankDetailLogList.isEmpty()) {
        RankDetailLog topLog = rankDetailLogList.get(0);
        String currentTopProduct = topLog.getProduct();
        if (topProduct == null) {
            topProduct = currentTopProduct;
            topProductNum = 1;
        } else {
            if (topProduct.equals(currentTopProduct)) {
                topProductNum++;
            } else {
                break;
            }
        }
    }
}
System.out.println("榜首商品:" + topProduct + ",天数:" + topProductNum);

输出:C:1 表示商品霸榜榜首1天。

步骤详解:

  • topProduct 标记榜首商品,topProductNum 榜首天数记录。
  • 遍历集合,记录榜首商品,然后天数设置1。遍历数据,如果是连续的数据,数量 +1。找不到商品就结束遍历。

统计前三

前三的统计其实是排除了榜首,也就是只统计最新数据的第2和第3的商品。往前汇总统计。

Set<String> threeProductSet = new HashSet<>();
Map<String,Integer> threeProductMap = new HashMap<>();
boolean first = true;
for (Map.Entry<String, List<RankDetailLog>> entry : sortedCreateTimeMap.entrySet()) {
    List<RankDetailLog> rankDetailLogList = entry.getValue();
    if (!rankDetailLogList.isEmpty()) {
        // 只取前三数据
        rankDetailLogList = rankDetailLogList.subList(0,Math.min(3,rankDetailLogList.size()));
        if (first) {
            for (int i = 0; i < rankDetailLogList.size(); i++) {
                RankDetailLog detailLog = rankDetailLogList.get(i);
                String topThreeProduct = detailLog.getProduct();
                if (i >= 1) {
                    threeProductSet.add(topThreeProduct);
                    threeProductMap.put(topThreeProduct,0);
                }
            }
            first = false;
        } else {
            Set<String> currentThreeProductSet = new HashSet<>();
            for (RankDetailLog detailLog : rankDetailLogList) {
                String topThreeProduct = detailLog.getProduct();
                if (threeProductMap.containsKey(topThreeProduct)) {
                    threeProductMap.put(topThreeProduct,threeProductMap.get(topThreeProduct) + 1);
                    currentThreeProductSet.add(topThreeProduct);
                }
            }
            threeProductSet.removeAll(currentThreeProductSet);
        }
    }
}
System.out.println(threeProductMap);

输出:{A=2, B=3}

  • 获取到最新商品详情,统计第2和第3的商品,存 threeProductSet 以及计算器集合 threeProductMap 中。
  • 为了统计连续性,使用 currentThreeProductSet 存当天的商品信息,再和前面的商品交集,交集的数据就是有连续性商品数据。

总结

  • 商品榜单需要根据不同的统计维度、参数、统计时间来设计商品榜单表结构。再根据配置的信息,生成榜单详情信息。
  • 一般都使用定时方式生成榜单详情信息。
  • 需要统计连续霸榜天数,一般有两种方式,一种是统计榜首的连续天数,另一种是前三的连续天数。
    • 统计榜首首先获取最新的榜首商品,商品往前找,连续性的找到前面的数据,如果非连续性就查找结束。
    • 统计前三排除了榜首之外,就是统计第2和第3的商品。获取最新的商品并记录,往前遍历,使用 set 的存储每次遍历的商品,在使用集合的交集来保证统计的连续性。