天醒 發表於 2025-8-14 11:27:00

langgraph开发Deep Research智能体-项目搭建

<h1 id="前言">前言</h1>
<p>大家都说2025年是AI Agent元年,自然agent智能体开发也非常热门。很多公司的所谓的智能体其实是通过扣子、dify这种平台配出来的。就像是通过低代码平台配置出来的web页面一样,虽然能用,但是如果你的需求很复杂,往往平台就无法满足你的需求。作为程序员所以我们还是得需要自己动手来实现智能体,这篇文章我们来讲讲如何使用<code>langgraph</code>搭建一个<code>node.js</code>项目来实现一个Deep Research智能体。</p>
<p>加入欧阳的AI交流群</p>
<h1 id="什么是agent智能体项目">什么是agent智能体项目?</h1>
<p>智能体对外提供的服务就是API接口,所以agent智能体项目其实就是一个普通的提供<code>restful</code>接口的后端项目,只是这个项目中的API大多数都是流式的。langgraph官方提供了<code>python</code>和<code>nodejs</code>两种支持,在座的各位大部分都是前端开发,所以我们使用node.js来搭建智能体项目。</p>
<h1 id="搭建一个express项目">搭建一个express项目</h1>
<p>我这里是使用的是<code>express</code>,项目初始化就是使用的官方提供的<code>npx express-generator</code>,执行后生成的项目大概是这样的:</p>
<p><img alt="express-generator" width="1025" height="443" loading="lazy" src="https://img2024.cnblogs.com/blog/1217259/202508/1217259-20250814105657071-1986962929.png" class="lazyload"></p>
<p>初始化后就生成了一个最简单的express项目,但是这个项目使用的是js。我们期望使用<code>ts</code>,所以需要再额外引入ts相关的依赖,此时的package.json文件大概是下面这样的:</p>
<pre><code class="language-json">{
"scripts": {
    "dev": "nodemon --watch src --ext ts,json,md --ignore dist --ignore node_modules --exec \"npx ts-node ./bin/www"",
},
"devDependencies": {
    "nodemon": "^3.0.3",
    "ts-node": "^10.9.2",
    "typescript": "^5.3.3"
}
}
</code></pre>
<p>为了支持ts我们引入了<code>ts-node</code>和<code>typescript</code>,同时为了支持热更新我们引入了<code>nodemon</code>,并且也修改了<code>scripts</code>中的<code>dev</code>命令。</p>
<h1 id="引入langgraph">引入langgraph</h1>
<p>有的同学只听过<code>langchain</code>,没有听说过<code>langgraph</code>,他们两个有没有关系呢?</p>
<p>当然有关系了,<code>langgraph</code>和<code>langchain</code>都是同一个团队开发的,他们都可以用于开发agent智能体。</p>
<p>举个不恰当的例子:</p>
<ul>
<li>不使用任何大模型框架开发agent智能体就像是使用<code>原生javascript</code>直接操作DOM进行前端开发。</li>
<li>使用langchain开发agent智能体就像是使用<code>jquery</code>来进行前端开发。</li>
<li>使用langgraph开发agent智能体就像是使用<code>vue</code>来进行前端开发。</li>
</ul>
<p>所以现在<code>langchain</code>官方也推荐开发agent智能体时使用<code>langgraph</code>,不过一般我们还是会同时使用<code>langchain</code>。</p>
<p>大概会引入下面这些包:</p>
<pre><code class="language-json">
"dependencies": {
    "@langchain/community": "^0.3.50",
    "@langchain/core": "^0.3.66",
    "@langchain/deepseek": "^0.1.0",
    "@langchain/langgraph": "^0.4.3",
    "@langchain/openai": "^0.6.7",
    "@langchain/tavily": "^0.1.5",
}
</code></pre>
<h1 id="项目结构">项目结构</h1>
<p>既然是开发agent智能体,项目结构肯定和普通的express项目不一样。所以项目结构需要调整一下,我们把项目结构调整成下面这样:</p>
<pre><code>src
├─ agents
├─ config
├─ graph
├─ llms
├─ prompts
├─ routes
├─ server
│└─ app.ts
├─ tools
├─ utils
</code></pre>
<ul>
<li><code>agents</code>目录用于存放agent智能体。</li>
<li><code>config</code>目录用于存放配置。</li>
<li><code>graph</code>目录用于存放langgraph的代码,定义图的结构和node节点。</li>
<li><code>llms</code>目录用于存放大模型,一个项目会使用多个大模型。</li>
<li><code>prompts</code>目录用于存放prompt提示词。</li>
<li><code>routes</code>目录用于存放API接口路由。</li>
<li><code>server</code>里面的<code>app.ts</code>就是项目的启动文件。</li>
<li><code>tools</code>目录用于存放agent智能体中使用的工具。</li>
<li><code>utils</code>目录用于存放项目中使用的工具函数。</li>
</ul>
<p>项目的启动文件变成了<code>server/app.ts</code>,所以scripts中的<code>dev</code>命令需要修改一下:</p>
<pre><code class="language-json">"scripts": {
"dev": "nodemon --watch src --ext ts,json,md --ignore dist --ignore node_modules --exec \"npx ts-node src/server/app.ts\"",
}
</code></pre>
<p>启动文件<code>server/app.ts</code>的代码也很简单:</p>
<pre><code class="language-ts">
import dotenv from "dotenv";
import express, { Express } from "express";
import chatRouter from "../routes/chat";

dotenv.config();
const app: Express = express();
const port = process.env.PORT || 3001;

// ...省略
app.post("/api/chat/stream", chatRouter);
// ...省略

app.listen(port, () =&gt; {
console.log(`Server is running on port ${port}`);
});

export default app;
</code></pre>
<p>我们提供的<code>/api/chat/stream</code>是一个流式接口,给智能体提供类似于ChatGPT的聊天功能。</p>
<h1 id="在开发环境调试和追踪智能体运行过程">在开发环境调试和追踪智能体运行过程</h1>
<p>传统的后端项目只要代码没bug,项目的运行过程也基本是确定的,所以我们可以通过日志来分析代码的运行过程。</p>
<p>由于大模型的输出具有随机性,所以智能体的运行过程也是不确定的,如果通过日志来分析智能体的运行过程,可能就不太够用了。</p>
<p>并且智能体项目的开始一般是用户的输入,结束是智能体的输出。在开发环境一般就会面临几个问题:</p>
<ul>
<li>由于langgraph是基于图设计的(和状态机很类似),接触一个新智能体项目,单纯通过代码无法直观的分析出智能体可能的运行流程。如果将代码转换成<code>if/else</code>来理解,那么langgraph中就会包含大量的<code>if/else</code>,你当然不能清晰的分析出智能体的运行过程</li>
<li>项目中有多个智能体,每个智能体又会有多个节点,由于大模型输出的随机性导致智能体的运行过程并没有按照我们编排的期望流程去执行。通过日志去分析智能体的运行过程来找bug有点难。</li>
<li>想要从中间某个流程开始去debug代码,我们不得不让代码从头开始运行,而不是从我们想要debug代码的部分开始运行</li>
</ul>
<p>说了这么多,有没有什么解决方案呢?</p>
<p>有,可以使用<code>@langchain/langgraph-cli</code>这个脚手架,可以帮我们创建、开发和部署 LangGraph.js 项目。</p>
<p>我这边使用的是他提供的<code>开发</code>服务,可以解决前面我们提到的那几个问题。</p>
<p>在<code>scripts</code>中新增一个<code>start</code>命令用于启动<code>@langchain/langgraph-cli</code>脚手架提供的服务器:</p>
<pre><code class="language-json">"scripts": {
"dev": "nodemon --watch src --ext ts,json,md --ignore dist --ignore node_modules --exec \"npx ts-node src/server/app.ts\"",
"start": "npx @langchain/langgraph-cli dev --port 2025 --config ./langgraph.json",
}
</code></pre>
<p>指定端口为<code>2025</code>,并且给脚手架指定配置文件为根目录的<code>langgraph.json</code>文件。</p>
<p>执行<code>yarn start</code>可以在终端看见这样的输出:<br>
<img alt="cli" width="662" height="282" loading="lazy" src="https://img2024.cnblogs.com/blog/1217259/202508/1217259-20250814105717637-375951484.png" class="lazyload"></p>
<p>第一个<code>http://localhost:2025</code>就算脚手架帮我们启动的API服务器。</p>
<p>第二个<code>Studio UI: https://smith.langchain.com/studio?baseUrl=http://localhost:2025</code>是一个<code>langsmith</code>的后台页面,需要注册一下,免费的。</p>
<p>注册后就能看到下面的页面:<br>
<img alt="node" width="1511" height="497" loading="lazy" src="https://img2024.cnblogs.com/blog/1217259/202508/1217259-20250814105732639-1341071856.png" class="lazyload"></p>
<p>红框框住的部分就是我这个项目中智能体的运行流程,从_start_节点开始,到_end_节点结束,这样我们就能直观的看到智能体可能会如何运行。</p>
<p>点击顶部的<code>Chat</code>按钮,可以切换到聊天页面:<br>
<img alt="chat" width="1025" height="741" loading="lazy" src="https://img2024.cnblogs.com/blog/1217259/202508/1217259-20250814105745981-216708179.png" class="lazyload"></p>
<p>在输入框中输入内容就能直接调试我们的<code>/api/chat/stream</code>接口,并且还能像ChatGPT一样看到打字机一样的流式输出。如图:<br>
<img alt="stream" width="1302" height="1122" loading="lazy" src="https://img2024.cnblogs.com/blog/1217259/202508/1217259-20250814105801663-1265005088.png" class="lazyload"></p>
<p>点击顶部的<code>Graph</code>切换会图表视图:<br>
<img alt="graph" width="1678" height="1119" loading="lazy" src="https://img2024.cnblogs.com/blog/1217259/202508/1217259-20250814105814512-589527408.png" class="lazyload"></p>
<p>在右侧我们可以看见智能体的完整真实运行流程,其中的<code>coordinator</code>、<code>planner</code>这些是我们编排的节点,可以看见智能体是从一个节点跳转到另一个节点。</p>
<p>将鼠标hover上红框的地方,可以看到运行到每个节点时的<code>state</code>状态,也就是我们代码里面定义的变量值,每个节点对应的<code>state</code>的值都可能不同。</p>
<p>还有一个<code>Re-run from here</code>按钮,点击这个按钮后可以让智能体从当前节点重新开始运行,无需每次都从头开始,这在debug代码时很有用,token成本也降低了。</p>
<p>你可能想问,<code>@langchain/langgraph-cli</code>这么好用,为什么我只用在开发环境,不在生产环境也使用呢?</p>
<p>使用<code>@langchain/langgraph-cli</code>进行部署是付费项目了,这是他们公司提供的SaaS服务,可以将你的服务器部署在他们的平台上,但是langchain是一个国外的公司,所以国内的项目不太合适,不过他们也提供了私有化部署服务。</p>
<h1 id="总结">总结</h1>
<p>这篇文章讲了如何搭建一个Deep Research智能体项目,并且使用<code>@langchain/langgraph-cli</code>在开发环境调试和追踪智能体运行过程。</p>
<p>在我的规划中Deep Research智能体nodejs项目是一个系列文章,代码和功能也会陆续完善,后面会慢慢填坑,源代码地址为:https://github.com/iamouyang21/DeepResearch-Langgraph。(初期源码参考了字节开源的python项目deer-flow)</p><br><br>
来源:https://www.cnblogs.com/heavenYJJ/p/19037337
頁: [1]
查看完整版本: langgraph开发Deep Research智能体-项目搭建