什么是AI Agent?大白话新手教学

Agent的诞生背景

如果只有LLM的话,那么LLM就相当于一个脑子,你问他一个问题,他会给你答案或者告诉你怎么做,但并不会帮你去解决这个问题,实际还是需要你自己动手去解决。
(比如我问大模型:“我要回福建,需要买河南到福建的机票”。那么大模型只会告诉你买机票的方法,并不会去帮你买机票)
这样非常的麻烦。
那么我们能不能让LLM返回答案的同时去把问题也给解决了呢?
为了能让LLM(脑)解决实际问题,我们先需要给大模型加上一个tools(手)。
再把脑子和手集成到一个东西里,让这个东西能够自由地调度手和脑子。这个东西就是agent。
大模型用于回答问题(脑子),agent是你的助理,他能够根据大模型回答的问题,并借助tools(手),去完成一系列指定的操作。

用LangChainGo集成Agent

Langchain是一个python框架,用于将大语言模型集成到各种应用中。
LangchainGo就是这个Langchain框架的Go语言版本,除此之外还有 langchain4j(用于java)、rust-langchain(用于rust)、langchain.js(用于javascript)
需求:
我们现在用LangChainGo集成一个Agent,让这个Agent可以根据我们的指令去打开电脑上的Wegame。
package main

import (
    "context"
    "fmt"
    "log"
    "os/exec"

    "github.com/tmc/langchaingo/agents"
    "github.com/tmc/langchaingo/chains"
    "github.com/tmc/langchaingo/llms/openai"
    "github.com/tmc/langchaingo/tools"
)

// OpenWeGameTool 自定义一个 tool,用于打开 WeGame 应用
type OpenWeGameTool struct{}

// Tool 的名称
func (t OpenWeGameTool) Name() string {
    return "OpenWeGame"
}

// Tool 的功能描述
func (t OpenWeGameTool) Description() string {
    return "Opens the WeGame application on the user's computer."
}

// Tool 的功能
func (t OpenWeGameTool) Call(ctx context.Context, input string) (string, error) {
    // Windows 命令:启动 WeGame
    cmd := exec.Command("cmd", "/c", "start", "", `D:\WeGame\WeGame.exe`)

    // 执行命令
    err := cmd.Run()
    if err != nil {
       return "", fmt.Errorf("failed to open WeGame: %v", err)
    }
    return "WeGame application opened successfully", nil
}

func main() {
    // Step 1: 初始化LLM
    llm, err := openai.New(
       openai.WithModel("deepseek-reasoner"),
       openai.WithToken("你的api key"),
       openai.WithBaseURL("https://api.deepseek.com"),
    )
    if err != nil {
       log.Fatalf("Failed to initialize LLM: %v", err)
    }

    // Step 2: 初始化 tools
    agentTools := []tools.Tool{
       OpenWeGameTool{}, // 打开wegame的tool
    }

    // Step 3: 初始化agent
    agent := agents.NewOneShotAgent(
       llm,
       agentTools,
       agents.WithMaxIterations(3), // 设置最大迭代次数为3
    )
    agentExecutor := agents.NewExecutor(agent)

    // Step 4: 运行agent,并输入prompt
    prompt := "帮我打开vscode"
    answer, err := chains.Run(context.Background(), agentExecutor, prompt)
    if err != nil {
       log.Fatalf("Failed to run agent: %v", err)
    }

    // Step 5: 打印结果
    fmt.Println("Answer:", answer)
}

深入了解Agent

Agent 和 LLM 之间的通信方式:

Prompt
在初始化时,Agent 先将 Tools 的描述以及指定大模型返回的格式写在 System prompt 中。

0

在用户提问时,Agent 再将用户的提问写在 User prompt 中,连带着上面的 System prompt 一块发给LLM。
顺利的话,LLM会返回一个正确格式的信息。
但是,这里边儿 System Prompt 里的信息都是用自然语言写的,不够规范,不够严谨。
所以容易造成LLM返回一个错误格式信息,Agent 发现这个信息格式不对,会再次调用LLM,进行重试。这样会消耗很多无意义的 token。
为了避免LLM返回一个错误格式信息,我们需要对双方的交互信息交互方式进行规范处理。
为此,各大厂商推出了一个新功能——Function Calling
Function Calling
主要通过两方面来进行改进的,分别是双方的交互信息和交互方式。
  1. 交互信息:
每个tool的描述都用一个统一格式的json对象来定义
LLM给的回复也需要用一个统一格式的json对象来定义
  1. 交互方式
这些 json 的定义不再通过prompt进行交互,而是是通过专门的 API 参数。
这样一来,所有工具描述和返回信息的格式都放在相同的地方,并且按照相同的格式。
所以LLM就更容易理解我们的诉求,生成的答案就更准确。人们也可以更加有针对性的训练LLM。
但是 function calling 也有缺点,例如各大厂商的标准不统一,部分大模型不支持 function calling 等,所以其并没有完全取代prompt。
目前 function calling 和 prompt 这两种方式使用都很流行。

Agent 和 Tools 之间的通信方式:

tools实际上是一个服务,Agent通过MCP通信协议去调用他。(MCP专门用来规范Agent和Tool服务之间是怎么交互的。)
运行Tools的服务叫作MCP Server,调用它的Agent叫作MCP Client。
MCP规定了MCP Server如何和MCP Cient交互,以及MCP Server要提供哪些接口,比如说用来查询MCP Server中有哪些Tool、Tool的功能、描述、需要的参数、格式等等的接口。
MCP server既可以和Agent跑在同一台服务器上,通过标准输入输出进行交互,也可以被部署在网络上通过http进行交互。
package main

import (
    "context"
    "fmt"
    "github.com/i2y/langchaingo-mcp-adapter"
    "github.com/tmc/langchaingo/agents"
    "github.com/tmc/langchaingo/llms/openai"
)

func main() {
    ctx := context.Background()

    // 初始化 OpenAI LLM
    llm, err := openai.New()
    if err != nil {
        panic(err)
    }

    // 连接到 MCP 服务器并加载工具
    mcpURL := "https://mcp.composio.dev/your-app-id"
    tools, err := mcpadapter.LoadTools(ctx, mcpURL)
    if err != nil {
        panic(err)
    }

    // 初始化 Agent Executor
    executor, err := agents.Initialize(
        llm,
        tools,
        agents.ZeroShotReactDescription,
        agents.WithMaxIterations(3),
    )
    if err != nil {
        panic(err)
    }

    // 提出问题
    prompt := "请发送一封邮件给张三,内容是会议安排。"
    answer, err := executor.Call(ctx, map[string]any{"input": prompt})
    if err != nil {
        panic(err)
    }

    fmt.Println(answer["output"])
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值