什么是 LangChain?
LangChain 是一个功能强大的 AI 框架,专门用于构建基于大语言模型(LLM)的智能应用。它不仅提供了基础的 LLM 调用接口,还通过 Prompt 模板、记忆(Memory)、智能代理(Agents)、知识检索(Retrieval)等模块,让 AI 具备更强的推理、搜索、执行任务的能力
- 官网:https://www.langchain.com
- git:https://github.com/langchain-ai/langchain
什么是AI工作流
工作流,是由各种类型的节点和边组成一个类似流程图的东西。AI工作流,就是融合了AI能力的工作流,例如有些节点就是一个AI大模型。像coze的工作流
工作流可以做什么
有些工作他是有固定流程的,例如hr筛选招聘简历,可能你的输入是一个压缩包,第一步你需要加压压缩包,第二步你需要一个个简历过一遍,然后记录是否符合要求,最后再整理符合要求的简历,给到部门负责人进行第2轮的筛选。这些不管谁做,什么时候做,都有固定的流程步骤,这类的事情,我们就可以做成一个工作流,让他自动的做这些事情。工作流其实并不是什么新事物,是很早就有的概念,也有相关应用,但在AI时代,升级成AI工作流后,工作流就变得异常强大,可以胜任更多以前做不了的事情。
今天就教你不用coze,怎么用langchain写一个工作流
举例
下面这个例子是演示如何根据输入,判断这个输入是属于什么级别的事情,分支节点有:
- 普通事情
- 重要事情
- 重要紧急事情
- 紧急事情
1.首先定义数据结构
我们需要定义一个贯彻整个流程输入输出的数据结构
// 定义状态注解
const StateAnnotation = Annotation.Root({
input: Annotation<string>,
decision: Annotation<string>,
output: Annotation<string>,
});
2.定义和实现各类节点
// 开始节点:接收输入并进行初步处理
asyncfunction startNode(state: typeof StateAnnotation.State) {
console.log("Executing startNode");
// 假设这里对输入进行了一些初步处理
return { ...state }; // 直接返回状态,不做修改
}
// 路由节点:根据输入文本决定后续路径
asyncfunction router(state: typeof StateAnnotation.State) {
console.log("Executing router");
const { input } = state;
let decision = "handleDefault"; // 默认路径
// 模拟异步操作,延时 1 秒
await sleep(1000);
if (input.includes("urgent") && input.includes("important")) {
decision = "handleBoth";
} elseif (input.includes("urgent")) {
decision = "handleUrgent";
} elseif (input.includes("important")) {
decision = "handleImportant";
}
return { ...state, decision };
}
// 处理紧急任务
asyncfunction handleUrgent(state: typeof StateAnnotation.State) {
console.log("Executing handleUrgent");
return { output: "Urgent task handled" };
}
// 处理重要任务
asyncfunction handleImportant(state: typeof StateAnnotation.State) {
console.log("Executing handleImportant");
return { output: "Important task handled" };
}
// 处理紧急且重要的任务
asyncfunction handleBoth(state: typeof StateAnnotation.State) {
console.log("Executing handleBoth");
return { output: "Both urgent and important tasks handled" };
}
// 处理默认任务
asyncfunction handleDefault(state: typeof StateAnnotation.State) {
console.log("Executing handleDefault",state);
return { output: "Default task handled" };
}
3.构建工作流
其实就是定义节点名字,和连线
// 构建工作流
const workflow = new StateGraph(StateAnnotation)
.addNode("startNode", startNode)
.addNode("router", router)
.addNode("handleUrgent", handleUrgent)
.addNode("handleImportant", handleImportant)
.addNode("handleBoth", handleBoth)
.addNode("handleDefault", handleDefault)
.addEdge("__start__", "startNode") // 开始节点不是路由节点
.addEdge("startNode", "router") // 从开始节点到路由节点
.addConditionalEdges(
"router",
(state) => state.decision, // 条件函数:根据 decision 字段决定后续路径
["handleUrgent", "handleImportant", "handleBoth", "handleDefault"]
)
.compile();
重点说明
- addNode 定义流程里面的节点
- addEdge 流程里面的连线
- addConditionalEdges 条件节点需要采用条件连线,即分支
4.测试
const inputs = [
"This is an urgent task",
"This is an important task",
"This is both urgent and important",
"This is a regular task"
];
5.输出结果
6.工作流异常处理
1.超时处理工作流的节点可能出现很长时间都没有答复,这个时候我们需要给这个流程配置个超时时间,不能让流程一直卡着。
const result = await workflow.invoke({ input: "This is an urgent task" }, { timeout: 10000 }); // 设置全局超时时间(整个流程,非单个节点)
2.异常处理工作流执行过程可能出现节点执行异常,包括上述的超时也算异常,异常的处理方式跟普通的代码一样。
(async () => {
try {
const result = await workflow.invoke({ input: "This is an urgent task" }, { timeout: 3000 }); // 设置全局超时时间
console.log(`Output: ${result.output}`);
} catch (error) {
console.error(`Workflow failed: ${error.message}`,error);
}
})();
7.完整代码
import { StateGraph, Annotation } from"@langchain/langgraph";
// 封装 sleep 函数
function sleep(ms: number): Promise<void> {
returnnewPromise((resolve) => setTimeout(resolve, ms));
}
// 定义状态注解
const StateAnnotation = Annotation.Root({
input: Annotation<string>,
decision: Annotation<string>,
output: Annotation<string>,
});
// 开始节点:接收输入并进行初步处理
asyncfunction startNode(state: typeof StateAnnotation.State) {
console.log("Executing startNode");
// 假设这里对输入进行了一些初步处理
return { ...state }; // 直接返回状态,不做修改
}
// 路由节点:根据输入文本决定后续路径
asyncfunction router(state: typeof StateAnnotation.State) {
console.log("Executing router");
const { input } = state;
let decision = "handleDefault"; // 默认路径
// 模拟异步操作,延时 1 秒
await sleep(1000);
if (input.includes("urgent") && input.includes("important")) {
decision = "handleBoth";
} elseif (input.includes("urgent")) {
decision = "handleUrgent";
} elseif (input.includes("important")) {
decision = "handleImportant";
}
return { ...state, decision };
}
// 处理紧急任务
asyncfunction handleUrgent(state: typeof StateAnnotation.State) {
console.log("Executing handleUrgent");
return { output: "Urgent task handled" };
}
// 处理重要任务
asyncfunction handleImportant(state: typeof StateAnnotation.State) {
console.log("Executing handleImportant");
return { output: "Important task handled" };
}
// 处理紧急且重要的任务
asyncfunction handleBoth(state: typeof StateAnnotation.State) {
console.log("Executing handleBoth");
return { output: "Both urgent and important tasks handled" };
}
// 处理默认任务
asyncfunction handleDefault(state: typeof StateAnnotation.State) {
console.log("Executing handleDefault",state);
return { output: "Default task handled" };
}
// 构建工作流
const workflow = new StateGraph(StateAnnotation)
.addNode("startNode", startNode)
.addNode("router", router)
.addNode("handleUrgent", handleUrgent)
.addNode("handleImportant", handleImportant)
.addNode("handleBoth", handleBoth)
.addNode("handleDefault", handleDefault)
.addEdge("__start__", "startNode") // 开始节点不是路由节点
.addEdge("startNode", "router") // 从开始节点到路由节点
.addConditionalEdges(
"router",
(state) => state.decision, // 条件函数:根据 decision 字段决定后续路径
["handleUrgent", "handleImportant", "handleBoth", "handleDefault"]
)
.compile();
// 测试工作流
const inputs = [
"This is an urgent task",
"This is an important task",
"This is both urgent and important",
"This is a regular task"
];
for (const input of inputs) {
console.log(`\nProcessing input: ${input}`);
const result = await workflow.invoke({ input });
console.log(`Output: ${result.output}`);
}
结语
看到这里,大家不知道会不会觉得,工作流是不是把普通简单的事情复杂化了?例如同样的事情,如果不采用工作流的做法,自己写个代码更简单,更快就能完成。确实是这样。但相信你写的代码肯定是把工作流里面的流程写在某个函数里面,这样的代码相比工作流,灵活性就要差很多,例如我们想做一个跟coze一样可以随意变化的工作流,就需要将流程的搭建过程抽象出来,支持动态关联。
如何零基础入门 / 学习AI大模型?
大模型时代,火爆出圈的LLM大模型让程序员们开始重新评估自己的本领。 “AI会取代那些行业?
”“谁的饭碗又将不保了?
”等问题热议不断。
不如成为「掌握AI工具的技术人」
,毕竟AI时代,谁先尝试,谁就能占得先机!
想正式转到一些新兴的 AI 行业,不仅需要系统的学习AI大模型。同时也要跟已有的技能结合,辅助编程提效,或上手实操应用,增加自己的职场竞争力。
但是LLM相关的内容很多,现在网上的老课程老教材关于LLM又太少。所以现在小白入门就只能靠自学,学习成本和门槛很高
那么我作为一名热心肠的互联网老兵,我意识到有很多经验和知识值得分享给大家,希望可以帮助到更多学习大模型的人!至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
这份完整版的大模型 AI 学习资料已经上传优快云,朋友们如果需要可以微信扫描下方优快云官方认证二维码免费领取【保证100%免费
】
👉 福利来袭
优快云大礼包:《2025最全AI大模型学习资源包》免费分享,安全可点 👈
全套AGI大模型学习大纲+路线
AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!
640套AI大模型报告合集
这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。
👉学会后的收获:👈
• 基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;
• 能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;
• 基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;
• 能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习框架等技术,这些技术的掌握可以提高程序员的编码能力和分析能力,让程序员更加熟练地编写高质量的代码。
👉 福利来袭
优快云大礼包:《2025最全AI大模型学习资源包》免费分享,安全可点 👈
这份完整版的大模型 AI 学习资料已经上传优快云,朋友们如果需要可以微信扫描下方优快云官方认证二维码免费领取【保证100%免费
】
作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量。