ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

低成本搭建AI Agent:国产大模型与LangChain实战指南

低成本搭建AI Agent:国产大模型与LangChain实战指南 1. 项目概述为什么从零搭建一个AI Agent最近AI Agent的概念火得不行感觉身边搞技术的朋友都在聊。简单来说AI Agent就是一个能自主理解目标、规划任务、调用工具并执行行动的智能体它不只是个聊天机器人更像一个能帮你干活的“数字员工”。看到网上各种炫酷的演示我也心痒痒想自己动手搭一个玩玩。但一查资料发现很多方案要么对硬件要求高比如需要高端GPU要么调用商业API如GPT-4成本不菲对于个人开发者或小团队试水来说门槛不低。我的核心诉求很明确低成本、易上手、能跑通完整流程。我不想一开始就陷入复杂的架构设计和昂贵的资源消耗中。经过一番调研和折腾我最终选定了一套以国产大模型为核心、结合轻量级开源框架的方案总成本可以压到极低甚至利用免费资源就能跑起来。这篇文章我就把自己从零搭建一个基础AI Agent的完整过程、踩过的坑以及最省钱的配置方案分享出来。无论你是想学习AI Agent原理的学生还是想尝试AI应用落地的开发者这篇“接地气”的指南应该都能给你提供一条清晰的路径。2. 核心思路与方案选型为什么这么搭配搭建AI Agent核心是让大语言模型LLM具备“思考-行动”的能力。一个典型的Agent系统包含几个关键部分一个强大的“大脑”LLM一套让大脑能指挥“手脚”的框架Agent Framework以及各种可用的“工具”Tools。我的选型全部围绕“省钱”和“可行”这两个原则展开。2.1 “大脑”选型拥抱国产模型模型是Agent的核心也是成本大头。直接使用OpenAI的GPT-4系列虽然效果顶级但API调用费用对于频繁测试和长期运行来说是一笔不小的开支。因此我将目光投向了国产大模型。目前许多国产模型不仅提供了效果不错的API服务价格也相对友好甚至有针对开发者的免费额度。例如DeepSeek近期热度很高提供了丰富的API和开源模型其免费额度对于个人项目初期完全够用。通义千问、文心一言、智谱GLM等这些主流厂商的API也都提供了不同程度的免费试用包或非常低廉的计价方式。选择国产模型API的优势在于成本可控有明确的免费额度或极低的按量付费价格如每百万tokens几元人民币试错成本低。网络稳定无需考虑复杂的网络访问问题延迟通常也更低。功能适配很多国产模型针对中文场景和国内生态做了优化。注意选择模型时一定要仔细阅读其官方文档的计费规则和Rate Limit频率限制。免费额度通常有每日或每月的上限超过后可能会收费或服务中断。对于Agent这种可能需要多次调用模型的系统要合理规划调用频率。2.2 “骨架”选型轻量级开源框架有了大脑还需要一个框架来组织它的思考逻辑和行动流程。我不想从零开始写所有的状态管理和工具调用逻辑那样太耗时。因此选择一个成熟的开源Agent框架是明智之举。我最终选择了LangChain和LangGraph的组合。虽然市面上还有AutoGPT、CrewAI等但我的考虑是LangChain生态最丰富文档最完善社区活跃。它提供了连接LLM、工具、记忆等组件的标准化方式学习资源多遇到问题容易找到解决方案。LangGraph是LangChain团队推出的用于构建有状态、多智能体应用的新库。它用“图”的概念来定义Agent的执行流程非常适合描述那种“思考-行动-观察-再思考”的循环比单纯的链Chain更灵活直观。这个组合虽然不是唯一的也不是最简单的但它提供了足够的能力和灵活性并且有强大的社区支持对于学习Agent原理和构建复杂应用来说是一个很好的起点。2.3 “手脚”准备定义工具与技能Agent需要通过工具来与世界交互。工具可以是任何东西搜索网页、查询数据库、执行计算、调用某个软件接口等。为了快速演示我准备了几个最简单的工具计算器一个能进行数学运算的函数。网络搜索利用SerpAPI或DuckDuckGo搜索注意有些服务可能需要注册或付费初期可用模拟搜索代替。本地文件读写让Agent能读取或生成文本文件。定义工具的关键是用清晰的描述告诉LLM这个工具是干什么的、输入什么、输出什么。框架会将这些工具的描述作为“系统提示词”的一部分交给模型让模型学会在合适的时候调用它们。3. 环境搭建与核心依赖安装工欲善其事必先利其器。我的开发环境选择了最普遍的组合Python VSCode。下面是最小化的环境准备步骤。3.1 Python环境配置我推荐使用Python 3.10或3.11版本这是目前大多数AI库兼容性最好的版本。安装Python前往Python官网下载对应操作系统的安装包。安装时务必勾选“Add Python to PATH”这样可以在命令行直接使用python命令。验证安装打开终端Windows CMD/PowerShell, Mac/Linux Terminal输入python --version和pip --version确认版本信息正确显示。使用虚拟环境强烈推荐为了避免不同项目的包版本冲突一定要使用虚拟环境。# 安装虚拟环境管理工具如果未安装 pip install virtualenv # 创建名为 ai_agent_env 的虚拟环境 python -m venv ai_agent_env # 激活虚拟环境 # Windows: ai_agent_env\Scripts\activate # Mac/Linux: source ai_agent_env/bin/activate激活后命令行提示符前会出现(ai_agent_env)字样表示你已进入该环境。3.2 安装核心库在激活的虚拟环境中使用pip安装以下库。这里我使用了清华源加速下载。pip install langchain langchain-community langgraph -i https://pypi.tuna.tsinghua.edu.cn/simplelangchain: 核心框架。langchain-community: 包含大量社区贡献的工具、模型集成等。langgraph: 用于构建有状态的Agent图。接下来安装你选择的LLM的集成包。例如如果你用DeepSeekpip install langchain-deepseek -i https://pypi.tuna.tsinghua.edu.cn/simple如果用智谱AIpip install langchain-zhipu -i https://pypi.tuna.tsinghua.edu.cn/simple请根据所选模型的官方LangChain文档来安装对应的集成包。3.3 获取并配置API密钥国产模型的API密钥通常在其官方开放平台申请。以DeepSeek为例访问DeepSeek开放平台官网注册并登录。在控制台找到“API密钥”或类似栏目创建一个新的密钥。非常重要不要将密钥直接硬编码在代码中推荐使用环境变量管理。在项目根目录创建一个名为.env的文件。在文件中写入DEEPSEEK_API_KEY你的实际密钥在Python中安装python-dotenv库来读取pip install python-dotenv在代码开头加载环境变量from dotenv import load_dotenv load_dotenv() import os api_key os.getenv(DEEPSEEK_API_KEY)4. 核心代码实现构建一个能思考的Agent环境准备好后我们开始写代码。我将分步构建一个能使用计算器和搜索工具的简单Agent。4.1 第一步初始化LLM大脑首先我们引入必要的模块并初始化LLM。这里以DeepSeek为例。from langchain_deepseek import ChatDeepSeek from langchain_core.messages import HumanMessage, SystemMessage import os # 从环境变量读取API Key api_key os.getenv(DEEPSEEK_API_KEY) if not api_key: raise ValueError(请在 .env 文件中设置 DEEPSEEK_API_KEY) # 初始化DeepSeek聊天模型 # 注意这里使用 base_url 参数指定国内可访问的端点具体URL需查阅最新文档 llm ChatDeepSeek( api_keyapi_key, base_urlhttps://api.deepseek.com, # 示例请以官方文档为准 modeldeepseek-chat, temperature0.1, # 温度设低一些让Agent的思考更稳定、更少“胡言乱语” )关键参数解释model: 指定使用的模型名称如deepseek-chat。temperature: 控制输出的随机性。对于Agent执行任务通常设置较低的值如0.1-0.3以保证其决策的稳定性和可重复性。值越高回答越有创意但也越不可控。base_url: 有些SDK会自动配置但如果遇到网络问题可能需要手动指定一个正确的API端点地址。4.2 第二步定义工具手脚我们定义两个简单的工具一个计算器和一个模拟搜索引擎。from langchain.tools import tool from langchain_community.tools import DuckDuckGoSearchRun import math # 1. 自定义计算器工具 tool def calculator(expression: str) - str: 执行数学计算。输入一个数学表达式字符串如 3 5 * 2返回计算结果。 try: # 警告使用eval有安全风险仅用于演示。生产环境应使用更安全的解析库如 ast.literal_eval 或专门数学库。 result eval(expression, {__builtins__: None}, {math: math}) return f计算结果: {result} except Exception as e: return f计算错误: {e} # 2. 使用社区提供的搜索工具需要安装 langchain-community # 注意DuckDuckGoSearchRun 是免费的但可能不稳定或在某些区域受限。也可以使用SerpAPI付费但稳定。 search_tool DuckDuckGoSearchRun() # 将所有工具放入一个列表 tools [calculator, search_tool]实操心得tool装饰器是LangChain提供的便捷方式它能自动将你的函数转化为Agent可识别的工具格式包括生成描述、解析输入等。为工具函数编写清晰、准确的文档字符串docstring至关重要LLM就是靠这个描述来理解何时以及如何使用该工具的。对于calculator工具演示中使用了eval这在实际项目中是高危操作绝不能用于处理用户直接输入。这里仅为简化示例真实场景应替换为安全的表达式求值库。4.3 第三步创建Agent执行器组装大脑和手脚现在我们将LLM和工具绑定创建一个可以执行的Agent。这里使用LangChain的create_react_agent它实现了经典的“ReAct”Reasoning Acting范式。from langchain.agents import create_react_agent, AgentExecutor from langchain import hub # 从LangChain Hub拉取一个优化过的ReAct提示词模板 # 这个模板会指导LLM如何按“思考-行动-观察”的步骤进行 prompt hub.pull(hwchase17/react) # 创建ReAct Agent agent create_react_agent(llm, tools, prompt) # 创建Agent执行器它负责运行Agent并处理工具调用循环 agent_executor AgentExecutor( agentagent, toolstools, verboseTrue, # 设为True可以看到Agent详细的思考过程调试时非常有用 handle_parsing_errorsTrue, # 自动处理Agent输出解析错误避免程序崩溃 max_iterations5, # 限制最大迭代次数防止Agent陷入死循环 )4.4 第四步运行与测试让我们用一个需要综合运用知识和计算的问题来测试我们的Agent。# 测试问题 question “已知光在真空中的速度是每秒30万公里那么光走完1.5亿公里需要多少分钟请先搜索确认光速的准确值再进行计算。” print(f用户问题: {question}\n) print(*50) try: # 运行Agent response agent_executor.invoke({input: question}) print(\n *50) print(f最终答案: {response[output]}) except Exception as e: print(f执行过程中出现错误: {e})当你运行这段代码并将verboseTrue时会在控制台看到类似下面的输出这清晰地展示了Agent的“思考”过程 进入新的Agent执行链... 思考用户需要计算光走完1.5亿公里所需的时间单位是分钟。我需要先确认光在真空中的准确速度。 行动使用搜索工具查询“光在真空中的速度 准确值”。 观察[搜索工具返回结果光在真空中的速度是299,792,458米/秒约等于每秒30万公里。] 思考好的光速c ≈ 3.0 × 10^8 m/s。距离是1.5亿公里即1.5 × 10^11米。时间 距离 / 速度。 行动使用计算器工具计算表达式 “1.5e11 / 3.0e8”。 观察计算结果: 500.0 思考得到的时间是500秒。用户问的是多少分钟所以需要将秒转换为分钟。 行动使用计算器工具计算表达式 “500 / 60”。 观察计算结果: 8.333333333333334 思考所以光走完1.5亿公里大约需要8.33分钟。 最终答案光在真空中的速度约为每秒30万公里精确值为299,792,458米/秒。走完1.5亿公里需要约500秒换算成分钟大约是8.33分钟。这个过程完美诠释了ReAct Agent的工作流它自主地规划了“先搜索确认数据 - 再计算时间 - 最后单位转换”的步骤并正确地调用了相应的工具。5. 进阶使用LangGraph构建更可控的工作流基础的AgentExecutor已经能工作但有时我们需要更精细地控制Agent的流程或者构建多Agent协作系统。这时LangGraph就派上用场了。它允许我们用“图”来定义状态机。5.1 定义状态与节点我们构建一个简单的、具有明确循环的Agent图。from typing import TypedDict, Annotated, Sequence import operator from langchain_core.messages import BaseMessage from langgraph.graph import StateGraph, END # 1. 定义状态State # 状态是一个字典包含所有在流程中传递和更新的信息 class AgentState(TypedDict): messages: Annotated[Sequence[BaseMessage], operator.add] # 消息历史会自动追加 question: str # 用户原始问题 intermediate_steps: list # 记录工具调用和结果 # 2. 定义图节点Nodes # 节点1调用LLM决定下一步行动思考 def llm_node(state: AgentState): # 从历史消息构造提示 prompt f你是一个助手需要回答这个问题{state[question]} 你之前已经进行了这些步骤{state.get(intermediate_steps, [])} 请根据以上信息决定下一步是直接回答还是调用工具。 如果你需要调用工具请严格按照以下格式回复 行动: [工具名称] 行动输入: [工具输入] 否则直接给出你的最终答案。 # 调用LLM llm_response llm.invoke([HumanMessage(contentprompt)]) return {messages: [llm_response]} # 将LLM的回复添加到消息历史 # 节点2执行工具调用行动 def tool_node(state: AgentState): # 这里需要解析上一步LLM的输出提取出“行动”和“行动输入” # 为简化我们假设LLM的输出格式正确并直接调用对应的工具 last_message state[messages][-1].content # ... (此处省略具体的解析和工具调用逻辑实际应用需完善) # 模拟一个工具调用结果 tool_result 模拟工具调用结果计算完成。 return { intermediate_steps: [(“模拟工具”, “模拟输入”, tool_result)], # 记录步骤 messages: [HumanMessage(contentf观察: {tool_result})] # 将观察结果加入历史 } # 节点3判断是否继续路由 def decide_next_node(state: AgentState): last_message state[messages][-1].content # 简单的逻辑如果LLM的回复中包含“最终答案”则结束否则继续调用工具 if 最终答案 in last_message: return end else: return continue5.2 组装图并运行# 3. 创建图并添加节点 workflow StateGraph(AgentState) workflow.add_node(llm, llm_node) workflow.add_node(tool, tool_node) # 4. 设置边Edges和条件路由 workflow.set_entry_point(llm) # 入口是llm节点 # 从llm节点出来后根据decide_next_node函数的返回值决定下一步 workflow.add_conditional_edges( llm, decide_next_node, { continue: tool, # 如果继续去tool节点 end: END # 如果结束直接到终点 } ) # 从tool节点出来后总是回到llm节点进行下一轮思考 workflow.add_edge(tool, llm) # 5. 编译图 app workflow.compile() # 6. 运行图 initial_state AgentState( messages[], question计算10的阶乘是多少, intermediate_steps[] ) final_state app.invoke(initial_state) print(final_state[messages][-1].content)通过LangGraph我们可以清晰地定义Agent的决策循环LLM - 判断 - 工具 - LLM并且可以方便地扩展例如加入检查工具调用结果是否满意的节点、支持多个专用Agent协作等。这为构建复杂的Agent应用提供了强大的基础。6. 成本控制与优化实战对于个人项目成本控制是重中之重。以下是我总结的几个关键策略6.1 Token消耗分析与估算LLM API的计费基本都与Token数量挂钩。Token可以理解为文本的“碎片”对于中文一个字大约对应1-2个Token。输入Token (Input/Prompt Tokens)你发送给模型的提示词、历史消息、工具描述等所占的Token。输出Token (Output/Completion Tokens)模型生成的回答所占的Token。Agent场景的Token消耗特点上下文长每次调用都需要携带完整的对话历史、工具描述、系统指令导致输入Token量很大。调用频繁一个任务可能需要多次“思考-行动”循环意味着多次API调用。工具描述是开销大头每个工具详细的函数签名和描述都会占用大量Token。省钱技巧精简工具描述在保证模型能理解的前提下尽可能缩短工具的函数名和描述。避免冗长的说明。管理对话历史不要无限制地堆积历史消息。可以只保留最近几轮对话或者对历史消息进行摘要Summarization后再放入上下文。LangChain提供了多种Memory组件来帮助管理。选择性价比高的模型对于Agent的“思考”步骤不一定需要能力最强、最贵的模型。可以尝试用较小、较便宜的模型如DeepSeek的较小参数版本来承担规划任务只在需要生成最终答案时调用更强的模型。6.2 利用免费额度与本地模型最大化免费额度几乎所有国产模型平台都有免费额度。注册多个平台账号在开发测试阶段轮换使用可以极大延长免费使用时间。但要注意遵守平台的使用条款。本地模型兜底对于开发环境或对响应速度要求不高的场景可以考虑在本地部署一个轻量级开源模型如Qwen2.5-1.5B-Instruct、Phi-3-mini等。使用Ollama或LM Studio可以非常方便地在本地运行这些模型。虽然能力不如云端大模型但用于测试Agent流程逻辑、工具调用是否正常是完全可行的且零成本。你可以配置一个“回退”策略优先使用免费API额度用尽后自动切换到本地模型。6.3 监控与日志一定要养成监控开销的习惯。可以在代码中简单记录每次调用的时间、模型和预估Token数。import time from langchain.callbacks import StdOutCallbackHandler class CostTrackingCallback(StdOutCallbackHandler): def on_llm_start(self, serialized, prompts, **kwargs): self.start_time time.time() # 可以在这里估算prompts的token数需要安装tiktoken或类似库 estimated_input_tokens len(str(prompts)) // 4 # 非常粗略的估算 print(f[成本跟踪] LLM调用开始预估输入Token: {estimated_input_tokens}) def on_llm_end(self, response, **kwargs): elapsed time.time() - self.start_time # 估算生成的token数 output_text response.generations[0][0].text estimated_output_tokens len(output_text) // 4 print(f[成本跟踪] LLM调用结束耗时{elapsed:.2f}秒预估输出Token: {estimated_output_tokens}) # 在使用agent_executor时传入callback agent_executor AgentExecutor(..., callbacks[CostTrackingCallback()])更专业的做法是使用LangChain的LangSmith平台它能提供非常详细的链路追踪、Token计数和成本分析不过这是付费服务。7. 常见问题与避坑指南在搭建和调试过程中我遇到了不少典型问题这里列出来供你参考。7.1 模型不按预期调用工具症状Agent一直在“思考”说需要调用工具但输出的文本格式不符合框架的解析要求比如没有“行动”关键字导致框架无法识别并执行工具。根因提示词Prompt不够清晰或者模型本身对工具调用的指令遵循能力不足。解决方案强化提示词在系统指令中用非常明确、格式化的例子告诉模型应该如何响应。参考hwchase17/react这个提示词模板它就是专门为ReAct范式优化的。选择适合的模型有些模型在工具调用/函数调用Function Calling方面进行了专门优化效果更好。可以查阅模型的官方文档看是否强调此功能。启用handle_parsing_errors就像我们之前代码中设置的这个参数能让AgentExecutor在解析失败时尝试让模型修正错误而不是直接崩溃。7.2 Agent陷入死循环症状Agent不停地调用同一个工具或者在不同的工具间来回切换始终无法得出最终答案。根因任务目标不清晰或者工具返回的结果无法让模型推导出下一步。解决方案设置max_iterations这是最重要的安全阀。务必设置一个合理的上限如10次防止无限循环消耗大量Token和费用。优化工具反馈确保工具返回的结果是清晰、结构化、信息丰富的。如果工具返回错误或模糊信息模型很可能无法正确理解。在提示词中加入反思指令例如在每次行动后提示模型“检查当前结果是否已足够回答问题如果足够请给出最终答案”。7.3 API调用失败与Token失效症状出现类似token exchange failed、status 403 forbidden、your access token could not be refreshed等错误。根因API密钥错误或失效密钥填写错误、密钥被重置、免费额度用完。网络或区域限制某些API端点可能对访问IP有区域限制。请求格式或频率问题发送的请求不符合API要求或触发了频率限制Rate Limit。排查步骤检查密钥确认环境变量中的密钥是否正确并前往模型平台的控制台查看密钥状态、剩余额度。检查base_url确认代码中初始化模型时使用的base_url是否正确特别是对于某些需要特定域名的国产模型。查看完整错误信息Python的报错信息通常很长仔细阅读后半部分里面往往有服务器返回的具体错误原因。加入重试机制对于网络波动或暂时的Rate Limit可以在代码中加入简单的重试逻辑如使用tenacity库但重试间隔要合理避免加重服务器负担。7.4 本地环境配置问题Python包冲突这是最常见的问题。langchain及其生态包更新很快不同版本间可能存在接口变化。解决方案坚持使用虚拟环境为每个项目创建独立的虚拟环境这是避免冲突的黄金法则。使用requirements.txt锁定版本在项目稳定后运行pip freeze requirements.txt将当前环境的所有包及版本号导出。其他人或你在新环境部署时使用pip install -r requirements.txt即可复现完全一致的环境。仔细阅读错误信息安装或运行时出错首先看错误信息的最后几行它通常会明确指出是哪个包、哪个版本不兼容。搭建这个AI Agent的过程更像是一次对现有开源生态和云服务的“组合式创新”。最大的体会是不要一开始就追求完美和强大。用最小的成本、最简单的工具链跑通核心流程看到Agent真的能“动起来”这个正反馈至关重要。之后再根据具体需求逐步替换更强的模型、增加更复杂的工具如连接数据库、调用外部API、设计更优雅的工作流用LangGraph实现。这套以国产模型开源框架为基础的方案无疑为个人开发者探索AI Agent世界打开了一扇低成本、可实操的大门。
返回列表