强烈推荐! 手把手教你用Function Call实现LLM深度搜索,干货多到学不完

简介: VoidMuse 是一个开源AI IDE插件,支持IntelliJ IDEA与VS Code,整合20+优秀组件,通过深度搜索等功能帮助开发者在实践中掌握AI工程化技术,特别适用于学习Function Call与多轮工具调用的实现。文章介绍了如何利用Function Call能力,让AI像专家一样进行多-轮迭代搜索,以获取更全面的信息。内容涵盖了实现原理、Vercel AI SDK代码实战、必要的控制机制,并对比了不同模型的表现。

关于VoidMuse: 一个以学习为目标的开源AI IDE插件,支持IntelliJ IDEA和VS Code。通过整合20+优秀开源组件,让你在实际开发中掌握AI工程化技术。不仅提供工具,更重要的是帮你把AI知识真正应用起来,通过实践来学习。本文将通过VoidMuse的深度搜索功能,带你深入理解Function Call技术。

1. 深度搜索和传统搜索的区别

传统搜索模式通常只进行一次查询,用户输入关键词后,搜索引擎返回与该关键词匹配的结果。但实际上,我们在搜索内容时,很难一下子就搜索到自己满意的内容,需要根据已获取的信息,不断迭代搜索,才能获取到自己满意的结果。

例如,当搜索"React性能优化"时,传统搜索只会返回与这个关键词直接相关的结果,而不会自动深入到"React虚拟DOM优化"、"React组件懒加载"等更具体的领域。

深度搜索突破了传统搜索的限制,通过多轮迭代搜索实现更全面、更深入的信息获取:

  • 首次搜索后,系统分析搜索结果
  • 基于已获取的信息,自动生成新的、更精确的搜索词
  • 使用新搜索词进行下一轮搜索
  • 不断迭代,直到获取足够全面的信息或达到预设的搜索深度

这种方式模拟了专业研究人员的搜索行为,每一轮搜索都建立在前一轮获取的知识基础上,逐步深入和扩展信息范围。

深度搜索效果如下:

深度搜索效果.png

2. Function Call 与深度搜索

想要实现深度搜索,就要利用到 Function Call 能力,LLM通过function call调用搜索工具,不断迭代搜索

2.1 Function Call 的基本概念

Function Call(函数调用)是大语言模型(LLM)的一项关键能力,允许模型在对话过程中调用预定义的函数或工具。在深度搜索中,Function Call扮演着核心角色:

  • 模型可以决定何时需要调用搜索工具
  • 模型可以生成适当的搜索关键词
  • 模型可以分析搜索结果并决定下一步行动

2.2 深度搜索的时序图

深度搜索的实现涉及LLM、应用程序和搜索引擎之间的复杂交互:
深度搜索时序图.png

深度搜索实现的关键:循环调用大模型,直到大模型不再请求搜索工具,或者达到最大搜索次数。

2.2.1 LLM决策过程

  1. 接收用户查询
  2. 分析查询内容,判断是否需要搜索外部信息
  3. 如需搜索,生成适当的搜索关键词
  4. 分析搜索结果,决定是否需要进一步搜索
  5. 如需进一步搜索,生成新的搜索关键词
  6. 当获取足够信息后,综合所有结果回答用户

2.2.2 工具调用流程

  1. 应用程序向LLM发送包含工具定义的请求
  2. LLM返回工具调用请求(包含搜索关键词)
  3. 应用程序执行搜索并获取结果
  4. 应用程序将搜索结果返回给LLM
  5. 重复步骤2-4,直到LLM不再请求搜索或达到最大搜索次数

2.3 搜索工具的声明与使用

2.3.1 伪代码实现-直接接入llm api实现

深度搜索的伪代码实现:对接llm api

while(result.toolCall 存在 || maxStepCount 未到) {
   
  // 调用搜索工具
  const searchResult = await callSearchTool(toolCall);

  // 调用大模型: 需要把历史数据也传递给大模型
  result = await callLLM(history, searchResult);
}

调用llm的数据参数可参考图片:包含了两次工具调用
深度搜索-发送给LLM的数据结构.png

调用llm的完整参数结构:每次都要携带完整的历史上下文过去,包含了前几次llm返回的工具
深度搜索-首次调用llm.png
深度搜索-第二次调用llm.png

3次搜索工具调用时,第3次本地搜索完成后调用llm时所传递的完整参数如下图
深度搜索-完整调用llm传递的参数.png

2.3.2 使用vercel ai sdk实现

vercel ai sdk:封装了多轮工具调用,知道了原理后直接使用封装好的sdk会更加高效,不需要自己再造轮子了

在实现深度搜索时,需要向LLM提供搜索工具的定义。以下是一个典型的搜索工具定义示例:

const searchTool = {
   
  name: "webSearch",
  description: "搜索互联网获取最新信息",
  parameters: {
   
    type: "object",
    properties: {
   
      query: {
   
        type: "string",
        description: "搜索关键词"
      }
    },
    required: ["query"]
  }
};

在Vercel AI SDK中,工具的使用方式如下:

const result = streamText({
   
    model: model,
    messages: messages,
    system: systemPrompt,
    tools: [searchTool],  // 提供搜索工具定义
    stopWhen: stepCountIs(5),  // 限制最大搜索次数
    abortSignal: abortController.current?.signal,
    onError: handleError
});

3. 深度搜索的控制机制

3.1 LLM自主判断结束条件

深度搜索的一个关键特性是LLM能够自主判断何时应该结束搜索:

  • 当LLM认为已获取足够信息时,不再返回工具调用请求
  • 当LLM发现后续搜索可能不会提供新信息时,停止搜索
  • 当LLM确定问题已经得到完整回答时,结束搜索过程

这种自主判断机制使深度搜索既能获取全面信息,又能避免无效搜索,提高效率。

3.2 最大工具调用次数限制(stopWhen: stepCountIs(5))

尽管LLM能够自主判断搜索结束条件,但为了防止潜在的无限循环或过度搜索,设置最大工具调用次数限制是必要的:

stopWhen: stepCountIs(5)  // 限制最多进行5次工具调用

这个参数确保即使LLM持续请求更多搜索,系统也会在达到预设次数后强制结束搜索过程。

3.3 防御性设计的必要性

在实现深度搜索时,防御性设计至关重要:

  • 防止无限循环:LLM可能陷入持续搜索的循环,必须设置最大调用次数
  • 控制资源消耗:每次搜索都消耗API调用和计算资源,需要合理限制
  • 避免信息过载:过多的搜索结果可能导致信息过载,反而降低回答质量

4. 实际应用案例

4.1 代码示例解析

以下是使用Vercel AI SDK实现深度搜索的核心代码

const result = streamText({
   
    model: model,
    messages: MessageConverter.getInstance().convertToApiFormat(historyList.map(msg => msg.message), promptContent),
    system: PromptService.getSystemPrompt({
   
        modelName: modelRef.current?.name || '',
        projectInfo: projectInfo,
        tools: tools
    }),
    tools: tools,
    stopWhen: stepCountIs(5),
    abortSignal: abortController.current?.signal,
    onError: (error) => {
   
        handleApiError(error, onUpdate, onSuccess, selectedModel);
    }
});
export const webSearchTool = tool({
   
  description: 'Search the web for information based on keywords to obtain the latest relevant materials and data',
  inputSchema: z.object({
   
    keyword: z.string().describe('Search keyword should be specific and relevant. Please automatically determine based on the nature of the search content: use English keywords for international content like technical documentation, international news, academic materials; use Chinese keywords for Chinese information, localized content, Chinese community discussions. Choose the language that will yield the most accurate search results.'),
    searchIntent: z.string().describe('Search intent explanation, describe why you need to search for this keyword')
  }),
  execute: async ({
    keyword, searchIntent }) => {
   
    try {
   
      const result = await searchService.onlineSearch(keyword);

      if (result.success) {
   
        return {
   
          success: true,
          keyword,
          searchIntent,
          results: result.results.map(item => ({
   
            title: item.title || '',
            url: item.url,
            snippet: item.description,
            favicon: item.favicon || '',
          }))
        };
      } else {
   
        return {
   
          success: false,
          error: result.msg || 'Search failed',
          keyword,
          searchIntent
        };
      }
    } catch (error) {
   
      return {
   
        success: false,
        error: error instanceof Error ? error.message : 'Unknown error occurred',
        keyword,
        searchIntent
      };
    }
  }
});

export type WebSearchResult = {
   
  success: boolean;
  keyword: string;
  searchIntent: string;
  results?: Array<{
   
    title: string;
    url: string;
    snippet: string;
    favicon: string;
  }>;
  error?: string;
};

5. 不同模型的表现对比

实际测试中,Claude 3.7+ 和 OpenAI O系列模型是能做到搜索多次的,但 GPT-4o-mini 就经常只会触发一次搜索,而不会深度多次搜索,这也就意味着 GPT-4o-mini 模拟在agent场景的能力上是偏弱的,在需要深度搜索的场景下,建议使用Claude 3.7+

目录
相关文章
|
21天前
|
人工智能 搜索推荐 算法
万字长文深度解密!Cursor Codebase实现原理全公开
VoidMuse 是一个开源AI IDE插件,支持 IntelliJ IDEA 与 VS Code,整合20+优秀组件,通过混合搜索架构(Lucene+向量)实现Codebase智能代码检索,助力开发者在真实项目中掌握AI工程化技术。
272 3
|
8天前
|
人工智能 IDE Java
我们从零开始实现了一个cursor的codebase功能(踩了很多RAG的坑)
VoidMuse 是一个以学习为目标的开源AI IDE插件,支持IntelliJ IDEA与VS Code,集成20+优秀开源组件,助力开发者在实践中掌握AI工程化技术。本文深入解析其基于混合检索的Codebase实现,涵盖向量化、索引构建与检索优化,助你真正理解并应用Function Call等核心技术。
140 5
我们从零开始实现了一个cursor的codebase功能(踩了很多RAG的坑)
|
存储 JSON 前端开发
使用JSZip实现压缩文件与图片
使用JSZip实现压缩文件与图片
|
22天前
|
运维 算法 数据挖掘
【故障定位系列】基于DeepSeek的故障定位大揭秘
传统故障定位依赖专家经验与固定算法,难以应对复杂场景。引入DeepSeek大模型后,可凭借其强大推理与自适应能力,实现智能故障定位。通过“大模型+Agent”协同架构,大模型负责决策,Agent执行数据分析,既降低Token消耗,又保留智能化分析优势。未来,随着大模型理解与推理能力提升,故障定位将更高效、精准。
|
19天前
|
人工智能 Cloud Native Serverless
智驱未来,降本增效:2025阿里云双十一,企业数字化转型的终极引擎
一年一度的阿里云双十一全球狂欢季不仅是消费者的盛宴,更是企业实现技术升级与成本优化的黄金窗口。进入2025年,随着AI大模型、大数据分析的深度应用,企业对云计算的依赖性空前增强。阿里云作为亚太市场的领军者,其双十一大促已演变为一场为企业量身打造的“技术普惠”行动。本文将为您全面解析2025年阿里云双十一的独特优势、核心亮点及参与攻略,助您抢占先机
291 0
|
5天前
|
人工智能 固态存储 Linux
树莓派这种“玩具级”设备,真能跑大模型吗?
本期教程带你用树莓派5部署Qwen3模型,打造完全离线、自带屏幕与键盘的“AI小终端”。基于C语言实现,不依赖Python或llama.cpp,支持多尺寸Qwen3模型,实现本地化私有推理。跟随步骤,轻松搭建属于你的端侧AI助手。
137 23
|
22天前
|
SQL 运维 Kubernetes
【故障定位系列】电商业务系统告警频发,如何快速实现应用接口级故障定位
本文以电商场景为例,探讨如何实现Web应用接口级故障根因定位。通过构建实时拓扑、对比客户端与服务端响应时间,结合指标下钻与耗时分解技术,精准定位到故障服务及具体接口,提升运维效率。