
一只用 AI Agent 搭副业产线的程序员前 9 篇文章我们拆解了 Agent 的每个零件感知-决策循环、Function Calling、Tool 接口、ReAct、Plan-and-Execute、多 Agent 协作、记忆系统、自我反思、人机协作。现在把这些零件组装成一个完整的框架。你可以直接拿这个架构去写自己的 Agent不用从零搭。模块四知识地图┌──────────────────────┐ │ Agent 核心循环 │ │ 感知 → 决策 → 执行 │ ← 第 31 篇 └──────────┬───────────┘ │ ┌──────────────────┼──────────────────┐ │ │ │ ▼ ▼ ▼ ┌────────────────┐ ┌──────────────┐ ┌─────────────────┐ │ Function │ │ Tool 接口 │ │ 推理模式 │ │ Calling │ │ 统一设计 │ │ ReAct / PE │ │ 第 32 篇 │ │ 第 33 篇 │ │ 第 34/35 篇 │ └────────────────┘ └──────────────┘ └─────────────────┘ │ │ │ └──────────────────┼──────────────────┘ │ ┌──────────────────┼──────────────────┐ │ │ │ ▼ ▼ ▼ ┌────────────────┐ ┌──────────────┐ ┌─────────────────┐ │ 多 Agent 协作 │ │ 记忆系统 │ │ 自我反思 │ │ 第 36 篇 │ │ 第 37 篇 │ │ 第 38 篇 │ └────────────────┘ └──────────────┘ └─────────────────┘ │ ▼ ┌──────────────────────┐ │ Human-in-the-Loop │ │ 安全阀门 │ ← 第 39 篇 └──────────────────────┘通用 Agent 框架设计packageframeworkimport(contexttime)// ───────── 核心接口 ─────────// Agent 所有 Agent 的统一接口typeAgentinterface{// Run 执行任务返回最终输出Run(ctx context.Context,taskstring)(string,error)// Name Agent 名称Name()string// Describe 描述 Agent 的能力Describe()string}// Tool 工具接口来自第 33 篇typeToolinterface{Name()stringDescription()stringParameters()SchemaExecute(ctx context.Context,argsstring)Result}// Memory 记忆接口来自第 37 篇typeMemoryinterface{Remember(msg Message)Recall(querystring)stringConsolidate()// 巩固短期记忆到长期}// Planner 规划器接口来自第 35 篇typePlannerinterface{CreatePlan(goalstring,contextstring)(Plan,error)RevisePlan(plan Plan,feedbackstring)(Plan,error)}// Critic 反思接口来自第 38 篇typeCriticinterface{Review(outputstring,criteriastring)ReviewResult}// HumanGate 人机协作接口来自第 39 篇typeHumanGateinterface{RequestApproval(req ConfirmationRequest)ConfirmationResponse}// ───────── 基础类型 ─────────typeMessagestruct{Rolestringjson:roleContentstringjson:contentTimestamp time.Timejson:timestamp}typeSchemastruct{Typestringjson:typePropertiesmap[string]Propertyjson:propertiesRequired[]stringjson:required}typePropertystruct{Typestringjson:typeDescriptionstringjson:descriptionEnum[]stringjson:enum,omitempty}typeResultstruct{Successbooljson:successDatastringjson:dataErrorstringjson:error,omitempty}typePlanstruct{Goalstringjson:goalTasks[]Taskjson:tasks}typeTaskstruct{IDstringjson:idNamestringjson:nameDescriptionstringjson:descriptionDependsOn[]stringjson:depends_onActionstringjson:action}typeReviewResultstruct{HasIssuesboolIssues[]string}typeConfirmationRequeststruct{StepIDstringActionstringDetailsstringRisk RiskLevel}typeConfirmationResponsestruct{ApprovedboolCommentstring}typeRiskLevelintconst(RiskLow RiskLeveliotaRiskMedium RiskHigh RiskCritical)// ───────── Agent 配置 ─────────typeAgentConfigstruct{Namestringjson:nameSystemPromptstringjson:system_promptModelstringjson:modelTemperaturefloat64json:temperatureMaxStepsintjson:max_stepsMaxTokensintjson:max_tokensStepTimeout time.Durationjson:step_timeoutEnableReActbooljson:enable_reactEnableReflectbooljson:enable_reflectMaxReflectionsintjson:max_reflectionsAutoApproveRisk RiskLeveljson:auto_approve_risk}funcDefaultConfig()AgentConfig{returnAgentConfig{Model:deepseek-v4-pro,Temperature:0.2,MaxSteps:15,MaxTokens:8000,StepTimeout:30*time.Second,EnableReAct:true,EnableReflect:true,MaxReflections:3,AutoApproveRisk:RiskLow,}}// ───────── 通用 Agent 实现 ─────────typeGenericAgentstruct{config AgentConfig tools*ToolRegistry memory Memory planner Planner critic Critic humanGate HumanGate llmCallfunc([]Message,[]Tool)(string,[]ToolCall,error)messages[]Message}funcNewGenericAgent(config AgentConfig)*GenericAgent{returnGenericAgent{config:config,tools:NewToolRegistry(),memory:NewNoopMemory(),// 默认无记忆planner:nil,// nil 表示使用 ReAct 模式critic:nil,// nil 表示不审查humanGate:NewNoopHumanGate(),// nil 表示不等待确认}}// WithTools 注入工具集func(a*GenericAgent)WithTools(tools...Tool)*GenericAgent{for_,t:rangetools{a.tools.Register(t)}returna}// WithMemory 注入记忆系统func(a*GenericAgent)WithMemory(m Memory)*GenericAgent{a.memorymreturna}// WithPlanner 注入规划器启用 Plan-and-Execute 模式func(a*GenericAgent)WithPlanner(p Planner)*GenericAgent{a.plannerpreturna}// WithCritic 注入反思器func(a*GenericAgent)WithCritic(c Critic)*GenericAgent{a.criticcreturna}// WithHumanGate 注入人机协作func(a*GenericAgent)WithHumanGate(h HumanGate)*GenericAgent{a.humanGatehreturna}// WithLLM 注入 LLM 调用函数func(a*GenericAgent)WithLLM(fnfunc([]Message,[]Tool)(string,[]ToolCall,error))*GenericAgent{a.llmCallfnreturna}// Run 执行任务func(a*GenericAgent)Run(ctx context.Context,taskstring)(string,error){// 初始化a.messages[]Message{{Role:system,Content:a.config.SystemPrompt},}// 如果有记忆先检索相关内容ifa.memory!nil{context:a.memory.Recall(task)ifcontext!{a.messagesappend(a.messages,Message{Role:user,Content:[相关记忆]\ncontext,})}}a.messagesappend(a.messages,Message{Role:user,Content:task,})// 选择执行模式ifa.planner!nil{returna.runPlanAndExecute(ctx)}returna.runReAct(ctx)}// runReAct ReAct 模式第 34 篇func(a*GenericAgent)runReAct(ctx context.Context)(string,error){forstep:0;stepa.config.MaxSteps;step{select{case-ctx.Done():return,ctx.Err()default:}// 决策调用 LLMcontent,toolCalls,err:a.llmCall(a.messages,a.tools.ListTools())iferr!nil{return,fmt.Errorf(LLM 调用失败 (step %d): %w,step,err)}// 有工具调用 → 执行iflen(toolCalls)0{for_,tc:rangetoolCalls{// 人机协作检查ifa.humanGate!nil{risk:assessRisk(tc.Name,tc.Args)ifriska.config.AutoApproveRisk{resp:a.humanGate.RequestApproval(ConfirmationRequest{StepID:fmt.Sprintf(step_%d,step),Action:tc.Name,Details:tc.Args,Risk:risk,})if!resp.Approved{return,fmt.Errorf(步骤被用户拒绝)}}}// 执行工具result:a.tools.Execute(ctx,tc.Name,tc.Args)a.messagesappend(a.messages,Message{Role:user,Content:fmt.Sprintf(工具 %s 结果: %s,tc.Name,result.Data),})}continue}// 没有工具调用 → 最终答案output:content// 自我反思第 38 篇ifa.critic!nil{reviewResult:a.critic.Review(output,检查正确性和完整性)ifreviewResult.HasIssues{// 注入反思结果让 LLM 修正a.messagesappend(a.messages,Message{Role:user,Content:fmt.Sprintf(反思发现问题:\n%s\n请修正。,strings.Join(reviewResult.Issues,\n)),})continue}}// 记忆巩固第 37 篇ifa.memory!nil{a.memory.Remember(Message{Role:assistant,Content:output,Timestamp:time.Now(),})a.memory.Consolidate()}returnoutput,nil}return,fmt.Errorf(达到最大步数限制 (%d),a.config.MaxSteps)}// runPlanAndExecute Plan-and-Execute 模式第 35 篇func(a*GenericAgent)runPlanAndExecute(ctx context.Context)(string,error){// 先获取当前上下文contextStr:ifa.memory!nil{contextStra.memory.Recall(a.messages[len(a.messages)-1].Content)}plan,err:a.planner.CreatePlan(a.messages[len(a.messages)-1].Content,contextStr,)iferr!nil{return,fmt.Errorf(规划失败: %w,err)}// 执行 DAGresults:make(map[string]string)for_,task:rangetopologicalSort(plan.Tasks){// 收集依赖结果vardepResults[]stringfor_,depID:rangetask.DependsOn{depResultsappend(depResults,results[depID])}// 执行单个任务这里可以用 ReAct 做子任务执行taskInput:fmt.Sprintf(任务: %s\n上下文: %s,task.Action,strings.Join(depResults,\n))subAgent:NewGenericAgent(a.config)subAgent.WithTools(a.tools.ListTools()...)subAgent.WithLLM(a.llmCall)// 子任务不需要规划器用 ReActsubAgent.plannernilresult,err:subAgent.Run(ctx,taskInput)iferr!nil{return,fmt.Errorf(任务 %s 失败: %w,task.ID,err)}results[task.ID]result}// 汇总所有结果varallResults[]stringfor_,t:rangeplan.Tasks{allResultsappend(allResults,fmt.Sprintf([%s] %s: %s,t.ID,t.Name,results[t.ID]))}returnstrings.Join(allResults,\n),nil}// ───────── 辅助函数 ─────────functopologicalSort(tasks[]Task)[]Task{// 实现拓扑排序见第 35 篇// ...returntasks}funcassessRisk(toolName,argsstring)RiskLevel{// 根据工具名称和参数评估风险destructive:[]string{deploy,drop,delete,force_push,publish}for_,d:rangedestructive{ifstrings.Contains(strings.ToLower(toolName),d){returnRiskCritical}}returnRiskLow}// ───────── 空实现默认值 ─────────typeNoopMemorystruct{}funcNewNoopMemory()*NoopMemory{returnNoopMemory{}}func(n*NoopMemory)Remember(msg Message){}func(n*NoopMemory)Recall(querystring)string{return}func(n*NoopMemory)Consolidate(){}typeNoopHumanGatestruct{}funcNewNoopHumanGate()*NoopHumanGate{returnNoopHumanGate{}}func(n*NoopHumanGate)RequestApproval(req ConfirmationRequest)ConfirmationResponse{returnConfirmationResponse{Approved:true}}// ───────── Tool 注册中心来自第 33 篇 ─────────typeToolRegistrystruct{toolsmap[string]Tool}funcNewToolRegistry()*ToolRegistry{returnToolRegistry{tools:make(map[string]Tool)}}func(r*ToolRegistry)Register(t Tool){r.tools[t.Name()]t}func(r*ToolRegistry)Execute(ctx context.Context,namestring,argsstring)Result{t,ok:r.tools[name]if!ok{returnResult{Success:false,Error:fmt.Sprintf(未知工具: %s,name)}}returnt.Execute(ctx,args)}func(r*ToolRegistry)ListTools()[]Tool{vartools[]Toolfor_,t:ranger.tools{toolsappend(tools,t)}returntools}使用示例5 分钟组装一个代码审查 Agentfuncmain(){// 1. 创建 Agentagent:framework.NewGenericAgent(framework.AgentConfig{Name:CodeReviewBot,SystemPrompt:coderPrompt,Model:deepseek-v4-pro,MaxSteps:10,EnableReAct:true,EnableReflect:true,})// 2. 注册工具agent.WithTools(FileReader{BasePath:./project},CodeRunner{Timeout:5*time.Second},)// 3. 添加记忆记住项目上下文agent.WithMemory(framework.NewShortTermMemory(8000))// 4. 添加自我反思agent.WithCritic(GoCodeCritic{})// 5. 添加人机协作危险操作需要确认agent.WithHumanGate(framework.ConsoleGate{})// 6. 注入 LLMagent.WithLLM(func(msgs[]framework.Message,tools[]framework.Tool)(string,[]framework.ToolCall,error){returncallDeepSeekAPI(msgs,tools)})// 7. 运行result,err:agent.Run(context.Background(),审查 pkg/handler/ 目录下所有 Go 文件的安全漏洞输出报告)iferr!nil{log.Fatal(err)}fmt.Println(result)}框架的核心哲学是插件式组装你需要什么能力就装什么组件。简单任务 → 只装 Tools复杂推理 → 加 ReAct Memory质量控制 → 加 Critic生产环境 → 加 HumanGate批处理 → 加 Planner模块四总结地图文章核心能力关键代码量一句话31Agent 循环~100 行for LLM Tool Agent32Function Calling~150 行Schema 定义 → LLM 决策 → 你执行33Tool 接口~200 行统一接口注册即用34ReAct~180 行推理 → 行动 → 观察 → 再推理35Plan-and-Execute~200 行DAG 拓扑排序先规划再执行36多 Agent 协作~180 行一个生成一个审查互相制约37记忆系统~250 行短期窗口 长期向量存储38自我反思~180 行生成 → 审查 → 修正循环39Human-in-the-Loop~200 行高风险节点拉手刹40通用框架~300 行插件式组装5 分钟搭一个新 Agent模块四总计约 1940 行 Go 代码覆盖了从零到一搭建一个生产级 Agent 的所有核心组件。下一步模块四到此结束。你已经掌握了从底层原理到完整框架的 Agent 设计能力。模块五我们将进入Agent 的实战案例——用这个框架解决真实世界的三个问题自动化代码审查、智能数据分析、24 小时运维助手。每个案例都是完整可运行的。关注我别错过。 一只用 AI Agent 搭副业产线的程序员全平台同名虾哥不加班需要定制 AI 工具来聊聊 → lob_ai源码GitHub - lobster-bujiaban