基于 LangChain+LangGraph 来实现一个翻译项目
相信大家在看文档的时候,有时会比较苦恼,比如 AI 相关的文档都是外文,中文文档比较少,看起来会比较吃力,有的时候会看不懂,翻译软件又翻得很乱,完全看不了,今天就基于 LangChain 和 LangGranph 将吴恩达博士的一个项目给搬过来。
一方面就是为了自己看文档方便点,另一方面也是练练手,用用 LangChain 和 LangGraph
什么是 LangGraph
LangGraph 是一个用于构建状态化的、多角色应用程序的库,用于创建代理和多代理工作流程。与其他LLM框架相比,它具备以下核心优势:循环、可控性和持久性。LangGraph 支持定义涉及循环的流程,这对大多数代理架构至关重要,区别于基于DAG的解决方案。作为一个极其底层的框架,它提供对应用程序流程和状态的精细控制,这对创建可靠的代理至关重要。此外,LangGraph 集成了持久性功能,实现高级的人机交互和记忆特性。
LangGraph 的特性
循环和分支:在您的应用中实现循环和条件语句。 状态持久化:在图中的每一步后自动保存状态。支持在任意点暂停和恢复图的执行,以便支持错误恢复、人在回路的工作流程、时间旅行等功能。 人在回路中控制:中断图的执行以批准或编辑代理计划的下一步行动。 流式支持:在每个节点产生输出时即时流式传输(包括令牌流)。 与LangChain的集成:LangGraph与LangChain和LangSmith无缝集成,但并不要求必须使用它们。
以上两段是翻译,官网地址:🦜🕸️LangGraph
安装方式:
pip install -U langgraph
示例:
LangGraph 的核心概念是状态。每一个 graph 执行会产生状态,可以在不同的 nodes 之间传递。每个 node 通过返回值更新内部状态。 graph 更新它的内部状态方式是由选择 graph 的类型或用户自定义函数定义的
导入依赖包
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate,HumanMessagePromptTemplate, SystemMessagePromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langgraph.graph import StateGraph, START, END
from dotenv import find_dotenv, load_dotenv
load_dotenv(find_dotenv()) # 加载相关配置
配置文件
是项目的目录中 .env 文件
定义一个方法用于请求 OpenAI
def llm_invoke(prompt, temperature=0.3):llm = ChatOpenAI(temperature=temperature)chain = {"input": RunnablePassthrough()} | prompt | llm | StrOutputParser()return chain.invoke("")
定义节点间要使用的一个状态类
from typing import TypedDict, Optional
class State(TypedDict):source_lang:strtarget_lang:strsource_text:strcountry:Optional[str] = Nonetranslation_1: Optional[str] = Nonereflection: Optional[str] = Nonetranslation_2: Optional[str] = None
初次翻译
def initial_translation(state):source_lang = state.get("source_lang")target_lang = state.get("target_lang")source_text = state.get("source_text")prompt = ChatPromptTemplate.from_messages([("system",f"You are an expert linguist, specializing in translation from {source_lang} to {target_lang}."),("user", f"""This is an {source_lang} to {target_lang} translation, please provide the {target_lang} translation for this text. \Do not provide any explanations or text apart from the translation.{source_lang}: {source_text}{target_lang}:""")])translation = llm_invoke(prompt)print("[初次翻译结果]:\n", translation)return {"translation_1": translation}
反思第一次翻译
def reflect_on_translation(state):source_lang = state.get("source_lang")target_lang = state.get("target_lang")source_text = state.get("source_text")country = state.get("country") or ""translation_1 = state.get("translation_1")additional_rule = (f"The final style and tone of the translation should match the style of {target_lang} colloquially spoken in {country}."if country != ""else "")prompt = ChatPromptTemplate.from_messages([("system", f"You are an expert linguist specializing in translation from {source_lang} to {target_lang}. \You will be provided with a source text and its translation and your goal is to improve the translation."),("user",f"""Your task is to carefully read a source text and a translation from {source_lang} to {target_lang}, and then give constructive criticism and helpful suggestions to improve the translation. \{additional_rule}The source text and initial translation, delimited by XML tags <SOURCE_TEXT></SOURCE_TEXT> and <TRANSLATION></TRANSLATION>, are as follows:<SOURCE_TEXT>{source_text}</SOURCE_TEXT><TRANSLATION>{translation_1}</TRANSLATION>When writing suggestions, pay attention to whether there are ways to improve the translation's \n\(i) accuracy (by correcting errors of addition, mistranslation, omission, or untranslated text),\n\(ii) fluency (by applying {target_lang} grammar, spelling and punctuation rules, and ensuring there are no unnecessary repetitions),\n\(iii) style (by ensuring the translations reflect the style of the source text and takes into account any cultural context),\n\(iv) terminology (by ensuring terminology use is consistent and reflects the source text domain; and by only ensuring you use equivalent idioms {target_lang}).\n\Write a list of specific, helpful and constructive suggestions for improving the translation.Each suggestion should address one specific part of the translation.Output only the suggestions and nothing else.""")])reflection = llm_invoke(prompt)print("[反思结果]:\n", reflection)return {"reflection": reflection}
根据反思改进翻译结果
def improve_translation(state):source_lang = state.get("source_lang")target_lang = state.get("target_lang")source_text = state.get("source_text")translation_1 = state.get("translation_1")reflection = state.get("reflection")prompt = ChatPromptTemplate.from_messages([("system", f"You are an expert linguist, specializing in translation editing from {source_lang} to {target_lang}."),("user", f"""Your task is to carefully read, then edit, a translation from {source_lang} to {target_lang}, taking intoaccount a list of expert suggestions and constructive criticisms.The source text, the initial translation, and the expert linguist suggestions are delimited by XML tags <SOURCE_TEXT></SOURCE_TEXT>, <TRANSLATION></TRANSLATION> and <EXPERT_SUGGESTIONS></EXPERT_SUGGESTIONS> \as follows:<SOURCE_TEXT>{source_text}</SOURCE_TEXT><TRANSLATION>{translation_1}</TRANSLATION><EXPERT_SUGGESTIONS>{reflection}</EXPERT_SUGGESTIONS>Please take into account the expert suggestions when editing the translation. Edit the translation by ensuring:(i) accuracy (by correcting errors of addition, mistranslation, omission, or untranslated text),(ii) fluency (by applying {target_lang} grammar, spelling and punctuation rules and ensuring there are no unnecessary repetitions), \(iii) style (by ensuring the translations reflect the style of the source text)(iv) terminology (inappropriate for context, inconsistent use), or(v) other errors.Output only the new translation and nothing else.""")])translation_2 = llm_invoke(prompt)print("[最终翻译结果]:\n", translation_2)return {"translation_2": translation_2}
定义 workflow
workflow = StateGraph(State)# 规划执行任务
## 节点注册
workflow.add_node("initial_translation", initial_translation)
workflow.add_node("reflect_on_translation", reflect_on_translation)
workflow.add_node("improve_translation", improve_translation)
## 连接节点
workflow.set_entry_point("initial_translation")
# 添加连接
workflow.add_edge("initial_translation", "reflect_on_translation")
workflow.add_edge("reflect_on_translation", "improve_translation")
workflow.add_edge("improve_translation", END)
开始执行
# 开始执行
app = workflow.compile()
result = app.invoke({"source_lang":"English","target_lang":"中文","source_text":"""LangGraph is a library for building stateful, multi-actor applications with LLMs, used to create agent and multi-agent workflows. Compared to other LLM frameworks, it offers these core benefits: cycles, controllability, and persistence. LangGraph allows you to define flows that involve cycles, essential for most agentic architectures, differentiating it from DAG-based solutions. As a very low-level framework, it provides fine-grained control over both the flow and state of your application, crucial for creating reliable agents. Additionally, LangGraph includes built-in persistence, enabling advanced human-in-the-loop and memory features."""
})
输出:
[初次翻译结果]:LangGraph 是一个用于构建具有LLMs的有状态、多角色应用程序的库,用于创建代理和多代理工作流程。与其他LLM框架相比,它提供了这些核心优势:循环、可控性和持久性。LangGraph允许您定义涉及循环的流程,这对于大多数代理体系结构至关重要,使其与基于DAG的解决方案有所区别。作为一个非常低级别的框架,它可以对应用程序的流程和状态进行精细控制,这对于创建可靠的代理至关重要。此外,LangGraph还包括内置的持久性,可以实现高级的人在环和内存功能。 [反思结果]:1. 将 "LLMs" 翻译为 "有限状态机" 或 "有限状态机器",以更准确地反映原文中的意思。2. 将 "flows" 翻译为 "流程" 而非 "流程",以更贴近原文的含义。3. 将 "agent and multi-agent workflows" 翻译为 "代理和多代理工作流程" 而非 "代理和多代理工作流程",以提高翻译的流畅度。4. 将 "fine-grained control" 翻译为 "细粒度控制" 而非 "精细控制",以更准确地表达原文的意思。5. 将 "human-in-the-loop" 翻译为 "人在环" 而非 "人在环",以确保术语的一致性和准确性。 [最终翻译结果]:LangGraph 是一个用于构建具有有限状态机的有状态、多角色应用程序的库,用于创建代理和多代理工作流程。与其他有限状态机框架相比,它提供了这些核心优势:循环、可控性和持久性。LangGraph允许您定义涉及流程的流程,这对于大多数代理体系结构至关重要,使其与基于DAG的解决方案有所区别。作为一个非常低级别的框架,它可以对应用程序的流程和状态进行细粒度控制,这对于创建可靠的代理至关重要。此外,LangGraph还包括内置的持久性,可以实现高级的人在环和内存功能。
相关文章:
基于 LangChain+LangGraph 来实现一个翻译项目
相信大家在看文档的时候,有时会比较苦恼,比如 AI 相关的文档都是外文,中文文档比较少,看起来会比较吃力,有的时候会看不懂,翻译软件又翻得很乱,完全看不了,今天就基于 LangChain 和 …...
javascript 如何将 json 格式数组转为 excel 表格| sheetJS
案例 // https://unpkg.com/xlsx0.18.5/dist/xlsx.full.min.js function exportXlsx(jsonData, fileName , mine null) {const workbook XLSX.utils.book_new();// 将JSON数组转换成工作表const worksheet XLSX.utils.json_to_sheet(jsonData);// 向工作簿添加工作表XLSX.…...
网页制作技术在未来会如何影响人们的生活?
网页制作技术在未来会如何影响人们的生活? 李升伟 网页制作技术在未来可能会从以下几个方面显著影响人们的生活: 1. 工作与学习方式的变革:远程办公和在线教育将更加普及和高效。通过精心制作的网页,人们能够实现更便捷的协作…...
【计算机网络】网络层——IPv4地址(个人笔记)
学习日期:2024.7.24 内容摘要:IPv4地址,分类编址,子网,无分类编址 IPv4地址概述 在TCP/IP体系中,IP地址是一个最基本的概念,IPv4地址就是给因特网上的每一台主机的每一个接口分配一个在全世界…...
c++ 学习笔记之多线程:线程锁,条件变量,唤醒指定线程
基于CAS线程加锁方式 CAS(Compare-And-Swap)和 mutex 都是用于实现线程安全的技术,但它们适用于不同的场景,具有不同的性能和复杂性。下面是对两者的区别和使用场景的详细解释: CAS(Compare-And-Swap&…...
《0基础》学习Python——第二十三讲__网络爬虫/<6>爬取哔哩哔哩视频
一、在B站上爬取一段视频(B站视频有音频和视频两个部分) 1、获取URL 注意:很多平台都有反爬取的机制,B站也不例外 首先按下F12找到第一条复制URL 2、UA伪装,下列图片中(注意代码书写格式) 3、Co…...
第13周 简历职位功能开发与Zookeeper实战
第13周 简历职位功能开发与Zookeeper实战 本章概述1. Mysql8窗口函数over使用1.1 演示表结构与数据1.2 案例1:获取男女总分数1.3 案例2****************************************************************************************本章概述 1. Mysql8窗口函数over使用 参考案例…...
什么是大型语言模型 (LLM)
本章探讨下,人工智能如何彻底改变我们理解和与语言互动的方式 大型语言模型 (LLM) 代表了人工智能的突破,它采用具有广泛参数的神经网络技术进行高级语言处理。 本文探讨了 LLM 的演变、架构、应用和挑战,重点关注其在自然语言处理 (NLP) 领…...
【人工智能】AI时代:探索个人潜能的新视角
文章目录 🍊Al时代的个人发展1 AI的高速发展意味着什么1.1 生产力大幅提升1.2 生产关系的改变1.3 产品范式1.4 产业革命1.5 Al的局限性1.5.1局限一:大模型的幻觉1.5.2 局限二:Token 2 个体如何应对这种改变?2.1 职场人2.2 K12家长2.3 大学生2.4 创业者 …...
pyaudio VAD通过声音音频值分贝大小检测没人说话自动停止录制
效果可能说话声音小可能不被监听到,需要更改QUIET_DB阈值,另外delay_time值是低于阈值多久就可以停止保存当前的语音 import pyaudio import waveimport sys import numpy as npdef record_auto(MIC_INDEX=1):开启麦克风录音,保存至temp/speech_record.wav音频文件音量超过…...
《后端程序猿 · @Value 注释说明》
📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数…...
【LeetCode】71.简化路径
1. 题目 2. 分析 3. 代码 我写了一版很复杂的代码: class Solution:def simplifyPath(self, path: str) -> str:operator [] # 操作符的栈dir_name [] # 文件名的栈idx 0cur_dir_name ""while(idx < len(path)):if path[idx] /:operator.ap…...
DockerCompose 安装环境
1. Redis version: 3 services:redis:image: redis:6.2.12container_name: redisports:- "6379:6379"environment:TZ: Asia/Shanghaivolumes:# 本地数据目录要先执行 chmod 777 /usr/local/docker/redis/data 赋予读写权限,否则将无法写入数据- /usr/loc…...
学习笔记之JAVA篇(0724)
p 方法 方法声明格式: [修饰符1 修饰符2 ...] 返回值类型 方法名(形式参数列表){ java语句;......; } 方法调用方式 普通方法对象.方法名(实参列表)静态方法类名.方法名(实参列表) 方法的详…...
【Android】广播机制
【Android】广播机制 前言 广播机制是Android中一种非常重要的通信机制,用于在应用程序之间或应用程序的不同组件之间传递信息。广播可以是系统广播,也可以是自定义广播。广播机制主要包括标准广播和有序广播两种类型。 简介 在Android中,…...
【.NET全栈】ASP.NET开发Web应用——ASP.NET数据绑定技术
文章目录 前言一、绑定技术基础1、单值绑定2、重复值绑定 二、数据源控件1、数据绑定的页面生存周期2、SqlDataSource3、使用参数过滤数据4、更新数据和并发处理5、编程执行SqlDataSource命令6、ObjectDataSource控件介绍7、创建业务对象类8、在ObiectDataSource中使用参数9、使…...
MySQL的账户管理
目录 1 密码策略 1.1 查看数据库当前密码策略: 1.2 查看密码设置策略 1.3 密码强度检查等级解释(validate_password.policy) 2 新建登录账户 3 账户授权 3.1 赋权原则 3.2 常见的用户权限 3.3 查看权限 3.4 赋权语法 4 实例 4.1 示例1&#x…...
FastGPT 源码调试配置
目录 一、添加 launch.json 文件 二、调试 本文简单介绍如何通过 vscode 对 FastGPT 进行调试。 这里假设已经安装 vsocde 和 FastGPT本地部署。 一、添加 launch.json 文件 vscode 打开 FastGPT 项目,点击 调试 -> 显示所有自动调试配置 -> 添加配置 -> Node.j…...
SQL Server数据迁移新纪元:数据库数据泵(Data Pump)使用指南
SQL Server数据迁移新纪元:数据库数据泵(Data Pump)使用指南 在数据管理的世界里,数据迁移是一个常见且复杂的过程。SQL Server提供了一个强大的工具——数据库数据泵(Data Pump),它可以帮助我…...
Android性能优化之OOM
OOM 什么是OOM?为什么会有OOM?APP的内存限制App的内存限制是多少? 为什么Android系统要设定App的内存限制?Android有GC自动回收资源,为什么还会OOM?容易发生OOM的场景及处理方案如何避免OOM? 什么是OOM&am…...
Claude Code 之父:2026 年我一行代码都没写,编程已被 AI 解决
2026 年,你还在一行一行敲代码吗?Claude Code 的创造者、Anthropic 核心人物 Boris Cherny,在公开访谈里抛出一句让整个行业震动的话:2026 年到现在,我没有写过一行代码。所有开发工作,100% 交给 AI 代理完…...
终极鼠标连点器使用指南:3分钟掌握高效自动化技巧
终极鼠标连点器使用指南:3分钟掌握高效自动化技巧 【免费下载链接】MouseClick 🖱️ MouseClick 🖱️ 是一款功能强大的鼠标连点器和管理工具,采用 QT Widget 开发 ,具备跨平台兼容性 。软件界面美观 ,操作…...
SAP-ABAP:变量、常量、结构与内表声明(10篇博客合集) 第五篇:声明时的键值设计技巧:结构与内表的主键、非主键配置指南
变量、常量、结构与内表声明(10篇博客合集) 第五篇:声明时的键值设计技巧:结构与内表的主键、非主键配置指南如果把内表比作一张内存中的“数据库表”,那么键就是这张表的索引甚至主键。键的设计直接决定了数据的唯一性…...
Transient、QuickEye、VerifyEye傻傻分不清?一文讲透Ansys里三种眼图仿真方法的适用场景与避坑指南
Transient、QuickEye、VerifyEye深度解析:Ansys眼图仿真技术选型实战指南 在高速数字系统设计中,眼图分析是评估信号完整性的黄金标准。面对Ansys工具链中三种截然不同的眼图生成方法,工程师常常陷入选择困境——是追求精确度的传统瞬态分析&…...
钱钟书《围城》第1-5章阅读笔记:一场关于人生困境的提前预演
前言 钱钟书先生的《围城》被誉为"新儒林外史",是中国现代文学史上风格独特的讽刺经典。这部创作于20世纪40年代的长篇小说,以抗战初期为背景,通过主人公方鸿渐的人生轨迹,深刻揭示了知识分子群体的精神困境与人性弱点。…...
2027考研全套资料免费分享
备战27考研最全备考资料整理完毕,一路走来深知备考搜集资料耗费大量时间,浪费不少精力。特意整理2027考研全科完整版资源,全部打包汇总,零基础考生直接拿来就能使用,省去四处搜集资料的烦恼。资料内含:&…...
Burp Suite拦截与替换机制深度解析:从协议层到规则链
1. 这不是“点开就能用”的功能,而是你和目标系统之间的一道可编程闸门很多人第一次在Burp Suite里点开Proxy → Intercept,看到HTTP请求被拦下来,兴奋地改个User-Agent、删个Cookie就点Forward,以为自己已经掌握了“拦截与替换”…...
探索Windows 10上的Android世界:揭秘WSA-Windows-10项目的3个技术突破
探索Windows 10上的Android世界:揭秘WSA-Windows-10项目的3个技术突破 【免费下载链接】WSA-Windows-10 This is a backport of Windows Subsystem for Android to Windows 10. 项目地址: https://gitcode.com/gh_mirrors/ws/WSA-Windows-10 想象一下&#…...
BiliRoamingX:彻底解决B站体验限制的完整增强方案
BiliRoamingX:彻底解决B站体验限制的完整增强方案 【免费下载链接】BiliRoamingX-integrations BiliRoamingX integrations and patches powered by ReVanced. 项目地址: https://gitcode.com/gh_mirrors/bi/BiliRoamingX-integrations 你是否曾为B站的内容区…...
DIY四路自动音频源切换器:从信号检测到继电器隔离的完整设计
1. 项目概述与核心需求解析作为一个喜欢在工作室里捣鼓各种音频设备的玩家,我经常遇到一个挺烦人的问题:我的功放只有一组输入,但我想接的设备却有好几个——台式电脑、平板、蓝牙接收模块,还有一台树莓派。每次想切换音源&#x…...
