AI创想
标题:
DeepSeek LangGraph 学习
[打印本页]
作者:
AI小编
时间:
昨天 16:06
标题:
DeepSeek LangGraph 学习
作者:CSDN博客
LangGraph背景
但是如果我们不想依赖平台,而是要自己开发一个带有工作流的 AI 应用,这时最好的方法就是借助框架来完成,比如前两年比较火的 LangChain,可以做出一条后面这样的链。
所以这个框架为什么叫 LangChain 也很好理解了,核心就是提供了 Chain(链)的功能。需要注意的是这条链在方向上来说是单向的,不能够向回流或者循环。
不过随着 AI 逐渐深入到业务,在落地一些应用的时候,大家就发现使用这种单向的链,有些应用搞不定,比如之前讲过的 AgenticRAG,也有人叫 GraphRAG。因为这样的应用不仅要有分支的功能,还要具备循环的功能。这时就需要用图结构来表示业务了。
(, 下载次数: 0)
上传
点击文件名下载附件
去年 LangChain 开发了一个扩展库,取名叫 LangGraph。这个库功能很强大,因为能够实现图的方式,解决 AgenticRAG 那是小菜一碟。
LangGraph编程学习
登录后复制
pip install langgraph
1.
登录后复制
from langgraph.graph import StateGraph, START,ENDdefsupermarket(state):return{"ret":"{}买到了".format(state["ingredients"])}if __name__ =="__main__": sg = StateGraph(dict)# 定义第一个节点 sg.add_node("supermarket", supermarket)# 定义起始边 sg.add_edge(START,"supermarket")# 定义结束边 sg.add_edge("supermarket", END) graph = sg.compile() ret = graph.invoke({"ingredients":"羊排"})print(ret)
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.
在代码的第 7 行,首先使用 StateGraph 方法定义了一个 Graph,可以理解为类似 Dify 创建了一个工作流。
登录后复制
from langgraph.graph import StateGraph, START,ENDdefsupermarket(state):print("supermarket")return{"ret":"{}买到了".format(state["ingredients"])}defrecipe(state):print("recipe")return{"ret":"搜到了菜谱"}defcooking(state):print("cooking")return{"ret":"做了一道菜"}if __name__ =="__main__": sg = StateGraph(dict)# 定义节点 sg.add_node("supermarket", supermarket) sg.add_node("recipe", recipe) sg.add_node("cooking", cooking)# 定义起始边 sg.add_edge(START,"supermarket")# 定义普通边 sg.add_edge("supermarket","recipe") sg.add_edge("recipe","cooking")# 定义结束边 sg.add_edge("cooking", END) graph = sg.compile() ret = graph.invoke({"ingredients":"羊排"})print(ret)
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.31.32.33.34.35.36.
因此如果想让“羊排”在节点间流转,应该在每一步都保存一下。但是基于目前的机制还有一个问题,那就是第一个节点的输出,同样也只能在第二个节点中拿到,在第三个节点中就拿不到了。
如果我想把每一步的输出也都保存下来,那代码应该这么写:
登录后复制
classState(TypedDict): ingredients:str ret:listdefsupermarket(state):print("supermarket")return{"ingredients": state["ingredients"],"ret":["{}买到了".format(state["ingredients"])]}defrecipe(state):print("recipe") last_ret = state["ret"]return{"ingredients": state["ingredients"],"ret": last_ret +["搜到了红烧{}的菜谱".format(state["ingredients"])]}defcooking(state):print("cooking") last_ret = state["ret"]return{"ingredients": state["ingredients"],"ret": last_ret +["做了一道红烧{}".format(state["ingredients"])]}
1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.
一共有两处改动。第一,State 我不直接用 dict 类型了,而是写一个 State 类,里面存放两个变量,一个是每一步都需要的 ingredients 变量,也就是“羊排”。另一个修改则是每一步的返回值 ret,由于需要存多个 ret,因此需要把它定义成列表。
GraphRAG
GraphRAG 的核心是知识图谱 + 图搜索
Graph RAG 的第一步,就是从非结构化文本中提取信息,构建一个知识图谱。这个过程可以通过 LLM 来完成。
提取代码描述
像是代码这种文本,其结构特点是由一个个的函数组成。因此对于这样的文本去构建知识图谱,是非常困难的。因为我们不管怎么切割文本,也都很难保证函数的完整性。除非将函数截成一张张的图片,然后利用视觉模型进行识别,然后再入库等,这就很麻烦了。
因此我们最好是先做一下预处理,用 LLM 将每一个代码文件的描述提取出来,基于描述文本再去构建知识图谱就会简单得多。
使用的Cursor 对文件进行的描述,具体方法是,我们在 Cursor 中打开该项目,然后点击打开一个文件后,按住 Ctrl + L,就会召唤出对话模式。此时我们贴入提示词即可,提示词如下:
依次将所有文件的描述全部提取出来,放入到一个 txt 文件中,留着待会使用 GraphRAG 构建知识图谱使用。
安装GraphRAG
编辑配置文件settings.yaml
将 models 里的 default_chat_model 以及 default_embedding_model 的信息从 OpenAI 改成我们自己国内的,比如 DeepSeek。当然如果你的服务器能访问 openai,那直接使用 OpenAI 也行。
其中 api_base、api_key 和 model 需要我们修改一下。这里 chat model 我用的是 deepseek-chat,embedding 用的是通义千问的 text-embedding-v1
代码分析测试
可以看到其将所有的相关代码描述都列出来了,而且还做了总结。
继续查询另一个
登录后复制
graphrag query--root ./graphrag/ --methodlocal--query"获取单个产品用到了哪个模型 "
1.
列出了 Product 实体类的结构,而且还做了代码分析等,效果是非常好的,这是 LLM + 传统 RAG 达不到的效果。
原文地址:https://blog.csdn.net/weixin_44066506/article/details/150353748
欢迎光临 AI创想 (https://llms-ai.com/)
Powered by Discuz! X3.4