用c#从头写一个AI agent,实现企业内部自然语言数据统计分析(三)--一个综合的例子

在前面一节中,我们做了一个简单的统计图表的例子。本节中,我们将实现一个综合的稍微复杂一点的例子,并对这个例子做一个详细的剖析,如下图所示:。

上面是我通过Agent和大模型进行的对话,在指定的时间,我在web端收到了一个消息,如下所示:

Agent按照我的要求从数据库中获取数据,并在指定的时间通过消息发送给我。Agent为何能如此听话?或者说能听得懂我的话,并按照要求执行呢?那是因为我给他配置了解决此类问题的各种工具(tools)让他在合适的时候调用,下面是Agent在收到我的指令后进行的一系列动作,整个过程描述如下:

1、用户发出请求:在晚上17点28统计一下知识库数量和用户数量,一起发给admin

2、Agent收到请求后发给大模型,大模型初步判断这个是一个定时触发的任务,调用我的工具创建定时器,这个工具的json描述如下:

复制代码
{
          "type": "function",
          "function": {
            "name": "RemindAdd",
            "description": "当你想定时提醒的时候非常有用。如果对于用户给出的时间不确定,例如用户说:10点提醒我拿东西,这里的10点可能是早上10点,也可能是晚上10点,所以你要询问用户给出确定的时间点。但是如果根据系统时间,现在的时间已经过了10点,那么默认就是晚上10点,就不用在询问用户了。",
            "parameters": {
              "type": "object",
              "properties": {
                "time": {
                  "type": "string",
                  "description": "定时到期时间,使用24小时时间格式。例如2025-02-05 15:31。如果用户是指每天任务的话, 那么这个时间必须是今天的时间"
                },
                "something": {
                  "type": "string",
                  "description": "一个动作,用户想要在定时到期时要做的事情,例如:做饭,洗碗等"
                },
                "timeRelated": {
                  "type": "string",
                  "description": "和用户定时相关的词语,例如:3分钟后,12:50,下午4点等"
                },
                "userInput": {
                  "type": "string",
                  "description": "用户输入的原话内容"
                },
                "userLoginName": {
                  "type": "string",
                  "description": "当前用户登录名,使用系统提示的内容填写"
                },
                "isEveryDay": {
                  "type": "string",
                  "description": "是否为每天重复提醒,true或者false"
                },
                "contentType": {
                  "type": "string",
                  "description": "提醒的类型:text或者action。text是指发送文本消息,action指的是一个动作:例如查询当天最新的IT资讯,发送消息,或者用户请求中包含 \"自动、定时、发送\" 等动作词汇时也认为是一个action。"
                }
              }
            },
            "required": [
              "time",
              "something",
              "timeRelated",
              "userInput",
              "userLoginName",
              "isEveryDay",
              "contentType"
            ]
          }
        }

大模型指示Agent调用这个工具,并传递参数。Agent根据传递参数创建定时器,保存在数据库中,这个定时器信息如下图:

3、在指定时间到期之后,Agent提取定时器的提醒内容 "统计知识库数量和用户数量,然后将结果一起发给admin" 提交给大模型。

4、大模型判断这是一个多任务场景,返回Agent说调用任务分解的tool,并传递参数,这个任务分解函数的json描述如下:

复制代码
 {
      "type": "function",
      "function": {
        "name": "Global_Decomposition",
        "description": "任务分解函数,把用户请求的内容分成若干个可执行的最小单元,确保每个单元都包含且只能包含一个独立任务。如果您发现用户的请求是一个包含多个任务的情况时,优先调用这个函数,这个函数的优先级别最大(除了和定时、提醒有关的内容)。例如用户说:统计一下部门用户数,并给我写一个简单js2个数字相加的函数,还有通知全体市场部人员开会。\n那么使用这个Global_Decomposition可以把用户的输入分解成3个任务,就是 :[{ \"index\": 1,\"desc\": \"统计一个部门用户数\" ,\"base\":\"\" },{\"index\": 2,\"desc\": \"写一个简单js2个数字相加的函数\" ,\"base\":\"\" },{\"index\":3,\"desc\":\"通知全体市场部人员开会\",\"base\":\"1,2\" }...] 。任务分解注意一下几点:\\n1、如果这些任务之间有前后依赖关系,那么请注意任务分解时候的排序,要把被依赖的任务放在依赖他的任务之前。\\n2、如果分解后还是只有一个任务,那么就不要分解。\\n3、要保证任务分解必须能全面执行用户的任务,任务分解的数量不限制,要保证逻辑清晰、完整、正确。\\n4、其中base指出任务之间的依赖关系。",

        "parameters": {
          "type": "object",
          "properties": {
            "tasks": {
              "type": "string",
              "description": "分解后的任务,一个json数组格式的字符串,不能为空。例如:[{\"index\": 1,\"desc\": \"统计一个部门用户数\",\"base\":\"\"   },{\"index\": 2,\"desc\": \"写一个简单js2个数字相加的函数\",\"base\":\"\"  },{\"index\":3,\"desc\":\"通知全体市场部人员开会\",\"base\":\"1,2\" }...]。其中base指出任务之间的依赖关系,填写依赖任务的index值,多个之间使用逗号隔开。"
            },
            "agentID": {
              "type": "string",
              "description": "agentID"
            },
            "userLoginName": {
              "type": "string",
              "description": "用户名,根据系统提示自动填入"
            },
            "userInput": {
              "type": "string",
              "description": "用户提问的原话内容"
            }
          }
        },
        "required": [
          "tasks",
          "agentID",
          "userLoginName",
          "userInput"
        ]
      }
    },

通过这个json,大模型把这个任务 " 统计一下知识库数量和用户数量,一起发给admin" 分解为三个任务:

  • 1、统计是知识库数量
  • 2、统计用户数量
  • 3、把上面两个统计结果发送给admin(任务3依赖于任务1、2)

Agent拿到分解的任务后,根据任务的依赖关系,经过遍历循环执行(如果分解任务数量多,依赖关系复杂可能需要多次遍历执行),先完成任务1和任务2(再上一篇中详细介绍过),然后把任务1和任务2的结果以及任务3一起提交给大模型

5、大模型在收到 第上面四步的请求(类似于:知识库数量178,用户数量51。请根据以上信息完成用户下面的请求:把统计结果发送给admin),判断这是一个信息发送的任务,返回工具调用信息,这个发送信息的json格式如下:

复制代码
{
        "type": "function",
        "function": {
          "name": "System_Notify",
          "description": "当你想发送通知、消息、email,短信等时非常有用。",
          "parameters": {
            "type": "object",
            "properties": {
              "agentID": {
                "type": "string",
                "description": "agentID"
              },
              "userLoginName": {
                "type": "string",
                "description": "发送人姓名"
              },
              "message": {
                "type": "string",
                "description": "消息内容。"
              },
              "toUser": {
                "type": "string",
                "description": "消息接收人姓名,多个接收人之间使用逗号(,)分开。例如:张三,李四,王五"
              },
              "userDesc": {
                "type": "string",
                "description": "消息接收人描述:用户没有提及具体的姓名而是一个描述,系统管理员 或者 财务部的部长"
              },
              "msgType": {
                "type": "string",
                "description": "消息类型,包括:短信(sms)、系统消息(system)、邮件(email)、微信群(weixingroup)、个人微信(weixinuser),多个消息类型之间使用逗号(,)分开。例如:sms,system,email,weixin。"
              },
              "toName": {
                "type": "string",
                "description": "当参数mstType是微信群时,toName指的是微信群的名称或者个人微信的名称"
              },
              "userInput": {
                "type": "string",
                "description": "用户提问的原话内容。"
              }
            }
          },
          "required": [
            "userLoginName",
            "message",
            "toUser",
            "userDesc",
            "msgType",
            "userInput",
            "toName",
            "agentID"
          ]
        }

6、Agent收到后,根据参数进行消息发送

至此整个流程完成。从这个过程中看出,Agent在人类和大模型之间,起到一个中间人的角色。人类在发出一个请求给Agent后,通过Agent和大模型之间的多次沟通和信息交流后,完成人类的指令。

以上只是一个简单的实例,但任何复杂的事情都是由简单的组成的不是吗?

相关推荐
钢铁男儿24 分钟前
C#:创建变量和类的实例
c#
了一li2 小时前
C#中用 OxyPlot 在 WinForms 实现波形图可视化(附源码教程)
开发语言·c#
Object-v2 小时前
部署一个自己的Spring Ai 服务(deepseek/通义千问)
java·spring boot·ai
大模型铲屎官2 小时前
Unity C# 与 Shader 交互入门:脚本动态控制材质与视觉效果 (含 MaterialPropertyBlock 详解)(Day 38)
c语言·unity·c#·交互·游戏开发·材质·shader
CoderJia程序员甲4 小时前
MarkItDown:如何高效将各类文档转换为适合 LLM 处理的 Markdown 格式
ai·llm·markdown·文档转换
攻城狮7号4 小时前
20250429-李彦宏口中的MCP:AI时代的“万能接口“
人工智能·python·ai·mcp
全栈小54 小时前
【C#】.net core6.0无法访问到控制器方法,直接404。由于自己的不仔细,出现个低级错误,这让DeepSeek看出来了,是什么错误呢,来瞧瞧
开发语言·c#·.netcore
浅陌sss11 小时前
C#中实现XML解析器
xml·c#
Florian13 小时前
Qwen3接入评测,最强开源模型更懂Graph了吗?
agent·graph·chat2graph·qwen3