ARTICLE DETAIL

资讯详情

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

AI Agent 入门:从大模型到工具调用的完整实践

AI Agent 入门:从大模型到工具调用的完整实践 AI Agent 是 2026 年前后 AI 应用开发中最值得花时间掌握的方向之一。很多人第一次接触这个概念时会误以为它只是给大模型加一个聊天窗口或者把 Prompt 写得再长一点。实际项目里的 AI Agent 要复杂得多它需要自主拆解任务、决定调用哪些工具、读取工具返回的结果、在失败时修正策略最后给用户一个可验证的答案。这篇文章面向零基础读者目标不是带你背概念而是先讲清楚 Agent 的运行机制再通过一个最小可运行案例和一个日志分析小项目把从环境准备到问题排查的完整链路走一遍。1. 先理解 AI Agent它和普通模型应用的区别在哪里1.1 一个通俗例子模型只会回答Agent 会完成事情直接用大模型接口写一个聊天程序本质上是一个“输入文本、输出文本”的映射过程。用户问“现在几点了”模型如果没有联网能力只能凭训练数据里的时间规律猜一个答案用户问“帮我统计今天生产环境 ERROR 日志数量”模型连日志存在哪里都不知道更不可能自己去查询。AI Agent 解决的就是这个问题。可以把 AI Agent 理解成以大语言模型为决策核心通过规划任务、调用外部工具、读取外部数据、执行动作并观察结果来完成一个相对完整目标的程序。它不只是输出一句话而是真正把“查时间”“查日志”“发通知”“改配置”这些动作串起来。这在工程上的含义非常明确模型负责理解用户意图并生成行动计划。程序负责执行计划中的具体动作。工具返回结果后模型再根据结果决定下一步动作。整个过程循环进行直到完成目标或达到限制条件。1.2 Agent 的四个核心能力规划、记忆、工具、执行在学习任何 Agent 框架之前先记住这四个核心能力它们也是你分析项目时最常用的拆分维度。能力通俗解释技术实现容易出现的问题规划 Planning把一个目标拆解成多个步骤Prompt 约束、任务图、子 Agent 调度步骤过多、规划不收敛记忆 Memory记住对话历史、中间结果和偏好上下文、向量库、短期与长期记忆上下文膨胀、记忆过期工具 Tools访问外部世界的能力Function Calling、API 封装、外部服务参数定义错误、权限过大执行 Execution真正运行动作并获取结果代码调用、消息发送、文件读写工具返回格式不符合预期很多 Agent 项目之所以不稳定不是因为模型不够强而是因为工具定义不清晰、记忆管理混乱、循环控制缺失。这四个能力中工具往往是最先要解决的因为如果没有工具Agent 就退化成普通对话机器人。1.3 从模型 API 到 Agent 循环Reasoning-Act-Observation可以把 Agent 的运行过程理解成一个循环学术上常写成 Reasoning-Act-Observation也就是“思考、行动、观察”的往复。每一次循环中模型根据当前状态决定下一步动作。程序解析模型输出执行对应工具。工具返回结果作为新观察加入上下文。模型继续思考直到给出最终答案。这个循环可以用伪代码表示while not task_finished: decision llm.generate(messages) if decision.has_tool_call(): result execute_tool(decision.tool_call) messages.append(result) else: answer decision.text task_finished True这段代码虽然简单但它概括了 Agent 的最小运行模型。实际项目会在这个循环基础上加记忆窗口、循环上限、错误恢复、日志追踪和权限控制。理解这个循环比背某个框架的 API 重要得多。2. 零基础学习路线和环境准备不要一上来就追框架2.1 先学什么再学什么一条更稳的路线很多初学者容易犯两个错误一是上来就学 LangChain 或某个低代码平台结果只学会拖拽节点不懂底层机制二是花大量时间研究多个框架结果哪个都没跑通。更稳妥的做法是先手写一遍最小 Agent再使用框架提高效率。推荐的学习顺序如下Python 基础变量、函数、异常处理、JSON 操作。大模型 API 调用理解 messages 结构、system 与 user 角色的区别。Function Calling学习如何定义工具、解析 tool_calls。手写一个最小 Agent 循环不依赖框架。学习一个编排框架的典型用法。做一个完整小项目例如日志分析 Agent。学习评估和调优如何衡量 Agent 是否“靠谱”。每完成一个阶段都要有明确的可验证结果。例如阶段 2 的完成标志是能通过 API 收到一个非空回复阶段 3 的完成标志是让模型成功请求一次加法工具并返回计算结果。2.2 Python 环境和依赖版本确认学习环境不需要太复杂Python 3.10 以上即可。建议单独建一个虚拟目录避免和系统 Python 环境互相干扰。python --version python -m venv agent-env source agent-env/bin/activate # Windows 下使用 agent-env\Scripts\activate pip install --upgrade pip pip install openai python-dotenv requests这里的依赖含义如下openai调用大模型接口兼容多个服务商的 OpenAI 风格接口。python-dotenv读取 .env 文件方便保存 API Key 和 Base URL。requests调用 Elasticsearch 等外部 HTTP 接口。如果原始环境没有明确给出版本落地前先运行pip show openai查看版本避免因为 API 变化导致示例代码不兼容。2.3 项目目录结构和环境变量建议用一个目录管理整个学习项目结构如下agent-learning/ ├── .env ├── requirements.txt ├── 01_basic_chat.py ├── 02_tool_call.py └── agent_utils/ ├── __init__.py └── es_client.py.env 文件示例OPENAI_API_KEYsk-xxxx OPENAI_BASE_URLhttps://api.example.com/v1 MODEL_NAMEgpt-4o-mini ES_URLhttp://localhost:9200 ES_USERreadonly_user ES_PASSWORDreadonly_password注意不要把包含 .env 的目录直接提交到 Git。在生产环境更应该使用密钥管理服务或容器环境的 Secret 机制而不是把明文密钥放在代码里。3. 实现一个最小可运行 Agent工具调用是 Agent 的入口3.1 最小闭环让 Agent 同时完成时间查询和数字计算下面这个例子不依赖任何 Agent 框架只使用 OpenAI 风格的 Chat Completions 接口。目标是让模型识别两个工具获取当前时间、计算两数之和。这样能完整展示 Function Calling 的核心链路。import json import os from datetime import datetime from dotenv import load_dotenv from openai import OpenAI load_dotenv() client OpenAI( api_keyos.getenv(OPENAI_API_KEY), base_urlos.getenv(OPENAI_BASE_URL), ) TOOLS [ { type: function, function: { name: get_current_time, description: 获取当前本地时间, parameters: { type: object, properties: {}, required: [] } } }, { type: function, function: { name: add, description: 计算两个数字的和, parameters: { type: object, properties: { a: {type: number, description: 第一个数字}, b: {type: number, description: 第二个数字} }, required: [a, b] } } } ] def call_tool(name, arguments): args json.loads(arguments) if name get_current_time: return {time: datetime.now().isoformat()} if name add: return {result: args[a] args[b]} return {error: funknown tool {name}} def run_agent(user_message): messages [{role: user, content: user_message}] for step in range(5): resp client.chat.completions.create( modelos.getenv(MODEL_NAME), messagesmessages, toolsTOOLS, ) msg resp.choices[0].message if msg.tool_calls: # 先把模型产生的 tool_calls 消息放入历史 messages.append(msg) for tc in msg.tool_calls: result call_tool(tc.function.name, tc.function.arguments) messages.append({ role: tool, tool_call_id: tc.id, content: json.dumps(result, ensure_asciiFalse) }) else: return msg.content return 已达到最大循环次数强制结束 if __name__ __main__: print(run_agent(现在几点了另外请计算 1235 的结果))这段代码虽然只有几十行但已经包含了一个 Agent 的完整闭环模型产生工具调用程序执行工具工具结果回传模型继续生成。运行方式python 02_tool_call.py如果一切正常最终输出会包含当前时间和 47 的计算结果。这里不写死输出是因为不同模型可能组织语言的方式不同关键是验证工具结果是否被正确使用。3.2 理解工具定义和工具调用协议工具定义本质上是给模型一份 JSON Schema让模型知道“有哪些函数可以调用、每个函数有什么参数”。这一步极其重要因为参数描述不清晰模型就会传错参数。实践中经常遇到的问题参数类型定义成 string模型传了数字。缺少 required 字段模型跳过必填参数。description 写得太模糊模型不理解参数含义。工具返回结果不是 JSON 字符串导致模型解析困难。对于开放式接口建议每个工具返回稳定的 JSON 结构。比如上述代码里固定返回{time: ...}或{result: 47}模型更容易从结果中提取信息。3.3 为什么必须限制循环次数和错误兜底Agent 不是无限循环必须设置最大步数。原因很现实模型可能重复调用同一个工具而不收敛。外部接口可能一直返回异常但模型仍然尝试重试。多步调用会积累大量 tokens成本和延迟都会快速上升。上述代码中的for step in range(5)是一种最简单的兜底策略。生产环境还需要引入更细的控制例如单次任务最大工具调用次数。同一个工具连续调用失败后的熔断。超时和预算控制。当模型连续两次产生完全相同的工具调用时强制终止。4. Agent 框架与平台选型学习期不要并行学三个框架4.1 框架到底替你解决了什么问题手写最小 Agent 能帮你理解原理但真实项目往往需要处理复杂的工具编排、多轮对话记忆、批量任务调度这时候使用框架可以节省大量基础代码。常见框架和平台可以从以下角度分类类别代表适用场景通用编排框架LangChain、LlamaIndex需要灵活编排模型、工具和记忆多智能体协作AutoGen、CrewAI多个 Agent 协同完成任务低代码平台Dify、Coze快速搭建接近生产可用的应用云厂商平台各家云平台的 Agent 服务不想自建基础设施的团队注意这个表只是分类参考不代表某种方案绝对优于另一种。选型时关注的是当前团队的技术栈和交付目标。4.2 选型时应关注的六个维度在实际选型中建议从这六个维度打分维度说明学习成本官方文档是否完整社区案例是否丰富模型适配是否支持你正在用的模型和接口工具生态是否自带 Elasticsearch、数据库、HTTP 请求等集成可视化能力是否需要拖拽编排还是偏向代码开发部署方式是否支持本地私有化部署可观测性是否能查看每一步 Prompt 和工具结果初学者最容易忽略的是“可观测性”。一个 Agent 项目如果看不到中间步骤出现问题后只能靠猜。选型前先确认框架是否支持 Trace、日志或 Debug 模式。4.3 一条务实的框架学习建议不要同时学三个框架。推荐顺序是手写循环跑通后选一个和自己技术栈最匹配的框架把 3.1 节的时间查询和加法工具改造成框架写法。然后只在这个框架上继续做 ES 日志分析项目。框架只是工具真正的难点在于工具设计、记忆管理和评估。5. 典型项目拆解通过 ES REST API 智能分析日志5.1 项目需求让 Agent 直接回答日志问题AI Agent 的一个典型场景是智能日志分析。用户不再需要打开 Kibana 去拼查询语句而是直接问“最近 5 分钟 ERROR 日志有多少条”Agent 负责把问题转换成 Elasticsearch 查询调用 ES REST API最后把结果翻译成自然语言。这个项目的架构并不复杂用户输入一句话。Agent 决定调用es_count工具。工具向{ES_URL}/{index}/_count发送请求。ES 返回命中数量。Agent 根据数量生成最终回答。这里的重点是不要预先写死所有查询逻辑而是把“生成查询、执行查询、解释结果”三步交给 Agent 循环完成。5.2 只读账号和最小权限配置连接 Elasticsearch 时最忌讳使用管理员账号。建议创建一个只读账号并且只授予目标索引的读取权限。这样即使 Agent 生成了错误的查询也不会对线上数据造成破坏。.env 配置示例ES_URLhttp://localhost:9200 ES_USERreadonly_user ES_PASSWORDreadonly_password ES_INDEXapp-logs如果公司使用云 ES还需要确认网络策略是否允许当前开发机访问。很多“明明配置正确却连接失败”的问题实际上出在防火墙和访问白名单上。5.3 定义 es_count 工具接下来定义工具。为了让模型生成正确的查询条件工具的 description 要写清楚参数含义import json import os import requests ES_TOOL { type: function, function: { name: es_count, description: 根据索引名和查询DSL统计Elasticsearch中符合条件的文档数量, parameters: { type: object, properties: { index: { type: string, description: 索引名称例如 app-logs }, query_body: { type: object, description: Elasticsearch 查询 DSL例如 {query: {term: {level.keyword: ERROR}}} } }, required: [index, query_body] } } } def es_count(index, query_body): url f{os.getenv(ES_URL)}/{index}/_count resp requests.get( url, jsonquery_body, auth(os.getenv(ES_USER), os.getenv(ES_PASSWORD)), timeout10, ) resp.raise_for_status() return resp.json()这里将query_body定义为 object 类型让模型直接生成 DSL。比如用户问“最近 5 分钟 ERROR 日志有多少条”模型可能会生成如下查询{ query: { bool: { filter: [ { range: { timestamp: { gte: now-5m } } }, { term: { level.keyword: ERROR } } ] } } }5.4 限制模型生成 DSL 的四个风险点模型生成 DSL 能提高灵活性但也引入风险。实际项目中需要做好以下限制风险表现处理方式查询太重全表扫描或大范围聚合设置查询超时限制 size禁止危险聚合索引越权查询到其他索引对 index 参数做白名单校验返回字段过多大量字段占用上下文在 query_body 中使用_source限制字段凭据泄露日志中出现账号密码禁止打印请求头和认证信息一个简单的白名单校验示例ALLOWED_INDICES {app-logs, app-logs-2026.01} def safe_es_count(index, query_body): if index not in ALLOWED_INDICES: return {error: findex {index} is not allowed} return es_count(index, query_body)在生产环境中这段校验可能会放在网关层或者在工具函数入口统一处理。5.5 运行验证从问题到答案将es_count和之前的run_agent组合起来运行python 03_es_agent.py 最近5分钟ERROR日志有多少条预期结果是一段自然语言回答例如根据查询最近5分钟共有 12 条 ERROR 日志。如果得到的是工具返回的原始 JSON说明 Agent 没有把工具结果转换成自然语言。此时需要检查模型是否正确接收了 tool 角色消息以及是否给了足够的指令。不要只看有没有报错还要确认最终输出是否符合用户预期。6. 开发中的常见坑从上下文膨胀到权限过大6.1 工具参数解析失败模型返回了非 JSON 内容现象调用json.loads(arguments)时抛出JSONDecodeError。原因模型在生成 arguments 时偶尔会带多余说明或者把参数写成 Python 字典字面量。检查方式打印tc.function.arguments查看原始内容。解决方式不要直接信任模型输出。可以先用正则提取 JSON 片段或使用框架内置的强校验解析。如果重复出现说明需要更清晰的工具参数描述。import re def safe_json_loads(text): try: return json.loads(text) except json.JSONDecodeError: match re.search(r\{.*\}, text, re.S) if match: return json.loads(match.group()) raise6.2 Agent 进入重复工具调用循环现象Agent 反复调用同一个工具甚至出现“先查询再查询还不停止”的情况。原因模型没有足够的状态信息来判断任务是否完成或者循环缺少终止条件。检查方式打印每一步的 messages 历史观察模型是否在做重复动作。解决方式设置严格的最大步数同一个工具连续调用两次且参数不变时强制终止在 Prompt 中明确说明“工具结果已经获得后直接给出最终答案”。6.3 上下文无限膨胀成本和延迟越来越高现象多轮工具调用后messages 越来越大接口响应越来越慢。原因把每个工具返回的完整原始结果都放进上下文尤其是 ES 返回的几百条日志原文。解决方式对工具返回内容做截断和摘要。例如只保留count和top_errors字段忽略原始日志明细。def summarize_es_result(resp): return { count: resp.get(count), took_ms: resp.get(took), }6.4 ES 日志分析中权限过大现象开发环境使用 admin 账号跑通后把同样的连接串带到生产环境。原因只是为了方便没有为 Agent 单独创建只读账号。后果一旦模型生成恶意或错误的查询可能影响线上集群。解决方式为 Agent 创建最小权限只读账号限制可查询索引开启 ES Audit Log并对查询超时做统一设置。6.5 把敏感数据发送给模型现象工具返回内容中包含用户昵称、手机号、Token这些内容被直接放入 messages。原因没有在工具层做数据脱敏。解决方式工具返回前过滤敏感字段或在 Prompt 和系统设计中明确允许的数据范围。生产环境还应该评估模型服务商的数据协议是否符合公司合规要求。7. 排查链路和调试方法从现象定位到具体环节7.1 分层排查链路Agent 项目出现问题时不要从“模型是不是不够聪明”开始猜。应该按照从输入到输出的链路逐层排查检查用户输入是否完整是否包含必要条件。检查工具定义是否符合目标接口的格式。检查模型是否真的发起了工具调用。检查工具调用是否真正执行成功。检查工具返回结果是否被正确放回 messages。检查最终答案是否包含幻想内容。检查外部依赖 ES、网络、权限是否正常。很多“模型不调用工具”的问题实际上是工具名或参数描述和用户问题不匹配。例如工具名是get_current_time但用户只问“现在几点”模型应该能推理出要调用它但如果工具 description 写得太含糊模型就可能放弃调用。7.2 日志埋点必须在每层留下可追踪信息调试 Agent 与调试普通程序不一样普通程序是确定性的Agent 每次输出可能不同。因此必须打印关键中间信息。import logging logging.basicConfig(levellogging.INFO) logger logging.getLogger(agent) logger.info(user_message%s, user_message) logger.info(tool_name%s args%s, name, args) logger.info(tool_result%s, json.dumps(result, ensure_asciiFalse)[:500])建议至少记录用户输入。每一步的模型决策。工具名称和参数。工具返回结果摘要。循环次数和终止原因。最终答案。7.3 可复用排错清单现象可能原因检查方式处理建议模型不调用任何工具工具定义不清、模型不支持 Function Calling查看响应中是否有 tool_calls检查模型是否支持工具精简工具数量工具调用成功但结果未生效tool_call_id 未回传打印 messages 结构确认 tool 消息里包含正确的 tool_call_id最终回答是编造的工具结果没进入上下文或模型忽略结果检查工具结果是否短于预期调高结果保留内容强化 PromptES 请求返回 401账号密码错误或权限不足用 curl 单独请求 ES检查只读账号是否能访问目标索引ES 请求返回 403白名单未加入或索引无权限查看 ES 日志和错误体配置 IP 白名单和索引权限Agent 反复执行同一工具缺少终止条件打印循环步骤和参数加入最大步数、重复调用停止规则7.4 建立简单评估集防止改一个问题坏一个功能Agent 项目需要评估不能只看一两条例子。最简单的方法是自己维护一个测试集1. 现在几点了 2. 1235 等于多少 3. 最近 5 分钟 ERROR 日志有多少条 4. 最近 1 小时 WARN 日志的主要来源是每次修改 Prompt 或工具逻辑后批量运行这些测试用例记录是否有明显回归。进阶做法是把测试集接入自动化系统并使用类似 Agent Benchmark 的方式衡量步骤成功率、工具调用准确率和最终答案正确率。社区里的 benchmark 可以参考但业务项目更应该建设自己的回归集。8. 从学习项目到生产级 Agent最佳实践和扩展方向8.1 学习环境和生产环境的差异学习环境只要能跑通最小闭环即可生产环境则需要额外考虑稳定性、安全性和可维护性。关注点学习环境生产环境API Key放 .env使用密钥管理服务或 Secret 机制模型固定用一个模型考虑模型回退和降级方案工具本地函数需要权限、限流、审计日志print 足够结构化日志、链路追踪循环控制最大 5 次多维度预算和熔断数据随便测试脱敏、合规、最小化不要直接把学习项目的代码部署上线。生产环境至少要补充超时、重试、限流、审计、监控和回滚方案。8.2 生产级 Agent 发布前检查清单所有外部服务的账号都是最小权限。所有 API Key 不写入代码仓库。工具函数都有超时和异常处理。Agent 循环设置了最大步数和重复调用检测。工具返回内容做了长度限制和字段过滤。日志中不打印敏感字段。每个 Agent 任务都可以通过 Trace ID 追踪。修改 Prompt 或工具后回归测试集全部通过。模型服务不可用时有降级方案。有评估标准知道“多好才算合格”。8.3 从单 Agent 到多 Agent 协作学习完单个 Agent 后下一步可以尝试多 Agent 协作。单 Agent 适合任务链路较短、目标明确的场景多 Agent 适合需要不同角色分工的场景例如一个 Agent 负责理解用户意图另一个 Agent 负责查询数据和生成报表第三个 Agent 负责审核结果。多 Agent 的难点在于消息传递、结果冲突和总成本控制。建议先从两个 Agent 的最小协作开始不要一开始就设计复杂角色。你会发现真正困难的不是让 Agent 聊天而是让它们高效地停止对话、达成共识。8.4 更值得关注的长期方向从技术演进看以下方向比追逐新框架更重要记忆系统如何让 Agent 长时间服务用户而不丢失关键信息。工具协议标准化如何让不同 Agent 复用同一套工具接口。自动化评估如何用更准确的指标判断 Agent 质量。安全控制如何限制 Agent 的动作边界和权限。业务深度融合日志分析、客服问答、代码辅助等场景的落地。这篇内容从理解 Agent 原理到完成日志分析小项目实际上覆盖了一条可以反复练习的路线。先手写最小循环再用框架提升效率最后把工具、记忆和评估补齐遇到问题按链路排查。对于初学者最重要的不是课程数量而是亲手跑通一个又一个闭环并把这些闭环变成自己的工程能力。
返回列表