DeepSeekV3.2模型内置Agent体验

传统 Agent 的架构困境

所有大模型的 Agent 能力都面临一个根本性矛盾:

Chain-of-Thought(CoT)推理模式: 能进行多步复杂推理,但推理过程是封闭的,无法中断去调用外部工具。

Function Calling(工具调用)模式: 能执行外部操作,但每次调用都会打断推理链路,导致上下文丢失和推理碎片化。

这种架构分离导致的结果是:要么闭卷推理(无实时数据支撑),要么开卷查询(缺乏深度分析)。

DeepSeek 3.2 的技术突破

核心创新:推理过程中的动态工具调用

DeepSeek 3.2 实现了全球首个"Reasoning-in-Action"范式:

架构对比:

arduino 复制代码
传统 ReAct:Thought → Action → Observation → Thought...
          (推理与行动交替,上下文割裂)

V3.2 新范式:Continuous Reasoning [Tool Call ⊂ Reasoning Process]
          (工具调用内嵌于连续推理流)

技术实现:

  • reasoning_content 传递机制:保持完整推理链路的上下文连贯性
  • 自适应工具决策:模型在推理中自主判断工具调用时机和参数
  • 双模式支持:思考模式(复杂任务)+ 非思考模式(快速响应)

这种架构让模型具备了真正的"元认知"能力:知道自己的知识边界,主动寻求外部信息补充。

详细信息可以查看官方文档,里面提供了python实现代码,因为我更喜欢ts,所以下面改写一段ts版的:

ts 复制代码
import OpenAI from 'openai'
import type {
  ChatCompletionMessageParam,
  ChatCompletionTool,
} from 'openai/resources/chat/completions'

// Get environment variables
const apiKey = process.env.DEEPSEEK_API_KEY
const baseURL = process.env.DEEPSEEK_BASE_URL

const client = new OpenAI({
  apiKey: apiKey,
  baseURL: baseURL,
})

// The definition of the tools
const tools: ChatCompletionTool[] = [
  {
    type: 'function',
    function: {
      name: 'get_date',
      description: 'Get the current date',
      parameters: { type: 'object', properties: {} },
    },
  },
  {
    type: 'function',
    function: {
      name: 'get_weather',
      description:
        'Get weather of a location, the user should supply the location and date.',
      parameters: {
        type: 'object',
        properties: {
          location: { type: 'string', description: 'The city name' },
          date: {
            type: 'string',
            description: 'The date in format YYYY-mm-dd',
          },
        },
        required: ['location', 'date'],
      },
    },
  },
]

// The mocked version of the tool calls
// In Python `**kwargs` unpacks the dict, in JS we receive a single object argument
function get_date_mock(): string {
  return '2025-12-01'
}

function get_weather_mock(args: { location: string; date: string }): string {
  return 'Cloudy 7~13°C'
}

const TOOL_CALL_MAP: Record<string, Function> = {
  get_date: get_date_mock,
  get_weather: get_weather_mock,
}

// Function to clear reasoning_content to save bandwidth
// Note: modifying objects in the array by reference
function clear_reasoning_content(messages: any[]) {
  for (const message of messages) {
    if (message.reasoning_content) {
      message.reasoning_content = null
    }
  }
}

async function run_turn(turn: number, messages: any[]) {
  let sub_turn = 1
  while (true) {
    // DeepSeek specific: extra_body for thinking
    const response = await client.chat.completions.create({
      model: 'deepseek-chat',
      messages: messages as ChatCompletionMessageParam[],
      tools: tools,
      // 注意!!!这里不需要extra_body包多一层,因为这里会将其他属性全部丢到body里面
      thinking: { type: 'enabled' },
    } as any) // Cast to any to allow extra_body if types are strict

    const message = response.choices[0].message
    messages.push(message)

    // Access properties (casting to any to access 'reasoning_content' which is not in standard types)
    const reasoning_content = (message as any).reasoning_content
    const content = message.content
    const tool_calls = message.tool_calls

    console.log(
      `Turn ${turn}.${sub_turn}\nreasoning_content=${reasoning_content}\ncontent=${content}\ntool_calls=${JSON.stringify(
        tool_calls
      )}`
    )

    // If there are no tool calls, stop the loop
    if (!tool_calls || tool_calls.length === 0) {
      break
    }

    for (const tool of tool_calls) {
      const tool_function = TOOL_CALL_MAP[tool.function.name]
      // In JS, we parse the JSON string to an object and pass it to the function
      const args = JSON.parse(tool.function.arguments)
      const tool_result = tool_function(args)

      console.log(`tool result for ${tool.function.name}: ${tool_result}\n`)

      messages.push({
        role: 'tool',
        tool_call_id: tool.id,
        content: tool_result,
      })
    }
    sub_turn += 1
  }
}

async function main() {
  // The user starts a question
  let turn = 1
  const messages: any[] = [
    {
      role: 'user',
      content: "How's the weather in Hangzhou Tomorrow",
    },
  ]

  await run_turn(turn, messages)

  // The user starts a new question
  turn = 2
  messages.push({
    role: 'user',
    content: "How's the weather in Hangzhou Tomorrow",
  })

  // Clear reasoning_content in history
  clear_reasoning_content(messages)

  await run_turn(turn, messages)
}

// Execute logic
main().catch(console.error)

输出:

vbnet 复制代码
Turn 1.1
reasoning_content=The user wants to know the weather in Hangzhou tomorrow. I need to get the date for tomorrow first, then use that to get the weather. Let me start by getting the current date.
content=
tool_calls=[{"index":0,"id":"call_00_jv8TcuSwxu1c5nzVMf0NrVrN","type":"function","function":{"name":"get_date","arguments":"{}"}}]
tool result for get_date: 2025-12-01

Turn 1.2
reasoning_content=Today is December 1, 2025. Tomorrow would be December 2, 2025. Now I can get the weather for Hangzhou for that date. Let me call get_weather with location "Hangzhou" and date "2025-12-02".
content=
tool_calls=[{"index":0,"id":"call_00_qdEqnDe5ulkeSe8orl44rAvN","type":"function","function":{"name":"get_weather","arguments":"{\"location\": \"Hangzhou\", \"date\": \"2025-12-02\"}"}}]
tool result for get_weather: Cloudy 7~13°C

Turn 1.3
reasoning_content=I have the weather information: "Cloudy 7~13°C". I should provide this to the user in a friendly manner. I'll also mention that it's for tomorrow. Let me craft a response.
content=Tomorrow (December 2, 2025) in Hangzhou, the weather will be **cloudy** with temperatures ranging from **7°C to 13°C**.
tool_calls=undefined
Turn 2.1
reasoning_content=The user is asking again about Hangzhou's weather tomorrow. I already provided the answer for December 2, 2025. I should check if there's any reason they might be asking again - perhaps they want more details or there's a misunderstanding about the date. Since today is December 1, 2025 (as per the get_date result), tomorrow is indeed December 2, 2025. I already have the weather information: cloudy, 7~13°C. I should just repeat the answer, perhaps with a slightly different phrasing. No need to call the function again since the date hasn't changed. I'll respond with the same information.  
content=The weather in Hangzhou tomorrow (December 2, 2025) will be **cloudy** with temperatures between **7°C and 13°C**.
tool_calls=undefined

看得出来和py的运行结果一样。支持推理过程进行函数调用之后,就可以不用再搓一个ReAct模型的Agent,让模型原生支持ReAct。

相关推荐
发现你走远了17 分钟前
05-权限不是开关:工具调用如何在放行、拦截与追问之间做决定
人工智能·agent·claude
AllData公司负责人25 分钟前
AI大模型数据开发底座系列说明书:AllData集成DB-GPT开源项目建设 AI 多模态分析底座,涵盖模态解析/智能大屏/MCP 扩展!
大数据·数据库·人工智能·gpt·数据采集·数据接入·模态解析
Agent世界1 小时前
用 CDP 做发布自动化:四道机器闸门与产物验收
前端·javascript
总要学点什么1 小时前
第104篇:三维特效-流动墙体效果——让贴图沿墙流动,它却只肯走一条对角线
开发语言·javascript·ecmascript·gis·webgl·材质·cesium
程序员大阳1 小时前
副队长ES6+教程(3)--解构赋值
前端·javascript·es6·赋值·解构
神膘护体小月半2 小时前
css - 元素背景图由 hover 触发,初次加载时闪动的解决办法
前端·javascript·css
程序员大阳2 小时前
副队长ES6+教程(2)--let 与 const
前端·javascript·es6·const·let·var
syyjhchou2 小时前
自己搭企业内部中转站,怎么让请求更容易命中缓存
人工智能·后端·语言模型·aigc
张然Adolf2 小时前
人工智能电力系统应用新手实战指南
人工智能
高洁012 小时前
数据同化与动态状态估计:让孪生持续贴合现实
人工智能·python·深度学习·transformer·迁移学习