第8节:理解Agent的设计思想

今天我们要来深入探讨一下Agent(智能体)的设计思想和实现原理。作为一个程序员,最好的学习方式就是通过代码来理解概念,所以我们直接从Go代码开始,深入剖析Agent的内部工作机制。

首先,让我们看看代码,这其实是一个非常典型的Agent应用:

func main() {
    ctx := context.Background()
    llm := DoubaoOpenai()
    //定义好工具
    serpapiTool, err := serpapi.New(serpapi.WithAPIKey(Serpapi))
    if err != nil {
        return
    }
    //calc
    calculator := new(tools.Calculator)

    tools := []tools.Tool{
        serpapiTool, calculator,
    }
    //agent
    agent := agents.NewExecutor(agents.NewOneShotAgent(llm, tools))
    res, err := chains.Run(ctx, agent, "你好,请问 it资源网的网站有哪些 ? ")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(res)
}

这段代码虽然简短,但已经完整地体现了Agent的核心设计思想。我们可以把它分解为几个关键部分:

  1. 语言模型(LLM) - Agent的大脑
  2. 工具集(Tools) - Agent的手脚
  3. Agent执行器(Executor) - Agent的决策中枢
  4. 任务执行 - Agent的工作流程

Agent的核心:语言模型(LLM)

首先初始化了一个llama3.2的大语言模型: 

func DoubaoOpenai(t *testing.T) *ollama.LLM {
    llm, err := ollama.New(
        ollama.WithModel("llama3.2"), // 指定使用的模型
    )
    if err != nil {
        log.Fatal(err)
    }

    return llm
}

这个LLM就是Agent的"大脑",负责理解自然语言、进行推理和生成回复。你可以把它想象成Agent的思维中枢,但它本身并不能直接执行具体任务。

Agent的"手脚":工具系统

Agent的强大之处在于它不仅能思考,还能通过工具来执行具体任务。在代码中,定义了两个工具:

// 搜索工具
serpapiTool, err := serpapi.New(serpapi.WithAPIKey(Serpapi))
// 计算器工具
calculator := new(tools.Calculator)

tools := []tools.Tool{
    serpapiTool, calculator,
}

工具的本质:统一接口

在langchaingo中,所有工具都实现了统一的接口:

type Tool interface {
    Name() string
    Description() string
    Call(ctx context.Context, input string) (string, error)
}

这个设计非常精妙,它意味着Agent可以使用任何实现了这个接口的工具。让我们看看两个具体工具的实现:

func (c Calculator) Description() string {
    return `Useful for getting the result of a math expression. 
    The input to this tool should be a valid mathematical expression that could be executed by a starlark evaluator.`
}

func (c Calculator) Name() string {
    return "calculator"
}

搜索引擎工具:

func (t Tool) Name() string {
    return "GoogleSearch"
}

func (t Tool) Description() string {
    return `
    "A wrapper around Google Search. "
    "Useful for when you need to answer questions about current events. "
    "Always one of the first options when you need to find information on internet"
    "Input should be a search query."`
}

这些描述信息非常重要,因为它们会被注入到Agent的提示词中,帮助LLM理解何时以及如何使用这些工具。
Agent的"灵魂":OneShotAgent
在你的代码中,最关键的一行是:

agent := agents.NewExecutor(agents.NewOneShotAgent(llm, tools))

这里创建了一个OneShotAgent,它是Agent的核心实现。OneShotAgent的职责是:

  1. 接收用户输入
  2. 根据输入和可用工具决定下一步行动
  3. 生成最终答案或工具调用指令
 
OneShotAgent内部使用了一个LLMChain,这是整个Agent的决策核心。它会将用户输入、工具描述、历史交互等信息组合成一个完整的提示词,然后让LLM进行推理。
Agent的"执行者":Executor
NewExecutor创建了一个执行器,负责管理Agent的整个执行流程:
func (e *Executor) Call(ctx context.Context, inputValues map[string]any, _ ...chains.ChainCallOption) (map[string]any, error) {
    inputs, err := inputsToString(inputValues)
    if err != nil {
        return nil, err
        }
    nameToTool := getNameToTool(e.Agent.GetTools())

    steps := make([]schema.AgentStep, 0)
    for i := 0; i < e.MaxIterations; i++ {
        var finish map[string]any
        steps, finish, err = e.doIteration(ctx, steps, nameToTool, inputs)
        if finish != nil || err != nil {
            return finish, err
        }
    }
    // ...
}

Executor的工作流程是一个循环过程:

  1. 接收输入
  2. 调用Agent的Plan方法制定计划
  3. 如果需要使用工具,就执行工具调用
  4. 将工具执行结果作为观察(Observation)反馈给Agent

重复这个过程,直到Agent认为任务完成

 

Agent的工作流程:一个完整的例子
让我们通过你的示例来理解Agent的完整工作流程。当你执行:

res, err := chains.Run(ctx, agent, "你好,请问 it资源网的网站有哪些 ? ")

会发生以下步骤:

 
    1. 输入处理:Executor接收问题"你好,请问 it资源网的网站有哪些 ?"
    2. 计划制定:OneShotAgent使用LLM分析问题,由于这是关于网络资源的问题,它决定调用GoogleSearch工具。
    3. 工具调用:Agent生成类似这样的指令:
         Action: GoogleSearch
         Action Input: it资源网的网站有哪些

       

    4. 执行搜索:Executor调用SerpAPI工具执行搜索。
    5. 结果反馈:搜索结果被作为Observation返回给Agent。
    6. 生成答案:Agent基于搜索结果生成最终回答
    7. 返回结果:通过chains.Run函数将最终答案返回。

Agent的智能之处:ReAct模式
  Agent的智能来源于ReAct模式(Reasoning + Action)。它不是简单地回答问题,而是按照"思考-行动-观察-再思考"的循环来解决问题。这种模式让Agent能够处理复杂的、需要多步骤才能解决的任务。
  在代码中,Agent面对"it资源网的网站有哪些"这个问题时,它会:
  1.   思考:这是一个需要网络搜索的问题
  2.   行动:调用GoogleSearch工具
  3. 观察:获取搜索结果
  4. 思考:基于搜索结果生成回答
  5. 行动:返回最终答案
总结
通过分析你的代码,我们可以看到Agent的设计思想非常优雅:
模块化设计:LLM、工具、执行器各司其职
统一接口:所有工具都遵循统一的接口规则
循环执行:通过迭代执行实现复杂任务处理
开放扩展:可以轻松添加新的工具
这种设计让Agent既保持了足够的智能,又具备了强大的可扩展性。它就像一个聪明的项目经理,知道什么时候该自己思考,什么时候该调用专家(工具)来解决问题。
Agent技术正在快速发展,而你已经在使用它了!随着你对这套系统的深入理解,相信你能构建出更加强大和智能的应用。
 
 
posted @ 2025-09-24 16:27  phpwyl  阅读(18)  评论(0)    收藏  举报