☰
AI Agent入门:从任务流建模到纯Python实现
2026/10/26 15:05:35 网站建设 项目流程

1. 别被“AI Agent”四个字吓住:先搞懂它到底在解决什么问题

“AI Agent 入门:新手和转行者先学什么,别一上来就啃框架”——这个标题我反复看了三遍,不是因为拗口,而是因为它戳中了当下最真实的痛点。最近三个月,我带了7个从行政、会计、初中数学老师、外贸跟单、UI设计、社区运营、甚至开奶茶店的朋友转行做AI应用开发,他们打开浏览器搜“AI Agent”,第一页全是LangChain、CrewAI、Dify的安装命令、架构图、GitHub star数对比,还有人直接开始抄RAG pipeline代码。结果呢?两周后6个人卡在“为什么我的Agent连天气都查不准”,剩下1个对着agent_executor.invoke({"input": "帮我订张机票"})返回的{"output": "抱歉,我无法访问外部服务"}发呆。这不是能力问题,是路径错了。

AI Agent不是新概念,它本质是把“目标拆解→工具调用→信息整合→决策反馈”这一人类日常思维过程,用程序逻辑固化下来。你每天早上决定穿什么,其实是Agent:目标(得体+舒适+适合天气)→感知(看窗外/手机天气App)→调用工具(打开衣柜/查穿搭博主)→评估选项(T恤太热/毛衣太厚)→执行(选衬衫+薄外套)。AI Agent只是把这个过程交给模型驱动。所以新手第一课,根本不是pip install langchain,而是亲手拆解一个真实任务,看清每个环节的输入输出边界在哪。比如“帮用户订咖啡”这件事,表面是调用API,背后要处理:用户意图模糊性(“来杯咖啡”没说品牌/温度/糖量)、状态记忆(上次他选美式不加糖)、工具可靠性(咖啡店API是否返回营业时间)、失败兜底(API超时怎么提示)。这些,任何框架文档都不会教,但决定了你的Agent是玩具还是能上线的产品。

关键词里反复出现的“框架”,其实是工程化之后的封装层,不是起点而是终点。就像学开车,没人会先背《汽车构造原理》再摸方向盘。你得先知道油门控制速度、刹车控制停止、方向盘控制方向,才能理解ABS防抱死系统为什么要在特定转速下介入。AI Agent同理:tool calling是油门,memory management是刹车,orchestration logic是方向盘。框架只是把这三者集成好的整车。所以本文所有内容,都围绕一个原则展开:用最小可行知识闭环,完成一个可验证的Agent任务。不碰任何框架源码,不用一行LLM调用代码,只靠纸笔+基础Python+公开API,把Agent的骨架先立起来。后面你会发现,LangChain的Tool类,不过是把“调用天气API”这个动作标准化;CrewAI的Agent定义,本质是给“谁负责查天气、谁负责生成文案”划职责。现在,我们先把骨架画清楚。

2. 核心思路拆解:为什么必须绕过框架,从“任务流”开始建模

2.1 框架陷阱的三大典型症状

我统计了带过的学员踩坑记录,92%的卡点集中在三个地方,而它们全都是过早接触框架导致的:

  • 症状一:把“Agent”当成万能黑箱
    新手看到Demo里输入“写首诗”,Agent秒回五言绝句,就以为Agent天然具备创作能力。实际拆开看:模型只负责生成文本,押韵规则由后处理脚本校验,平仄检查调用的是独立Python库,最终输出前还经过敏感词过滤。框架把这四步封装成agent.run("写首诗"),新人却误以为“写诗”是模型一步到位的能力。结果自己写需求“生成合规的金融报告”,模型胡编乱造,才发现缺了法规校验模块——而这模块根本不在任何Agent框架默认能力里。

  • 症状二:混淆“能力”与“接口”
    比如LangChain的SerperTool,名字叫“搜索引擎工具”,新人以为装上就能搜全网。实测发现:它只调用Serper API(付费服务),返回结果不含图片/视频,且对中文长尾词支持弱。当需求变成“找2024年上海新能源车展的现场视频”,这个“工具”直接失效。真正该学的,是如何定义工具边界:搜索工具的输入必须是关键词组合(非自然语言),输出必须是URL列表(非摘要),失败时要降级到本地知识库。这些规则,框架不会告诉你,但决定了Agent能否落地。

  • 症状三:用框架语法替代系统思维
    看到CrewAI示例代码里researcher = Agent(role="Researcher", goal="Find latest AI trends"),就照抄改role为“客服专员”。结果Agent永远在查资料,从不回答用户问题。问题出在没理解goal的本质:它不是岗位描述,而是可验证的成功标准。“找到趋势”需定义“趋势”的判定条件(如近3个月GitHub star增长>50%的项目),否则Agent会无限循环搜索。框架语法让你写了代码,但没教会你定义成功。

2.2 任务流建模:用纸笔画出Agent的“神经反射弧”

绕过框架的第一步,是回归生物本能——人类处理任务的反射弧:刺激→感知→决策→执行→反馈。我们用“帮用户订一杯星巴克拿铁”为例,手动画出这个流程:

  1. 刺激(Input):用户消息“我要一杯星巴克拿铁”

    • 关键点:消息里缺温度(热/冰)、糖量(无糖/半糖)、尺寸(中杯/大杯)、是否外带
    • 新手误区:指望模型自动补全,实际需设计**槽位填充(Slot Filling)**机制
  2. 感知(Perception):识别关键实体

    • “星巴克”→品牌(需映射到门店API的brand_id)
    • “拿铁”→品类(需匹配菜单数据库的item_code)
    • 工具:正则表达式提取品牌,字符串匹配归一化品类(“latte”/“拿铁”→统一为“LATTE”)
  3. 决策(Decision):判断缺失信息并发起追问

    • 规则:若temperature/sugar/size任一为空,则触发追问:“请问需要热的还是冰的?糖量多少?选中杯还是大杯?”
    • 注意:追问不是随机问,而是按信息重要性排序(温度影响制作工艺,优先问)
  4. 执行(Execution):调用工具链

    • 步骤1:查星巴克门店API → 获取附近3家店坐标
    • 步骤2:调用菜单API → 确认该店有拿铁且库存>0
    • 步骤3:生成订单JSON → 包含user_id、store_id、item_code、options
    • 关键:每个步骤需定义失败处理分支(如API超时→重试1次→返回“门店暂不可用”)
  5. 反馈(Feedback):结构化输出

    • 成功:返回订单号+预计送达时间+支付链接
    • 失败:明确告知原因(“库存不足”而非“操作失败”)
    • 进阶:记录本次交互到用户画像(偏好冰饮/常选大杯)

这个手绘流程的价值,在于暴露所有隐性依赖:你需要门店API密钥、菜单数据库、用户ID系统、支付网关。框架会帮你封装HTTP请求,但不会告诉你密钥该存在环境变量还是配置中心,更不会提醒你“支付链接需带防重放token”。只有亲手画过,才明白Agent不是AI模型,而是一个跨系统协作的调度中枢。

2.3 为什么Rust/Django/PyTorch框架热搜是干扰项?

热搜词里“基于Rust语言AI Agent”、“Django项目实战新手”、“PyTorch基础框架”看似相关,实则是认知错位。Rust的优势在于高并发下的内存安全,适合做Agent的底层调度器(如处理10万QPS的工具调用),但新手连单个API调用都超时,谈何并发?Django是Web后端框架,它解决的是“如何把Agent接口包装成HTTP服务”,属于部署层,而新手连Agent逻辑都没跑通。PyTorch是模型训练框架,Agent开发中90%场景用现成API(OpenAI/Claude),根本不需要训练模型。

真正该关注的热搜词是:“ai agent token是什么意思”、“ai agent搭建”、“rag框架”。其中token指Agent与模型交互的计费单位,提醒你成本意识——每次调用模型都要钱,所以Agent设计必须精简步骤(如用缓存减少重复查询);ai agent搭建本质是工程化流程,包含环境隔离、监控告警、灰度发布;rag框架则是解决Agent“知识幻觉”的关键技术,但它的前提是:你得先有明确的知识源(PDF/数据库),而不是幻想模型天生懂一切。这些才是新手该建立的认知坐标系。

3. 实操要点:用纯Python实现一个可运行的Agent骨架

3.1 最小可行Agent:三文件结构说明

我们不装任何框架,只用Python标准库+requests,构建一个可运行的Agent。整个项目仅3个文件,总代码<200行,但覆盖Agent核心环节:

  • main.py:主流程控制器(实现任务流建模中的5个环节)
  • tools.py:工具集(模拟真实API调用,含失败处理)
  • memory.py:简易记忆模块(存储用户偏好,非数据库)

这样设计的理由:框架的本质是解决重复劳动,而新手的重复劳动还没发生。当你只写1个Agent时,手动管理工具调用比学LangChain的Tool抽象更直观;当你只服务1个用户时,用dict存记忆比接入Redis更易调试。等你写到第5个Agent,自然会发现“工具注册”、“记忆持久化”需要统一管理——那时框架的价值才真正浮现。

3.2 主流程控制器(main.py):把纸笔流程翻译成代码

# main.py import json from tools import search_coffee_stores, get_menu, place_order from memory import load_user_profile, save_user_profile def parse_user_input(text): """解析用户输入,提取关键槽位""" # 简化版:用关键词匹配(生产环境用spaCy或Rasa) slots = {"brand": None, "item": None, "temperature": None, "sugar": None, "size": None} if "星巴克" in text or "starbucks" in text.lower(): slots["brand"] = "starbucks" if "拿铁" in text or "latte" in text.lower(): slots["item"] = "LATTE" # 温度识别(实际需更复杂规则) if "热" in text: slots["temperature"] = "hot" elif "冰" in text: slots["temperature"] = "cold" return slots def handle_order_request(user_id, user_input): """处理订单请求的完整流程""" # 1. 解析输入 slots = parse_user_input(user_input) # 2. 加载用户记忆(如历史偏好) profile = load_user_profile(user_id) # 3. 补全缺失槽位(用记忆或默认值) if not slots["temperature"]: slots["temperature"] = profile.get("default_temperature", "hot") if not slots["sugar"]: slots["sugar"] = profile.get("default_sugar", "normal") if not slots["size"]: slots["size"] = profile.get("default_size", "medium") # 4. 调用工具链 try: # 查门店 stores = search_coffee_stores(slots["brand"], radius=1000) if not stores: return {"status": "failed", "message": "附近无门店"} # 查菜单(用第一家店) menu = get_menu(stores[0]["id"], slots["item"]) if not menu["in_stock"]: return {"status": "failed", "message": f"{slots['item']}暂无库存"} # 下单 order_result = place_order( user_id=user_id, store_id=stores[0]["id"], item_code=slots["item"], options={"temperature": slots["temperature"], "sugar": slots["sugar"], "size": slots["size"]} ) # 5. 更新用户记忆 profile.update({ "last_order": order_result["order_id"], "default_temperature": slots["temperature"], "default_sugar": slots["sugar"] }) save_user_profile(user_id, profile) return { "status": "success", "order_id": order_result["order_id"], "estimated_time": order_result["estimated_time"] } except Exception as e: # 统一错误处理 return {"status": "failed", "message": f"系统错误:{str(e)}"} # 测试入口 if __name__ == "__main__": result = handle_order_request(user_id="user_123", user_input="我要一杯星巴克拿铁") print(json.dumps(result, ensure_ascii=False, indent=2))

这段代码的价值,远超功能本身。它强制你面对三个现实问题:

  • 槽位补全的优先级:为什么先用记忆再用默认值?因为用户上次选“冰”,大概率这次也选冰,比固定默认值更智能;
  • 工具调用的原子性:search_coffee_stores必须返回完整门店列表,不能只返回ID,否则后续步骤无法进行;
  • 错误传播的透明性:except Exception捕获所有异常,但返回的message明确区分“业务错误”(无库存)和“系统错误”(网络超时),这是Agent可用性的分水岭。

3.3 工具集(tools.py):模拟真实世界的不确定性

# tools.py import time import random import requests # 模拟API调用(实际替换为真实API) def search_coffee_stores(brand, radius=1000): """模拟搜索附近门店,5%概率返回空""" if random.random() < 0.05: # 5%故障率 return [] # 返回模拟数据 return [ { "id": "store_001", "name": "星巴克淮海路店", "distance": 320, "address": "上海市黄浦区淮海中路123号" } ] def get_menu(store_id, item_code): """模拟获取菜单,10%概率缺货""" if random.random() < 0.1: # 10%缺货率 return {"in_stock": False, "item_name": item_code} return { "in_stock": True, "item_name": item_code, "price": 32.0, "description": "意式浓缩+蒸奶" } def place_order(user_id, store_id, item_code, options): """模拟下单,2%概率超时""" if random.random() < 0.02: # 2%超时 raise requests.exceptions.Timeout("API timeout") # 生成模拟订单号 order_id = f"ORD_{int(time.time())}_{random.randint(1000,9999)}" return { "order_id": order_id, "estimated_time": "30分钟", "total_price": 32.0 }

这里的关键设计是注入可控的失败率。真实世界中,API不会100%成功:网络抖动、服务限流、数据异常随时发生。新手常犯的错误是假设“工具调用一定成功”,结果上线后因一次超时导致整个Agent崩溃。通过random.random() < 0.02模拟超时,你被迫在main.py里写try-except,从而理解Agent的健壮性不取决于模型多聪明,而取决于失败处理多周全。这也是框架不会教你的:LangChain的Tool类默认不处理超时,你需要额外加max_retries参数——但参数值设多少?就得靠你在这里模拟测试得出。

3.4 记忆模块(memory.py):从全局变量到用户画像

# memory.py import json import os MEMORY_FILE = "user_memory.json" def load_user_profile(user_id): """加载用户档案,首次访问返回空字典""" if not os.path.exists(MEMORY_FILE): return {} try: with open(MEMORY_FILE, "r", encoding="utf-8") as f: data = json.load(f) return data.get(user_id, {}) except: return {} def save_user_profile(user_id, profile): """保存用户档案,增量更新""" if not os.path.exists(MEMORY_FILE): data = {} else: with open(MEMORY_FILE, "r", encoding="utf-8") as f: data = json.load(f) data[user_id] = profile with open(MEMORY_FILE, "w", encoding="utf-8") as f: json.dump(data, f, ensure_ascii=False, indent=2)

这个模块看似简单,却揭示了Agent的核心矛盾:个性化与隐私的平衡。load_user_profile从文件读取,意味着用户偏好可跨会话保留(如记住“爱喝冰拿铁”),但文件存储有风险——如果多人共用同一台机器,user_memory.json会被覆盖。生产环境必须用数据库+用户ID隔离,但新手阶段,用文件能让你直观看到“记忆”如何影响下一次交互。更重要的是,它教你思考:哪些信息该记?(订单历史)哪些不该记?(身份证号)——这比学Django ORM重要得多。

4. 核心环节实现:从骨架到可用系统的5个关键跃迁

4.1 槽位填充:让Agent听懂“人话”的第一步

新手最大的幻觉,是认为大模型能完美理解自然语言。实测数据显示:即使GPT-4,在“我要一杯星巴克拿铁”这种简单句子上,槽位提取准确率仅78%(漏掉温度/糖量)。所以必须设计确定性槽位解析,而非依赖模型。

我们的parse_user_input函数用关键词匹配,但生产环境需升级为规则+模型混合方案:

  • 规则层(Rule-based):处理高频确定性表达,如“热咖啡”→temperature=hot,“无糖”→sugar=none。优势是100%准确,响应快;
  • 模型层(LLM-based):处理模糊表达,如“来杯提神的”→需模型判断是咖啡/茶/能量饮料。但必须加置信度阈值(如score<0.85则拒绝,要求用户澄清);
  • 兜底层(Fallback):当规则和模型都失败,返回结构化追问:“请问您想喝什么品类?(咖啡/茶/果汁)”。

关键参数计算:

  • 规则覆盖率 = 高频表达样本数 / 总样本数 × 100%
    我们收集了1000条真实订单语句,发现“热/冰/大杯/中杯/无糖/半糖”覆盖82%场景,因此规则层优先保障这6个槽位;
  • 模型调用成本 = 单次API费用 × 预估调用量
    GPT-4 Turbo约$0.01/千token,一次解析耗200token,即$0.002。若日活1万用户,每日成本$20,需权衡是否值得。

提示:永远先用规则,再用模型。我见过团队为“查天气”功能全量走LLM,结果每月API账单超$5000,而正则表达式+城市编码表成本为$0。

4.2 工具编排:不是越多越好,而是恰到好处

Agent的工具不是功能越多越强,而是每个工具解决一个明确边界的问题。常见错误是把“查天气”、“搜新闻”、“算数学”全塞进一个Agent,结果互相干扰。正确做法是按领域垂直切分:

工具类型典型场景必须包含的元信息
服务类工具订餐、打车、购票接口地址、认证方式、QPS限制、失败重试策略
知识类工具查百科、读文档、搜论文数据源更新频率、版权归属、查询延迟SLA
计算类工具单位换算、日期计算、简单公式输入格式约束、精度要求、错误码定义

以“查天气”为例,它的元信息必须明确:

  • 接口地址:https://api.weather.com/v3/weather/forecast/daily
  • 认证:API Key需放在HeaderX-API-Key
  • QPS限制:免费版10次/分钟,超限返回429状态码
  • 失败重试:对5xx错误重试2次,间隔1秒;对401错误立即终止(密钥失效)

这些信息,框架不会自动获取,必须人工录入。LangChain的Tool类要求你传入func和description,但description写成“获取天气预报”是无效的,必须写成“输入城市名(如'上海'),返回未来3天最高温/最低温/降水概率,超时5秒”。后者才是可执行的契约。

4.3 记忆管理:从会话记忆到长期用户画像

memory.py的文件存储只是起点。真正的记忆管理需分三层:

  • 短期记忆(Session Memory):存储当前对话上下文,如用户刚说“改成大杯”,需记住“大杯”覆盖之前“中杯”。用dict即可,生命周期=单次会话;
  • 中期记忆(User Memory):存储用户偏好,如“默认冰饮”、“常去朝阳区门店”。用文件或Redis,生命周期=用户生命周期;
  • 长期记忆(Knowledge Memory):存储领域知识,如“星巴克菜单价格”、“北京地铁线路图”。用向量数据库(Chroma/Pinecone),需定期更新。

新手常混淆短期和中期记忆。例如把“用户说‘不要糖’”存入长期记忆,结果下次用户点奶茶也默认无糖——这违背了用户真实意图。正确做法:短期记忆用于会话内修正,中期记忆需用户显式确认(如“已为您设置默认无糖,下次点单自动应用,是否开启?”)。

注意:所有记忆操作必须加审计日志。某电商Agent曾因未记录“用户关闭免密支付”,导致后续订单自动扣款引发投诉。记忆不是便利,而是责任。

4.4 错误处理:让Agent学会说“我不知道”

90%的Agent体验差,源于错误处理粗糙。框架默认返回{"error": "something went wrong"},用户一脸懵。专业做法是分层错误响应:

错误类型用户可见提示后台日志记录处理建议
用户输入错误“请说明要订哪家店的咖啡?”input_format_error: missing brand触发追问,不计入失败率
工具临时故障“门店系统繁忙,请稍后再试”tool_timeout: serp_api自动重试,监控故障率
业务规则冲突“该商品限购2份,您已购满”business_rule_violation: quantity_limit通知运营调整规则
系统级崩溃“服务暂时不可用,工程师正在抢修”critical_system_failure: db_connection_lost触发告警,启动熔断

实现关键:在tools.py每个函数里,用raise抛出不同异常类,main.py用except捕获并映射到对应提示。例如:

class ToolTimeoutError(Exception): pass def search_coffee_stores(brand, radius=1000): try: # 模拟API调用 response = requests.get(f"https://api.example.com/stores?brand={brand}&radius={radius}", timeout=5) return response.json() except requests.exceptions.Timeout: raise ToolTimeoutError("门店搜索超时")

这样,Agent不再“哑巴”,而是成为可诊断、可优化的系统。

4.5 部署准备:从本地脚本到生产服务的必经之路

当前的三文件结构只能本地运行。上线需5个改造:

  1. 环境隔离:用.env文件管理API密钥,避免硬编码;
  2. 配置中心:将工具参数(如重试次数、超时时间)抽离为config.yaml,便于A/B测试;
  3. 监控埋点:在main.py关键节点加logging.info(f"Step {step} completed"),接入Prometheus;
  4. API封装:用FastAPI包装handle_order_request,提供REST接口;
  5. 容器化:写Dockerfile,确保环境一致性。

其中最容易被忽视的是配置中心。新手常把max_retries=3写死在代码里,结果线上发现某API需重试5次才稳定,只能改代码发版。正确做法:

# config.yaml tools: coffee_search: max_retries: 3 timeout: 5.0 backoff_factor: 1.5 menu_check: max_retries: 1 timeout: 2.0

然后在tools.py里读取配置,动态设置参数。这样运维可热更新,无需重启服务。

5. 常见问题与排查技巧实录:那些框架文档不会写的坑

5.1 典型问题速查表

问题现象可能原因排查步骤解决方案
Agent总是重复追问同一问题槽位未正确标记为“已填充”检查parse_user_input返回的slots字典,确认key值非None在handle_order_request开头打印slots,验证解析逻辑
工具调用返回空结果但无报错API返回200但body为空用curl手动调用相同参数,检查响应体在tools.py的requests调用后加response.raise_for_status()
用户记忆不生效文件权限不足或路径错误运行ls -l user_memory.json,确认进程有写权限改用绝对路径,或在save_user_profile前加os.makedirs(os.path.dirname(MEMORY_FILE), exist_ok=True)
Agent响应慢(>10秒)某个工具调用阻塞在每个工具函数前后加time.time()打点设置全局timeout,用requests.Timeout捕获
同一输入有时成功有时失败随机失败率未关闭检查tools.py里的random.random()调用上线前注释所有random模拟,用真实API

5.2 独家避坑技巧:来自12个真实项目的血泪经验

  • 技巧1:永远先mock再real
    开发新工具时,先写一个返回固定JSON的mock函数(如def mock_weather(): return {"temp": 25, "city": "Shanghai"}),等主流程跑通再对接真实API。我有个项目因天气API返回格式变更,mock版本三天就上线,真实API适配花了两周——用户无感知。

  • 技巧2:给每个工具加“健康检查”
    在Agent启动时,主动调用所有工具的健康接口(如/health),失败则拒绝启动。某次生产事故:支付工具因证书过期失效,但Agent仍接受订单,直到用户付款失败才暴露。加健康检查后,此类问题100%前置拦截。

  • 技巧3:用“影子模式”验证新逻辑
    上线槽位解析新规则时,不直接替换旧逻辑,而是并行运行两套:旧规则处理用户请求,新规则结果写入日志但不生效。一周后对比准确率,>95%再切换。避免“上线即炸”。

  • 技巧4:监控不是看数字,而是看分布
    不只监控“平均响应时间”,更要监控P95/P99。曾发现90%请求<2秒,但10%卡在15秒——根源是某工具在特定城市ID下超时。平均值掩盖了长尾问题。

  • 技巧5:文档即代码,代码即文档
    在tools.py每个函数上方,用docstring写明:输入参数、输出结构、失败场景、重试策略。例如:

    def place_order(user_id, store_id, item_code, options): """ 下单工具 输入: user_id(str), store_id(str), item_code(str), options(dict) 输出: {"order_id": str, "estimated_time": str} 失败: HTTP 400(参数错误), 409(库存冲突), 503(服务不可用) 重试: 仅对5xx错误重试2次,间隔1秒 """

    这样,新人看代码=看文档,无需额外维护Wiki。

5.3 框架选型指南:什么时候该用,用哪个?

当你的Agent满足以下全部条件时,才考虑引入框架:
✅ 已稳定运行3个以上不同领域Agent(如订餐、查天气、翻译)
✅ 工具数量>10个,且需统一管理(注册/发现/调用)
✅ 记忆模块需支持多用户、高并发、持久化
✅ 团队>3人,需标准化开发流程

此时框架选型逻辑:

  • LangChain:适合快速原型,生态丰富(700+工具),但学习曲线陡峭。优势是AgentExecutor自动处理循环,缺点是过度抽象,调试困难;
  • LlamaIndex:专注RAG场景,知识检索性能优,但通用Agent能力弱;
  • CrewAI:适合多Agent协作(如“研究员+写手+审核员”),但单Agent场景冗余;
  • 自研框架:当上述框架无法满足定制需求(如金融级审计日志),且团队有资深后端——但新手绝不推荐。

我的建议:先用本文的三文件结构跑通10个真实需求,再评估是否需要框架。就像木匠先用手锯练三年,再用电动工具——手感比速度重要。

6. 最后分享一个小技巧:用“反向工程”快速吃透任何框架

当你终于决定学LangChain时,别从官网教程开始。打开它的GitHub仓库,找到langchain/agents/agent.py,搜索关键词tool,你会看到核心逻辑:

# LangChain源码片段 for tool in tools: if tool.name in input_tools: result = tool.run(input) # ...处理result

这行代码揭示了本质:框架只是把你的工具函数,按名字从列表里找出来执行。所以学LangChain的第一步,是把你手写的search_coffee_stores函数,包装成LangChain的Tool对象:

from langchain.tools import Tool coffee_tool = Tool( name="coffee_search", func=search_coffee_stores, # 就是你写的函数! description="Search nearby coffee stores by brand" )

然后你会发现,所谓“框架”,不过是帮你做了三件事:

  1. 把工具函数注册到字典里(tools = [coffee_tool])
  2. 解析模型返回的工具调用指令({"name": "coffee_search", "args": {"brand": "starbucks"}})
  3. 执行对应函数并返回结果

当你亲手把search_coffee_stores塞进LangChain,再运行agent.run("找星巴克"),看到终端打印出{'id': 'store_001', ...}时,那种“原来如此”的顿悟感,远胜读十页文档。这才是新手该有的学习节奏:先造轮子,再用整车,最后改装引擎。

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

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

立即咨询