ARTICLE DETAIL

资讯详情

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

【手搓 Agent 第2.2关】搭建 Agent 进阶能力:网络搜索工具(中)

【手搓 Agent 第2.2关】搭建 Agent 进阶能力:网络搜索工具(中) 承接上篇我们搭建的原生爬虫搜索工具虽然实现了联网功能但存在严重的工程短板工具内部自行捕获并吞掉异常大模型无法感知真实故障只能机械重复无效调用完全不具备智能体的自主思考能力。本篇聚焦 Agent 核心智能特性落地Error as Observation 错误即观测核心架构。重构工具异常处理逻辑将所有工具报错统一封装为标准对话信息喂给模型同时实现动态工具武器库、故障熔断、权限回收机制让 Agent 真正学会识别错误、分析错误、自主终止无效任务完成从“机械执行”到“智能决策”的升级。一、Agent 错误观测与自主熔断机制在本章节我们将探索如何让模型理解失败原因。我们将植入免疫系统核心代码error as observation。Error as Observation工具执行无论成功、崩溃、拦截、超时全部统一封装为 OpenAI 标准roletool消息存入chat_history捕获异常后绝不提前return终止流程把报错当作一条 “环境观测” 丢给大模型由模型自主判断下一步怎么做。1. 移除函数内部容错代码定位完整web_search函数。改动删除函数内部全部try/except只保留业务逻辑 检测安全验证主动抛异常。代码示例defweb_search(query:str)-str:print(f\n[执行工具] 正在联网搜索关键词{query})urlfhttps://www.baidu.com/s?wd{query}headers{User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36}resprequests.get(url,timeout10,headersheaders)resp.encodingresp.apparent_encoding resp.raise_for_status()soupBeautifulSoup(resp.text,html.parser)raw_textsoup.get_text(stripTrue,separator\n)if百度安全验证inraw_textor网络不给力inraw_text:raiserequests.exceptions.HTTPError(403 Forbidden百度反爬拦截需要人机验证)short_textraw_text[:2000]returnf【网络搜索结果】\n{short_text}我们把异常全部抛到上层统一处理而不是在工具内部吞掉异常。这样上层调度代码拿到完整错误类型、堆栈信息就可以靠代码逻辑精准区分故障。2. 核心工具执行循环增加局部异常捕获定位generate_response函数内部for tool in msg.tool_calls:循环里执行工具的代码块原代码片段无捕获tool_funcavailable_tools.get(func_name)iftool_func:tool_resulttool_func(**func_args)else:tool_result不存在该工具print(f工具返回结果{tool_result})修改方案给tool_func(**func_args)包裹try-except捕获所有工具抛出的异常生成标准化报错文本示例代码tool_funcavailable_tools.get(func_name)try:iftool_func:tool_resulttool_func(**func_args)else:tool_resultf不存在名为{func_name}的工具exceptExceptionase:tool_resultf【工具执行失败】HTTP 403 Forbidden百度反爬拦截需要人机验证。系统底层报错详情{str(e)}print(f工具返回结果{tool_result})不管是 403 拦截、网络超时、解析报错全部进入这个except异常不会向上跑到最外层大try不会直接返回全局错误、打断对话成功结果 / 报错信息都会存入同一个变量tool_result后续统一封装成roletool消息写入历史。3. 自我修正闭环完整运行日志在此阶段希望模型识别出搜索工具无法返回结果后由大模型进行推理思考从而进行二次工具调用只用知识库回答。升级系统提示词system_prompt{role:system,content:你是一个严谨的资料研究助手。你有两个强大的工具 1. query_knowledge_base用于查询企业内部标准、本地文件。 2. web_search用于查询最新的互联网公开信息。 请自主判断用户的提问灵活选择调用一个或多个工具来收集信息。 注意真实的网络环境是不稳定的如果调用网页搜索遇到失败或报错你需要自己分析原因决定是更换关键词重试还是直接利用已收集到的本地知识进行总结。在回答的末尾请务必标注信息来源。}动态工具剪枝与熔断机制在企业级 Agent 架构中用提示词指望大模型自己聪明是不可靠的。工业上一般通过动态剥夺大模型工具使用权的方式避免它多次调用无用工具。即如果检测到某个工具报了“不可逆的致命错误比如 403 永久拦截”我们在下一次请求大模型时直接把这个工具从tools列表里删掉。在进入循环前复制一份“动态武器库”示例代码defgenerate_response(prompt):try:chat_history.append({role:user,content:prompt})MAX_STEPS3step_count0# 【新增】复制一份当前的 tools 列表作为本轮对话的动态武器库# 这样我们可以随时在这个列表里删除失效的工具current_toolstools.copy()# 第一次请求时把 current_tools 传进去responseclient.chat.completions.create(modelModel_ID,messageschat_history,toolscurrent_toolsifcurrent_toolselseNone,tool_choiceautoifcurrent_toolselsenone,parallel_tool_callsFalse,# 关闭并发调用timeout30)ifnotresponse.choices:raiseException(模型首次返回空choices上下文过长或接口限流无输出)msgresponse.choices[0].message在工具报错时触发“熔断剪枝”且当大模型强行调用已经被熔断的工具直接拦截并严厉警告# ... 前面的代码保持不变 ...is_tool_allowedany(t[function][name]func_namefortincurrent_tools)ifnotis_tool_allowed:tool_resultf【工具调用失败】你没有权限调用{func_name}工具。else:# 执行本地工具动态分发调用tool_funcavailable_tools.get(func_name)try:iftool_func:tool_resulttool_func(**func_args)else:tool_resultf不存在名为{func_name}的工具exceptExceptionase:error_msgstr(e)if403inerror_msgor百度反爬拦截inerror_msg:tool_resultf【系统强制熔断】致命错误{error_msg}。该网页搜索渠道已永久失效禁止重试。current_tools[tfortincurrent_toolsift[function][name]!func_name]print(f[系统拦截] 触发熔断已剥夺大模型对 {func_name} 的调用权限)else:tool_resultf【工具执行失败】普通错误{error_msg}。你可以尝试更换关键词或修改参数后再次调用。print(f工具执行结果{tool_result})# ... 存入 chat_history 的代码保持不变 ...二次请求大模型时应用被阉割的武器库print(正在分析工具结果并生成后续回复...)# 【新增逻辑】如果所有工具都被没收了必须去掉 tools 参数否则 API 会报错api_kwargs{model:Model_ID,messages:chat_history,timeout:30}ifcurrent_tools:api_kwargs[tools]current_tools api_kwargs[tool_choice]autosecond_respclient.chat.completions.create(**api_kwargs)# 刷新 msg为最新的模型输出ifnotsecond_resp.choices:raiseException(二次调用模型返回空choices上下文过载无法生成回复)msgsecond_resp.choices[0].message预期结果流程调用query_knowledge_base查询本地知识库→ 未查询到完整结果→ 调用web_search进行联网搜索→ 因网页反爬虫无法获得结果→ LLM 思考认为此路不通无法联网搜索/系统强制熔断删除web_search工具→ LLM 不再强行联网搜索而是使用本地知识库已有信息回答问题。二、本篇总结 下期预告通过本篇改造我们彻底解决了 Agent 工具调用无脑重试、死循环卡死的问题让智能体具备了基础的自我反思与故障止损能力。但手写原生爬虫稳定性极差极易被网站反爬拦截仅适合入门学习完全无法适配线上生产环境。下一篇 Stage 2-网络搜索工具下篇我们将完成从玩具demo到工业级落地的升级替换商用专业搜索API同时解决大模型迭代式检索过度调用工具的问题通过软硬双层约束实现工具调用可控化完成生产级网络搜索工具闭环。
返回列表