DeepSeek + LangGraph: 探讨并评测推理模型在Agent应用上的能力与表现|深度

DeepSeek火爆出圈,特别是对标Open o1的R1模型,其更低的提示门槛与深度推理能力加速了AI应用的普及。不过,相对于个人应用侧的狂热,我们还需要更客观与科学的关注其在商业领域的生产力应用上的能力与表现。

不过现在你可能会好奇:既然DeepSeek-R1擅长深度“思考”,那么在更需要自主规划能力的Agent应用中,它是否有更好的表现呢?本文将以最常见的ReAct范式的Agent来探讨这个问题,不过,结果可能会颠覆你的预期。

01

什么是ReAct Agent?

ReAct(Reasoning + Acting)是一种结合推理(Reasoning)行动(Acting)的 AI 智能体范式。其核心理念是让 AI 先进行思考推理,再据此采取行动,如调用外部工具;经过多次这样循环,直到任务完成。

简单的说就是:

给Agent安上手脚(Tools)和大脑(LLM),让它自己思考,并借助手脚完成任务。

所以,ReAct Agent的特点是:

  • 自主规划能力:自行推理多子任务步骤,并在过程中动态调整

  • 工具使用:支持与API、数据库、搜索引擎等交互,以完成任务

  • 更高的灵活性:相对于有固定流程的Workflows,任务更灵活

  • 存在不可控性:LLM输出的不确定性可能会带来一定不可控性

02

ReAct Agent需要哪些推理能力

ReAct Agent是一种高度依赖于LLM的智能体,其需要的推理能力包括:

* 多任务步骤的规划与推理

  • 根据输入任务与工具等信息推理出子任务,并合理安排顺序

  • 理解推理历史与观察工具结果,动态规划,调整决策,避免冗余等

比如这样的任务:

“了解公司新品的网络评价,如果偏负面,则发送邮件到产品经理。”

这个任务需要LLM最终能够规划出类似下面的任务步骤,注意这个规划是要在过程中动态完成的,因为你无法事先得知网络评价的结果:

* 工具使用的推理

能够推理子任务需要使用的工具,及其结构化的输入参数。这通常借助LLM的Function Calling特性或者提示工程(Prompt)来实现。

* 协助子任务的执行

除了任务步骤的推理,当然LLM也可以用来协助完成某个具体任务。比如在一个研究智能体中,辅助生成论文提纲等。

我们重点关注前两种推理能力,这是体现Agent自主能力的核心。

03

手搓支持DeepSeek-R1的ReAct Agent

一个典型的ReAct Agent的Graph图表示如下:

在LangGraph中构建ReAct Agent最快捷的方法是使用官方提供的prebuilt函数:

但这个方法对我们并不适用。因为这个方法有一个强制要求:

大模型必须支持Function Calling(函数调用),因为其内部实现需要借助LLM的Function Calling功能来推理下一个步骤与工具!而目前的推理模型都不支持函数调用。

所以,我们必须要使用LangGraph来自行实现这个Agent,这需要使用提示工程来要求LLM进行任务步骤推理。这里仅展示核心过程:

1. 提示词

设计ReAct范式的Prompt如下:

...  
  
# ReAct 提示格式   
REACT_PROMPT = '''  
你被设计用于帮助完成各种输入任务,包括回答问题、内容创作、自动化处理等。  
  
## 工具  
你可以使用各种工具,并且需要自行决定使用工具的顺序,以完成当前任务。  
这可能需要将任务拆分为多个子任务,并使用不同的工具来完成各个子任务。  
你可以使用以下工具:  
  
{tools_desc}  
  
## 输出格式  
如果本次需要使用工具完成某个子任务,请按照以下格式输出:  
```c
Thought: 我需要使用一个工具来帮助回答这个问题。  
Action: 工具名称 ({tool_names} 中选择一个工具),如果需要使用工具的话。  
Action Input: 传递给工具的输入,使用 JSON 格式表示参数(例如:{{"query": "你好"}})。  

注意:

  • 始终以“Thought”开头。
  • 绝对不要在你的响应外部使用 Markdown 代码标记,但如果在你的回答中需要,你可以在适当的位置使用代码标记。
  • 请使用有效的JSON 格式作为Action Input。不要使用类似 {{‘input’: ‘你好世界’, ‘num_beams’: 5}} 这种错误格式。
  • 一次响应最多只能使用一个工具以完成一个子任务。不要在一次响应中出现多个Action。

如果你已经获得足够的信息而来输出最终回答,则必须使用以下两种格式之一来输出最后答案:

Thought: 我可以在不使用更多工具的情况下回答问题。  
Answer: [你的回答 (与用户问题的语言相同)]  
Thought: 我无法使用提供的工具回答该问题。  
Answer: [你的回答 (与用户问题的语言相同)]  

注意:

  • 确保所有子任务都完成后才输出最终答案
  • 最终回答尽量涵盖用户任务的所有方面

当前对话

以下是当前的对话历史, 由人类、AI的消息交替组成。

‘’’

2. 准备Tools

准备几个简单的模拟Tool,交给Agent使用:

  • 网络搜索(network_search)

  • 计算器(caculator)

  • 文本摘要与总结(document_summarizer)

  • 电子邮件发送(Email)

代码大致如下(省略了内部逻辑):

...  
  
# 定义4个模拟工具  
@tool  
def network_search(query: str) -> str:  
    """  
    用于执行网络搜索并返回搜索结果  
    Args:  
        query (str): 要进行网络搜索的关键词  
    """  
    print_colored(f'调用tool: network_search, 输入: {query}', 'green')  
    try:  
        # 调用 TavilySearchResults 来执行搜索,模拟返回结果  
        results = TavilySearchResults(max_results=2).invoke({"query": query})  
        return f"搜索结果: {results}"  
    except Exception as e:  
        return f"搜索错误: {str(e)}"  
      
@tool  
def calculator(query: str) -> str:  
    """  
    用来执行加减乘除计算  
    Args:  
        query (str): 要计算的表达式,如1+2*3  
    """  
  ...  
  
@tool  
def document_summarizer(text: str) -> str:  
    """  
    用来提炼与总结文本的核心内容,形成摘要  
    Args:  
        text (str): 要总结的文本内容  
    """  
  ...  
@tool  
def email(recipient, subject, body) -> str:  
    """  
    用于发送电子邮件  
    Args:  
        recipient (str): 收件人的电子邮件地址  
        subject (str): 电子邮件的主题  
        body (str): 电子邮件的正文  
    """  
...

3. 实现核心推理逻辑(借助LLM)

这个是整个流程的核心部分,主要职责是调用LLM进行任务推理:

  1. 通过提示词与对话历史让LLM推理下一步行动

  2. 如果需要调用工具,则给出结构化的调用信息

  3. 如果无需再调用工具,则输出LLM给出的答案

  4. 如果达到最大迭代次数仍未完成任务,则报错

实现如下(代码中的llm将在后面测试中使用不同模型如Deepseek-R1来替换):

...  
llm = ChatOpenAI(model='gpt-4o-mini')  
tools = [network_search,calculator,document_summarizer,email]  
  
async def call_model(  
    state: State, config: RunnableConfig  
) -> Dict[str, List[AIMessage]]:  
      
    # 生成工具描述  
    tools_desc = "\n".join([  
        f"- {tool.name}: {tool.description}\n"   
        for tool in tools  
    ])  
  
    tool_names = [tool.name for tool in tools]  
  
    # 生成 ReAct 提示  
    system_prompt = REACT_PROMPT.format(  
        tools_desc=tools_desc,  
        tool_names=tool_names  
    )  
  
    # 这一步需要根据不同模型增加或注释  
    state.messages = [HumanMessage(content=msg.content) if "ToolMessage" in msg.__class__.__name__ else msg for msg in state.messages]  
  
    # 调用 LLM,输入提示词(system_prompt)和对话历史(messages)  
    response = await llm.ainvoke([SystemMessage(content=system_prompt)] + state.messages)  
    content = response.content  
      
    print_colored("\n===========================Reasoning================================", 'magenta')  
    print_colored(f'{content}', 'magenta')  
    print_colored("=========================Reasoning End================================\n", 'magenta')  
  
    if "Action:" in content and "Action Input:" in content:  
  
        # 提取工具调用信息  
        action_lines = [line for line in content.split('\n') if line.startswith('Action:') or line.startswith('Action Input:')]  
        tool_name = action_lines[0].replace('Action:', '').strip()  
        tool_input = action_lines[1].replace('Action Input:', '').replace("'",'"').strip()  
        tool_input = tool_input.replace('\\', '\\\\')  
          
        response.tool_calls = [{  
            "id": "call_1",  
            "type": "function",  
            "name": tool_name,  
            "args": json.loads(tool_input)  
            }  
        ]  
  
    if state.is_last_step and response.tool_calls:  
        return {  
            "messages": [  
                AIMessage(  
                    content="对不起,我在指定的步骤数内无法找到问题的答案。"  
                )  
            ]  
        }  
  
    return {"messages": [response]}

4. 创建Graph

完成了核心的推理节点,就可以创建这个Graph(Tools调用借助官方ToolNode组件即可):

@dataclass  
class InputState:  
    messages: Annotated[Sequence[AnyMessage], add_messages] = field(  
        default_factory=list  
    )  
  
@dataclass  
class State(InputState):  
  
    is_last_step: IsLastStep = field(default=False)  
  
builder = StateGraph(State, input=InputState)  
builder.add_node(call_model)  
builder.add_node("tools", ToolNode(tools))  
builder.add_edge("__start__", "call_model")  
  
# 定义一个函数,根据模型输出的内容来决定下一个节点;如果有工具调用,则转向tools  
def route_model_output(state: State) -> Literal["__end__", "tools"]:  
    last_message = state.messages[-1]  
    if not isinstance(last_message, AIMessage):  
        raise ValueError(  
            f"Expected AIMessage in output edges, but got {type(last_message).__name__}"  
        )  
      
    if not last_message.tool_calls:  
        return "__end__"  
      
    return "tools"  
  
# 添加条件边  
builder.add_conditional_edges(  
    "call_model",  
    route_model_output,  
)  
builder.add_edge("tools", "call_model")  
  
# 编译  
graph = builder.compile()  
graph.name = "ReAct Agent"

5. 验证可用性

现在你可以使用graph.invoke方法来输入任务,以测试这个ReAct Agent。按照预期,它应该能够理解你的自然语言输入任务,并使用已有的四个工具(搜索、计算器、摘要、邮件发送)来完成。为了更好的观察,我们加入一些跟踪信息,以展示LLM的推理过程。

这里先用一个简单任务看下效果(模型gpt-4o-mini):

可以看到,第一次推理,LLM认为需要使用搜索工具;第二次推理,因为观察到工具返回(这里未打印),LLM已经可以正确回答问题了!

04

不同模型的ReAct Agent评测

现在我们使用不同难度的任务来考察类似DeepSeek- R1这样的推理模型,在ReAct Agent中的多任务步骤推理时的表现,并同通用模型做对比。

测试任务(从简单到复杂)

  • “搜索《哪吒2》的最新票房数据”,

  • “搜索《哪吒2》的详细剧情介绍,并发送到test@gmail.com”,

  • “搜索《哪吒2》的最新票房,如果超过50亿,再帮我搜索《哪吒3》的上映时间; 如果没有超过50亿,则创作一段加油的文字。最后把结果发邮件到test@gmail.com”

对比模型:

  • gpt-4o-mini

  • doubao-1.5-32k

  • deepseek-v3(官方)

  • deepseek-r1(官方)

  • deepseek-r1:7b(开源)

  • qwen-2.5:7b(开源)

测试方法:

  • 在不改变其他代码与提示的情况下,切换不同的模型

  • 依次输入3个测试任务,每个任务测试多次,观察结果

  • 确保每次任务是独立的,不记忆之前的任务历史

测试结果:


任务一任务二
任务三
gpt-4o-mini
Yes
YesYes
doubao-1.5-32kyesyesyes
deepseek-v3
yesyesyes
deepseek-r1
yesyes * no
deepseek-r1:7byesno *
no
qwen-2.5:7byesyes
no
  • yes: 全部成功,且推理过程输出符合预期

  • no:全部失败,未获得期望结果甚至异常

  • yes*: 代表大部分成功,偶尔失败;或者结果成功,但推理过程不符预期

  • no*: 代表大部分失败,偶尔成功

DeepSeek-R1失败的主要现象:

1. 不遵循逐步推理的指令。即一次性返回包含多个Thought-Action行动步骤的完整任务过程(尽管这个过程可能是正确的)。如这次:

2. 基于假设(幻觉)推理。在第一步的子任务推理后,有时候会自作主张的“假设”一个工具调用结果,并据此做后续步骤推理(r1:7b模型)。

3. 遗漏某个任务步骤。比如某一次任务3的测试中,未推理与执行“发送邮件”这一步骤,但最终却有如下“貌似完美”的输出:

4. 输出格式不能稳定遵循指令要求。比如下图中,自行添加了’json’标记,当然格式的问题有时候可以通过代码来容错,但也可能会直接异常:

我们来看一下最复杂的任务3的成功输出,推理过程应该类似下图:

05

思考与总结

尽管从直觉上你可能会认为“自带Cot(思维链)”的推理模型Deepseek- R1应该更擅长自主的多步骤任务规划与推理,但是事实恰恰相反:

目前的推理模型(DeepSeek-R1、OpenAI的o1等)在Agent需要的自主、多步骤、动态的任务规划能力上还缺乏足够的可用性

下面是我们的一些具体思考与总结:

1. 目前o1,r1这样的推理模型的确擅长step by step的思考问题,但输入任务应该更直接。即复杂性体现在问题本身,而不能是提示词与上下文。比如:

  • 根据需求描述生成复杂的代码

  • 解决一道复杂的数学问题

  • 进行一项科学计算与研究

  • 根据主题生成有深度的论文

而以下类型的任务它目前并不擅长:

  • 基于复杂上下文与对话历史的推理任务

  • 有严格的指令遵循与结构化输出要求的任务

  • 依赖于Function Calling功能的智能体任务

这里的结构化输出可以借助辅助LLM来完善;Function Calling也可以借助提示词来获得,但是第一个问题则需要等待模型进化。

2. 具体到AI Agent应用,特别是ReAct Agent,由于其更依赖于LLM的多任务步骤推理能力。我们建议:

  • 在任务步骤的动态规划与推理上,通用模型目前更适合,比如GPT-4o,DeepSeek-v3;且参数越大的模型越稳定

  • 推理模型,包括满血的DeepSeek-R1,以及开源的1.5b等蒸馏版本,都不建议用作Agent的任务步骤推理;但是可以作为一个Tool来完成某个子任务,比如根据搜索结果编写一份有深度的报告

  1. 推理模型在Agent中应用的另一个问题是响应性能,由于其深度思考的特点,其响应时间普遍较长,这是制约其在企业级应用的另一个问题。

以上的一些结论刚好也验证了DeepSeek-R1官方技术报告揭示的自身“能力缺陷”,包括不支持function calling、不擅长多轮对话、结构化输出较弱、提示词与复杂上下文敏感等,我们也期待下一个版本的R1在这些能力上取得突破!

如何学习大模型 AI ?

由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。

但是具体到个人,只能说是:

“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。

这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

在这里插入图片描述

第一阶段(10天):初阶应用

该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。

  • 大模型 AI 能干什么?
  • 大模型是怎样获得「智能」的?
  • 用好 AI 的核心心法
  • 大模型应用业务架构
  • 大模型应用技术架构
  • 代码示例:向 GPT-3.5 灌入新知识
  • 提示工程的意义和核心思想
  • Prompt 典型构成
  • 指令调优方法论
  • 思维链和思维树
  • Prompt 攻击和防范

第二阶段(30天):高阶应用

该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。

  • 为什么要做 RAG
  • 搭建一个简单的 ChatPDF
  • 检索的基础概念
  • 什么是向量表示(Embeddings)
  • 向量数据库与向量检索
  • 基于向量检索的 RAG
  • 搭建 RAG 系统的扩展知识
  • 混合检索与 RAG-Fusion 简介
  • 向量模型本地部署

第三阶段(30天):模型训练

恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。

到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?

  • 为什么要做 RAG
  • 什么是模型
  • 什么是模型训练
  • 求解器 & 损失函数简介
  • 小实验2:手写一个简单的神经网络并训练它
  • 什么是训练/预训练/微调/轻量化微调
  • Transformer结构简介
  • 轻量化微调
  • 实验数据集的构建

第四阶段(20天):商业闭环

对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。

  • 硬件选型
  • 带你了解全球大模型
  • 使用国产大模型服务
  • 搭建 OpenAI 代理
  • 热身:基于阿里云 PAI 部署 Stable Diffusion
  • 在本地计算机运行大模型
  • 大模型的私有化部署
  • 基于 vLLM 部署大模型
  • 案例:如何优雅地在阿里云私有部署开源大模型
  • 部署一套开源 LLM 项目
  • 内容安全
  • 互联网信息服务算法备案

学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。

如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值