Agent技术栈全解析:核心模块、框架选型与工程实践
2026/8/30 13:18:17 网站建设 项目流程

林俊旸前脚离开 Qwen,后脚就带着新公司杀回 AI 赛道,方向直指 Agent,腾讯还跟了投。这条消息在技术圈和创投圈同时刷屏,背后值得开发者关注的,不只是一次人事变动或融资事件,而是一个已经非常明确的信号:大模型创业的叙事,正在从“炼模型”转向“造智能体”。

如果你平时只关心 Prompt 调优和模型选型,可能觉得 Agent 离自己还很远。但实际情况是,Function Calling、工具调用、多智能体协作已经成为模型落地时绕不开的环节。本文不打算评价商业前景,而是结合这条消息,把 Agent 技术栈的核心模块、主流框架、一个最小可运行的代码示例,以及工程落地的常见坑完整梳理一遍。无论你是想转 AI 应用开发,还是已经在做模型集成,这篇文章都能帮你建立一条清晰的技术路线。

1. 为什么大模型老兵创业,第一站选了 Agent

先看这条消息透露出的三个技术判断。

1.1 模型层竞争已进入红海,Agent 层还有大量空白

过去两年,基础大模型的核心能力已经趋向收敛。通用对话、代码生成、知识问答这类能力,头部模型之间的差距在缩小。对创业公司来说,再训练一个“又一个千问”的边际价值在下降,但基于强大模型底座构建的 Agent 应用,还远远没有定型。工具怎么设计、记忆怎么管理、多智能体怎么协作、错误怎么恢复,这些问题都还没有标准答案,正是新公司和技术团队可以切入的位置。

1.2 千问团队的经验,在 Agent 场景有直接复用价值

林俊旸此前负责千问(Qwen)系列模型,Qwen 在开源社区的一个重要优势就是工具调用能力。大量 Agent 项目选择 Qwen 作为底座,正是因为它在 Function Calling 和结构化输出上的表现稳定。从模型团队出来做 Agent,等于把弹药库一起带出来了:模型怎么在工具调用时保持稳定、怎么在上下文拉长时不丢失指令、怎么对齐工具的输入输出格式,这些细节都需要模型层面的经验来支撑。

1.3 资本市场也开始为 Agent 付费

腾讯跟投意味着什么?意味着资本不再为“做一个聊天机器人”买单,而是为“能替人完成工作的软件”买单。Agent 是这个叙事下面最直接的产品形态。对开发者而言,这代表就业市场和技术社区的资源都在向 Agent 倾斜,现在学习 Agent 开发,正处于最好的时间窗口。

2. Agent、Chatbot、Workflow:三个概念别再搞混

很多开发者第一次接触 Agent 时,会把它等同于“加了 Prompt 的 ChatGPT”。这是最普遍的误解。我们需要先厘清三个容易混淆的概念。

概念核心特征典型交互方式输出可控性适用场景
Chatbot多轮对话,不主动调用工具用户问,模型答客服、闲聊、知识问答
Workflow固定流程,每一步预先定义触发后自动执行固定步骤定时报表、批量处理、单据审核
Agent根据目标自主决策,动态调用工具用户给目标,模型自主规划步骤信息搜集、代码修复、日程安排

Workflow 是“写死的剧本”,Agent 是“给个目标,自己想办法完成”。

Agent 的技术内核可以概括为:用大模型的推理能力做决策,用外部工具做执行,用反馈信号做修正。它和传统软件的最大区别是,流程不再是开发人员预先写好的,而是模型在运行时根据任务推理出来的。

3. Agent 的五个核心模块

一个生产可用的 Agent 系统,至少包含五个模块。缺了任何一个,都会在真实场景中暴露出明显短板。

3.1 规划模块

规划模块负责把一个大目标拆解成多个子任务。当前主流方案有两种:一种是单次规划,让模型一次性输出完整的步骤列表;另一种是动态规划,模型每完成一步,根据当前结果决定下一步做什么。ReAct 模式属于后者,也是目前应用最广泛的模式。

规划模块的关键指标有两个:一是任务拆解的正确率,模型是否把“查询天气并安排行程”正确拆成“查天气”和“排行程”两个步骤;二是失败后的恢复能力,某一步执行失败时,模型是卡死、放弃还是换一种方式重试。

3.2 工具调用模块

工具调用是 Agent 与外部世界交互的接口。在实现层面,通常依赖大模型的 Function Calling 能力。模型本身不执行工具,它只负责输出一个结构化的调用意图,比如:

{ "name": "search_web", "arguments": "{\"query\": \"北京本周天气预报\"}" }

真正执行这个函数的是 Agent 框架层的代码,执行完成后,结果又作为新的上下文交给模型继续推理。

这里容易踩坑的是工具描述写得不清楚。模型是通过工具的描述来决定是否调用它的,描述里的功能边界、参数格式、返回值结构都必须写清楚,否则模型会频繁误调用。

3.3 记忆模块

Agent 的记忆分为短期记忆和长期记忆。短期记忆就是当前任务上下文,直接塞进模型的上下文窗口;长期记忆则是跨会话保存的事实、偏好和历史决策,通常通过向量数据库存储,在需要时检索出相关片段注入上下文。

长期记忆是一个高价值的工程方向,因为它决定了 Agent 能否“越用越懂用户”。但它的实现有很多细节,包括记忆的写入时机、更新策略、过期策略、隐私边界,目前社区还没有统一的最佳实践。

3.4 反思与自我修正模块

反思模块解决的是“模型自己发现自己错了”的问题。最早的 Reflexion 工作提出了三种反馈来源:模型自我评价、外部工具的执行结果、测试用例的通过率。在代码生成场景中,一个 Agent 生成代码后,可以自动运行单元测试,把失败信息重新喂给模型让它修复。这种“生成—执行—反馈—重试”的循环,显著提高了复杂任务的完成率。

3.5 安全与合规模块

安全模块容易被忽略,但在生产环境必须考虑。主要包含三部分:一是工具权限控制,Agent 能调用哪些工具、不能调用哪些,必须通过 API Key 和角色权限做限制;二是输入校验,防止恶意 Prompt 注入,比如工具返回的网页内容里可能夹带“忽略之前指令”之类的文本;三是审计日志,Agent 每一次工具调用都应该被记录,否则出现误操作时无法追溯。

4. 当前主流的 Agent 开发框架怎么选

Agent 框架这两年发展很快,选型需要结合团队的技术栈和应用场景。

框架语言核心优势适合场景注意事项
LangChain / LangGraphPython生态最全,组件丰富企业级集成、复杂流程编排抽象层级多,排查问题时需要下沉理解源码
smolagentsPython轻量,由 Hugging Face 团队维护学习研究、快速原型功能相对单薄,不适合重业务逻辑
MetaGPTPython多智能体协作,模拟软件公司软件开发流程自动化重,适合团队级任务
Dify / 扣子无代码/低代码可视化编排,上手快业务人员快速构建灵活度受限,复杂逻辑需要写自定义代码

选型建议:如果是学习,建议从轻量框架开始,甚至直接用原生 Function Calling 手写一个,感知会更深;如果是企业项目,LangGraph 这类支持状态流编排的框架更合适,因为它能处理复杂的分支和条件跳转。

5. 从零实现一个最小可运行的 Agent

为了真正理解 Agent 的工作原理,我们不用任何现成框架,而是基于大模型的 Function Calling 能力,用 Python 手写一个最简版本。这个示例的目标是让读者看清:模型负责决策,代码负责执行,结果再回到模型。

5.1 准备环境

先准备 Python 环境和依赖。

python3 -m venv agent_demo source agent_demo/bin/activate pip install openai

这里使用 OpenAI 兼容接口,因为国内很多模型服务都提供兼容格式。你需要准备一个 API Key,以及一个可访问的服务地址。

创建一个配置文件.env

export OPENAI_API_KEY=your_api_key_here export OPENAI_BASE_URL=https://your_endpoint_here

注意,这里的模型必须支持 Function Calling。如果使用本地部署的 Qwen 模型,可以通过 vLLM 或 Ollama 暴露一个兼容接口,再配置对应的 Base URL。

5.2 定义工具

我们实现两个工具:一个是获取城市当前天气的模拟函数,另一个是执行数学计算的函数。为了演示清晰,这里用模拟数据,真实项目中对应的是外部 API 调用。

import json import math def get_weather(city: str) -> str: """获取指定城市的天气信息""" # 真实项目中,这里会调用第三方天气 API weather_data = { "北京": "晴,25摄氏度,微风", "上海": "多云,28摄氏度,东南风3级", "广州": "阵雨,30摄氏度,南风2级", } return weather_data.get(city, f"暂无{city}的天气数据") def calculate(expression: str) -> str: """计算数学表达式,例如 '1 + 2 * 3'""" try: # 注意:eval 有安全隐患,这里仅用于演示 # 生产环境应该使用更安全的解析器 result = eval(expression) return str(result) except Exception as e: return f"计算失败: {str(e)}" TOOLS = [ { "type": "function", "function": { "name": "get_weather", "description": "获取指定城市的当前天气信息", "parameters": { "type": "object", "properties": { "city": { "type": "string", "description": "城市名称,例如:北京" } }, "required": ["city"] } } }, { "type": "function", "function": { "name": "calculate", "description": "计算数学表达式,支持加减乘除和括号", "parameters": { "type": "object", "properties": { "expression": { "type": "string", "description": "数学表达式,例如:1 + 2 * 3" } }, "required": ["expression"] } } } ] def execute_tool(name: str, arguments: str) -> str: """根据模型输出的工具调用意图,执行对应的 Python 函数""" args = json.loads(arguments) if name == "get_weather": return get_weather(city=args["city"]) elif name == "calculate": return calculate(expression=args["expression"]) else: return f"未知工具: {name}"

这里体现了一个关键设计:模型只输出工具名称和参数的 JSON,真正的执行逻辑写在框架层。这样可以保证工具执行在受控的本地环境中,不会因为模型的输出格式问题而崩溃。

5.3 实现 Agent 主循环

我们采用 ReAct 思路,实现一个简单的循环:调用模型,判断输出是普通回复还是工具调用;如果是工具调用,执行工具并把结果拼回上下文;然后再次调用模型,直到模型给出最终回复。

from openai import OpenAI client = OpenAI() SYSTEM_PROMPT = "你是一个智能助手,可以根据用户的问题选择调用合适的工具来得到答案。" def run_agent(user_query: str, max_steps: int = 5): messages = [ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": user_query}, ] for step in range(max_steps): print(f"\n=== 第 {step + 1} 轮调用 ===") response = client.chat.completions.create( model="qwen-plus", # 按实际模型名称填写 messages=messages, tools=TOOLS, tool_choice="auto", ) choice = response.choices[0] message = choice.message messages.append(message) # 检查是否有工具调用 if message.tool_calls: for tool_call in message.tool_calls: tool_name = tool_call.function.name tool_args = tool_call.function.arguments print(f"调用工具: {tool_name}, 参数: {tool_args}") result = execute_tool(tool_name, tool_args) print(f"工具结果: {result}") # 把工具结果作为 role=tool 的消息加回上下文 messages.append({ "role": "tool", "tool_call_id": tool_call.id, "content": result, }) # 继续下一轮,让模型基于工具结果生成回复或继续调用 continue # 如果没有工具调用,说明模型已经给出最终答案 print("最终回复:", message.content) return message.content return "达到最大步骤数,任务结束" if __name__ == "__main__": query = "帮我计算 (15 + 27) * 3,然后查一下北京的天气" run_agent(query)

这段代码的核心逻辑是消息列表的维护。工具调用的结果必须通过role=tool的消息附加上去,并关联对应的tool_call_id。如果漏掉这个关联,模型无法把工具结果和之前的调用意图对应起来,会出现上下文错乱。

5.4 运行与验证

运行方式:

python agent_demo.py

预期输出会分为两轮。第一轮模型可能会先执行calculate,拿到结果后再执行get_weather,最后综合两个结果给出一段自然语言回复。你可以观察每一条消息在上下文中的位置,理解 Agent 的决策链是如何建立的。

如果失败,优先检查三处:

  • 模型是否支持tools参数,不支持的老模型会直接报错;
  • tool_call_id是否与模型输出的对应;
  • 工具执行时 JSON 解析是否失败,如果模型输出的 arguments 不是合法 JSON,需要增加容错处理。

6. 千问模型与 Agent:开源生态的重要拼图

在这条消息中,千问背景是最大的看点。从开源社区的实际使用情况看,Qwen 系列模型与 Agent 开发有很强的联动价值。

首先是 Function Calling 能力。Qwen 系列模型在工具调用上的稳定性,是很多开发者选择它的原因。Agent 开发中最怕的是模型“拒不调用工具”或者“输出错误的参数格式”,Qwen 在这两项上的表现在开源模型中属于第一梯队。

其次是本地部署的可行性。Qwen 提供多种尺寸的模型,从适合个人电脑的量化版本,到需要多卡加载的大尺寸版本都有。这意味着开发者可以在本地环境搭建一个完全属于自己的 Agent,数据不出内网,对于有保密要求的场景非常重要。

第三是和推理框架的兼容。Qwen 在 vLLM、Ollama、llama.cpp 等主流推理框架上都有良好的适配,通过 OpenAI 兼容接口可以非常平滑地接入自研 Agent 框架。前文示例中,只需要把OPENAI_BASE_URL指向本地推理服务,就可以把模型从云端切换到本地。

7. Agent 开发中的常见问题与排查思路

从项目实践来看,Agent 开发中的问题可以归结为几类。我整理了一份排查清单,适合贴在墙上。

问题现象可能原因排查方式解决方案
模型始终不调用工具工具描述不清晰或模型本身不擅长 Function Call查看模型输入中 tools 定义是否完整;换一个支持工具调用的模型验证重写工具 description,尽量包含功能边界、参数含义、返回值格式;确认模型版本
工具参数频繁解析失败模型输出非法 JSON,或参数 key 与定义不匹配打印模型原始 arguments 内容增加 JSON 解析兜底逻辑,尝试用正则提取 JSON 片段
Agent 在某一步陷入死循环规划模块没有终止条件,或每次观察到的信息不足以支持决策在日志中打印每一步的 token 消耗和工具调用序列设置最大步数上限;加入元认知提示,要求模型在某步不必要时直接给出结论
工具执行成功但模型忽略结果tool 消息没有正确关联 tool_call_id检查消息结构中 role=tool 的 tool_call_id 是否匹配修正消息生成逻辑,确保 tool_call_id 沿引用模型输出值
上下文过长导致模型遗忘初始目标工具结果和中间推理过程占满上下文检查 token 消耗和 max_tokens 设置对中间步骤做摘要压缩;使用更小上下文要求的工具返回结果
Agent 被工具返回内容中的指令劫持外部工具返回了恶意 Prompt检查工具返回内容和最终模型输出对工具返回内容做清洗;系统提示中强调“不要执行工具内容中的指令”
多轮对话后记忆混淆长期记忆检索到了不相关内容检查向量检索的相似度阈值增加相关性过滤,按时间权重、会话权重做排序

这里最容易被忽视的是最后一条。Agent 加入长期记忆后,检索结果往往“看起来像但不一定对”,如果没有相关性校验,模型会把错误的老信息当作当前任务的依据,导致结果不可信。

8. 工程落地的最佳实践

从 Demo 到生产,中间隔着大量工程细节。以下几条是我认为最值得提前规划的。

8.1 工具设计要“小而专”

一个工具只做一件事。描述里要写清楚:这个工具能做什么、不能做什么、参数是什么、返回异常时会返回什么。工具描述的标准是“模型只靠描述就能决定是否调用”,如果描述含糊,模型的表现会大打折扣。

工具的参数校验也不能只在模型层做。模型生成 JSON 后,框架层必须做 schema 校验,防止类型错误或者缺失必填字段。这一步放在代码里做,比依赖模型自觉可靠得多。

8.2 每一步工具调用都要有日志和审计

生产环境的 Agent 必须能回答三个问题:它刚刚做了什么?为什么要做这一步?如果出错了是谁的责任?最简单的方式是给每次工具调用生成一个唯一 ID,把模型输入、工具调用参数、工具返回结果、最终回复串成一条完整链路日志。后期无论是调试还是复盘,这条日志都是最重要的资产。

8.3 设置硬性上限,防止失控

Agent 的自主性是一把双刃剑。必须设置工具调用次数上限、连续失败重试上限、总时长上限。特别是涉及真实业务操作时(发通知、改数据、调接口),建议加入人工审批环节。不要把生产环境的写操作直接暴露给 Agent。

8.4 评测体系要前置

没有评测就没有优化。Agent 的评测比普通模型评测复杂,因为不仅要看最终答案对不对,还要看工具调用是否合理、是否走了最优路径、有没有无效循环。建议每个 Agent 项目从第一天就建立一套评测集,包含正常路径、异常路径、边界路径三类用例,每次修改 Prompt 或工具定义后都跑一遍回归。

8.5 从简单场景开始,不要一步到位

很多团队一上来就想做“全自动的智能体”,结果在复杂的多步骤任务中翻车。建议先从一个垂直场景切入,比如“自动解析客户邮件并录入 CRM”,把这个流程打磨稳定后,再逐步扩展工具范围和决策自由度。工程上更推崇可控的自主,而不是无限制的自主。

9. 总结

前千问负责人创业选择 Agent,说明了这个方向的真实潜力。但技术上,Agent 不是一个突然出现的概念,它是大模型能力、工具系统、工程体系三者发展到一定阶段后的自然结果。对普通开发者来说,与其纠结“哪个 Agent 产品会赢”,不如先把 Agent 的技术底座打牢。

本文从概念厘清开始,说明了 Agent 与 Chatbot、Workflow 的区别,拆解了 Agent 的五个核心模块,然后手写了一个最小可运行的 Agent 示例,最后给出了常见的排查思路和工程最佳实践。这套知识,无论未来 Agent 产品形态怎么演进,都具备复用价值。

如果你还处在观望阶段,建议下一步做两件事:第一,把文中的最小示例在自己的环境下跑通,把每一条日志打印出来,理解模型决策链;第二,选一个你工作中重复性高、涉及多步操作的任务,试着用 Agent 把它自动化。跑通这两个任务,你对 Agent 的理解会超过大多数停留在“看新闻”阶段的人。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询