问题背景:

        在DeepSeek-V3.1发布前,包括DeepSeek-R1DeepSeek-V3在内的早期版本,确实存在这一短板。

        主要原因在于技术路线的取舍。R1系列的核心亮点是通过思维链(Chain-of-Thought) 强化推理能力,专注于解决数学、代码等复杂逻辑问题。同时,其采用的混合专家模型(MoE) 架构旨在极致优化成本。在这一阶段,模型能力的天平明显倾向于深度推理成本控制,而非原生工具调用能力。

社区解决方案:

        面对R1不支持Function Call的情况,社区和开发者们想出了不少方案,主要分为两类:

  1. Prompt工程模拟:这是最主流的方案。核心思想是通过自然语言“教”模型调用工具

    • 操作方式:在系统提示词(System Prompt)中,详细描述工具的名称、功能、参数和调用格式(如JSON),并强制要求模型在需要调用工具时输出特定格式的文本。

    • 后处理解析:程序收到模型的文本回复后,通过正则表达式或JSON解析器,识别并提取出工具调用指令,再执行相应的函数。

    • 典型案例:Bella OpenAPI的ToolCallSimulator类,通过精心设计的模板注入和响应解析,为DeepSeek R1“模拟”出Function Call的效果。

  2. 提示词方案示例:在Prompt中明确定义动作类型。

# 动作类型定义
- TYPE: ANSWER (直接回答)
- TYPE: MCP (调用工具)

# 调用示例
TYPE: MCP
{
  "tool_name": "get_weather",
  "parameters": {"city": "Beijing"}
}

个人解决方法:

1. 结构化提示词优化

        通过设计一套结构化的提示词,为模型明确定义工具调用的规范。首先,明确模型作为编程助手的角色定位;其次,详细说明工具的使用规则,包括调用格式与执行流程;在此基础上,定义不同场景下的智能工作流程;最后,提供简化与完整两种工具调用格式作为示例。这样的提示词结构,相当于为模型构建了一套清晰可执行的“工具调用语言”,有效提升了工具调用意图的表达准确性。

2. 实时代码块解析

        在工具调用的解析环节,我们基于 LangChain4j 的 StreamingResponseHandler 实现了流式解析机制,能够在模型生成过程中实时处理 token,而不是等待完整响应后统一处理。具体实现上,系统会实时检测代码块的起始与结束标记,从模型输出中提取目标文件名,并完整捕获代码块内的内容。当检测到代码块结束时,自动触发对应的工具调用。这一流程确保了从模型输出到工具执行的无缝衔接。

        关键代码实现如下:

// 检测代码块开始
if (!inCodeBlock && token.contains("```")) {
    inCodeBlock = true;
    codeBlockCount++;
    // 检测文件名
}

// 检测代码块结束
if (inCodeBlock && token.contains("```")) {
    inCodeBlock = false;
    codeBlockCount++;
    // 触发工具调用
    if (confirmationDisplayed && codeBlockCount >= 2) {
        String cleanCode = codeBuffer.toString();
        triggerToolCallWithCode(detectedFileName, cleanCode.trim());
        hasTriggeredToolCall = true;
    }
}
```"

#### 3. 多格式工具调用检测
"我们还实现了多格式的工具调用检测机制,支持多种调用方式:

- **简化格式检测**:识别 `⏺ Read(文件名)` 等简化格式
- **完整格式检测**:识别 `file_manager read "文件路径"` 等完整格式
- **代码块格式检测**:识别代码块 + 文件名提示的组合
- **自然语言格式检测**:识别"创建文件"、"读取文件"等自然语言指令

这样无论模型使用哪种格式表达工具调用意图,我们都能准确识别并执行。

3. 实现过程中的关键挑战

        在落地过程中,我们面临几个关键挑战。首先是流式解析的复杂性,需要在模型边生成边输出的过程中实时处理,这对响应逻辑的设计提出了较高要求。其次是多格式识别问题,由于不同模型的输出风格差异较大,系统需要兼容多种工具调用格式,以保障识别的准确率。此外,如何正确将代码块内容与目标文件名关联,以及如何在合适的时机触发工具调用、避免打断用户交互的流畅性,也都是需要仔细权衡的技术难点。

4. 方案优势与技术价值

        这套方案的价值体现在多个方面。在兼容性上,它不依赖模型原生的 Function Calling 能力,可以适用于各类大语言模型;在灵活性上,通过支持多种工具调用格式,能够适配不同模型的输出风格。实时性方面,流式解析机制实现了边生成边处理,有效降低了用户的等待时间。同时,系统能够自动提取文件名与代码内容,减少了用户的手动输入,提升了智能化水平。最终,这些技术特性共同支撑起自然连贯的对话体验,在不打断用户思路的前提下完成工具调用。

总结:

        总结来说,我们通过结构化提示词定义工具调用规范,结合实时代码块解析和多格式检测,成功模拟了 Function Calling 功能,让 DeepSeek 模型能够执行各种工具操作,实现了从'对话'到'行动'的跨越。这一方案不仅解决了技术限制,也为其他不支持原生 Function Calling 的模型提供了参考实现。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐