🚀 实战 LangChain 版 OpenAI-Translator v2.0:从手写轮子到框架赋能
一、本章概览
第12章《实战 LangChain 版 OpenAI-Translator v2.0》是 LangChain 系列的实战收官之章——用前几章学到的 LangChain 知识,对第7章的 OpenAI-Translator v1.0 进行全面重构升级。
核心内容:
-
v1.0 Model 模块的问题与挑战 -
v2.0 设计如何回应挑战 -
ChatPromptTemplate 设计翻译提示模板 -
使用 ChatModel(GPT-3.5-turbo)执行翻译 -
使用 LLMChain 简化构造 ChatPrompt -
TranslationChain 类的完整实现 -
PDFTranslator 类重构 -
TranslationConfig 单例配置管理 -
基于 Gradio 的图形化界面 -
基于 Flask 的 Web Server 服务化 -
课程项目:openai-quickstart
二、先温故:LangChain ChatModel 使用流程
使用 ChatOpenAI 创建聊天模型,配合 SystemMessage、HumanMessage、AIMessage 实现多轮对话:
from langchain.chat_models import ChatOpenAI
from langchain.schema import AIMessage, HumanMessage, SystemMessage
chat_model = ChatOpenAI(model_name="gpt-3.5-turbo")
messages = [
SystemMessage(content="You are a helpful assistant."),
HumanMessage(content="who won the world series in 2020?"),
AIMessage(content="The Los Angeles Dodgers won the World Series in 2020."),
HumanMessage(content="where was it played?")
]
chat_model(messages)
# 返回:AIMessage(content="The 2020 World Series was played at Globe Life Field in Arlington, Texas.")
三、v1.0 Model 模块:问题与挑战
痛点分析
在 v1.0 中,OpenAI-Translator 的 Model 模块是自己手写的类体系,存在 4 大问题:
|
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
v1.0 Model 模块类结构
│ Model(基类)
│ ├── translate_prompt(content, target_language) → str
│ ├── make_text_prompt(text, target_language) → str
│ ├── make_table_prompt(table, target_language) → str
│ └── make_request(prompt) → raise NotImplementedError
│
├── OpenAiModel
│ ├── model: str
│ └── make_request(prompt) → (translation, status)
│
├── GLMModel
│ ├── model_url: str
│ ├── timeout: int
│ └── make_request(prompt) → (translation, status)
│
└── AzureOpenAI(继承 OpenAiModel)
四、v2.0 设计:用 LangChain 回应挑战
核心思路
★由 LangChain 框架接手大模型管理,聚焦应用自身的 Prompt 设计。
|
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
v2.0 Model I/O 架构
Input (prompts) Output (contents)
X = "foo", y = "bar"
↓
Prompt Template → "Does {x} like {y}, and why?"
↓
LLM / Chat Model → {"likes": True, "reason": "Because..."}
↓
Output Parser → "Foo does..."
↓
TranslationChain(LLMChain)
五、ChatPromptTemplate 设计翻译提示模板
Step 1:System 角色承担翻译指令
from langchain.prompts.chat import (
ChatPromptTemplate,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate,
)
# 翻译任务指令始终由 System 角色承担
template = (
"You are a translation expert, proficient in various languages. \n"
"Translates {source_language} to {target_language}."
)
system_message_prompt = SystemMessagePromptTemplate.from_template(template)
Step 2:Human 角色输入待翻译文本
# 待翻译文本由 Human 角色输入
human_template = "{text}"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
Step 3:构造 ChatPromptTemplate
# 使用 System 和 Human 角色的提示模板构造 ChatPromptTemplate
chat_prompt_template = ChatPromptTemplate.from_messages(
[system_message_prompt, human_message_prompt]
)
Step 4:生成 Messages 并翻译
# 生成聊天模型真正可用的消息记录 Messages
chat_prompt = chat_prompt_template.format_prompt(
text="I love programming."
).to_messages()
# 输出:
# ChatPromptValue(messages=[
# SystemMessage(content="You are a translation expert...Translates English to Chinese."),
# HumanMessage(content="I love programming.")
# ])
六、使用 ChatModel 执行翻译
from langchain.chat_models import ChatOpenAI
# 为了翻译结果的稳定性,将 temperature 设置为 0
translation_model = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)
translation_result = translation_model(chat_prompt)
print(translation_result.content) # 我喜欢编程。
七、使用 LLMChain 简化构造 ChatPrompt
LLMChain 将 Prompt 和 Model 封装在一起,无需每次都手动调用 to_messages():
from langchain.chains import LLMChain
# 无需再每次都使用 to_messages 方法构造 ChatPrompt
translation_chain = LLMChain(llm=translation_model, prompt=chat_prompt_template)
# 等价于 translation_result.content(字符串类型)
chain_result = translation_chain.run({'text': "I love programming."})
print(chain_result) # 我喜欢编程。
八、TranslationChain 类的完整实现
将上述所有步骤封装为 TranslationChain 类,继承自 LLMChain:
class TranslationChain:
def __init__(self, model_name: str = "gpt-3.5-turbo", verbose: bool = True):
# 翻译任务指令始终由 System 角色承担
template = (
"You are a translation expert, proficient in various languages. \n"
"Translates {source_language} to {target_language}."
)
system_message_prompt = SystemMessagePromptTemplate.from_template(template)
# 待翻译文本由 Human 角色输入
human_template = "{text}"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
# 使用 System 和 Human 角色的提示模板构造 ChatPromptTemplate
chat_prompt_template = ChatPromptTemplate.from_messages(
[system_message_prompt, human_message_prompt]
)
# 为了翻译结果的稳定性,将 temperature 设置为 0
chat = ChatOpenAI(model_name=model_name, temperature=0, verbose=verbose)
self.chain = LLMChain(llm=chat, prompt=chat_prompt_template, verbose=verbose)
def run(self, text: str, source_language: str, target_language: str) -> (str, bool):
result = ""
try:
result = self.chain.run({
"text": text,
"source_language": source_language,
"target_language": target_language,
})
except Exception as e:
LoG.error(f"An error occurred during translation: {e}")
return result, False
return result, True
九、PDFTranslator 类重构
v2.0 的 PDFTranslator 不再直接调用 Model 类,而是通过 TranslationChain 统一翻译接口:
class PDFTranslator:
def __init__(self, model_name: str):
self.translate_chain = TranslationChain(model_name)
self.pdf_parser = PDFParser()
self.writer = Writer()
def translate_pdf(self, input_file: str, output_file_format: str = 'markdown',
source_language: str = "English", target_language: str = 'Chinese',
pages: Optional[int] = None):
...
for page_idx, page in enumerate(self.book.pages):
for content_idx, content in enumerate(page.contents):
# Translate content.original
translation, status = self.translate_chain.run(
content, source_language, target_language
)
# Update the content in self.book.pages directly
self.book.pages[page_idx].contents[content_idx].set_translation(translation, status)
return self.writer.save_translated_book(self.book, output_file_format)
核心变化对比
|
|
|
|---|---|
| v1.0 | prompt = self.model.translate_prompt(content, target_language)
self.model.make_request(prompt)
|
| v2.0 | self.translate_chain.run(content, source_language, target_language) |
十、TranslationConfig 单例配置管理
v2.0 使用单例模式实现全局配置管理,通过 YAML 配置文件和命令行参数双重配置:
class TranslationConfig:
instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super(TranslationConfig, cls).__new__(cls)
cls._instance._config = None
return cls._instance
def initialize(self, args):
with open(args.config_file, "r") as f:
config = yaml.safe_load(f)
# Use the argparse Namespace to update the configuration
overridden_values = {
key: value for key, value in vars(args).items()
if key in config and value is not None
}
config.update(overridden_values)
self._instance._config = config
主入口调用:
if __name__ == "__main__":
argument_parser = ArgumentParser()
args = argument_parser.parse_arguments()
# 初始化配置单例
config = TranslationConfig()
config.initialize(args)
# 实例化 PDFTranslator 类,并调用 translate_pdf() 方法
translator = PDFTranslator(config.model_name)
translator.translate_pdf(config.input_file, config.output_file_format, ...)
十一、v2.0 功能特性研发
特性 1:基于 Gradio 的图形化界面
Gradio 是快速构建机器学习模型 Web 演示界面的框架,GitHub 21k+ Stars。
OpenAI-Translator v2.0 Gradio 界面设计:
┌─────────────────────────────────────┐
│ OpenAI-Translator v2.0 │
│ (PDF电子书翻译工具) │
│ │
│ ┌─────────────────────────────┐ │
│ │ 上传PDF文件 │ │
│ │ Drop File Here │ │
│ │ - or - Click to Upload │ │
│ └─────────────────────────────┘ │
│ │
│ 源语言(默认:英文) │
│ ┌─────────────────────────────┐ │
│ │ English │ │
│ └─────────────────────────────┘ │
│ │
│ 目标语言(默认:中文) │
│ ┌─────────────────────────────┐ │
│ │ Chinese │ │
│ └─────────────────────────────┘ │
│ │
│ [Clear] [Submit] │
│ │
│ ┌─────────────────────────────┐ │
│ │ 下载翻译文件 │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────────┘
代码实现:
import gradio as gr
def translation(input_file, source_language, target_language):
LOG.debug(f"[翻译任务]\n源文件:{input_file.name}\n源语言:{source_language}\n目标语言:{target_language}")
output_file_path = Translator.translate_pdf(
input_file.name,
source_language=source_language,
target_language=target_language
)
return output_file_path
def launch_gradio():
iface = gr.Interface(
fn=translation,
title="OpenAI-Translator v2.0(PDF电子书翻译工具)",
inputs=[
gr.File(label="上传PDF文件"),
gr.Textbox(label="源语言(默认:英文)", placeholder="English", value="English"),
gr.Textbox(label="目标语言(默认:中文)", placeholder="Chinese", value="Chinese")
],
outputs=[gr.File(label="下载翻译文件")],
allow_flagging="never"
)
iface.launch()
特性 2:基于 Flask 的 Web Server 服务化
将翻译功能封装为 REST API,通过 HTTP POST 请求调用:
from flask import Flask, request, jsonify, send_file
app = Flask(__name__)
@app.route('/translation', methods=['POST'])
def translation():
input_file = request.files['input_file']
source_language = request.form.get('source_language', 'English')
target_language = request.form.get('target_language', 'Chinese')
# 保存临时文件
input_file_path = TEMP_FILE_DIR + input_file.filename
input_file.save(input_file_path)
# 调用翻译函数
output_file_path = Translator.translate_pdf(
input_file=input_file_path,
source_language=source_language,
target_language=target_language
)
# 移除临时文件
os.remove(input_file_path)
# 返回翻译后的文件
return send_file(output_file_path, as_attachment=True)
客户端调用(通过 requests 请求翻译服务):
import requests
FLASK_SERVER_URL = 'http://localhost:5000'
translation_url = f'{FLASK_SERVER_URL}/translation'
file_path = '../tests/test.pdf'
params = {
'source_language': 'English',
'target_language': 'Chinese'
}
with open(file_path, 'rb') as file:
files = {'input_file': file}
response = requests.post(translation_url, files=files, data=params)
output_filename = "translated_output.md"
if response.status_code == 200:
with open(output_filename, 'wb') as output_file:
output_file.write(response.content)
print(f"Translation completed. Translated file saved as {output_filename}.")
else:
print(f"Translation failed. Status code: {response.status_code}")
十二、产品 v2.0 Feat List
OpenAI-Translator v2.0 的产品规划功能列表:
|
|
|
|
|---|---|---|
|
|
LangChain 架构重构 |
|
|
|
TranslationChain 翻译链 |
|
|
|
单例配置管理 |
|
|
|
Gradio 图形界面 |
|
|
|
Flask Web Server |
|
|
|
保留源 PDF 布局 |
|
|
|
支持更多语言 |
|
十三、课程项目:GitHub openai-quickstart
|
|
|
|---|---|
| 项目名称 |
|
| GitHub |
|
| License |
|
| 定位 |
|
| 文档 |
|
项目目录
openai-quickstart/
├── openai_api/ # OpenAI API 实战(Embedding、Function Calling)
├── langchain/ # LangChain 集成示例(本章核心)
├── openai-translator/ # OpenAI 翻译工具(v1.0 + v2.0)
├── chatgpt-plugins/ # ChatGPT 插件开发
├── docs/ # 文档与学习资料
└── selected_homework/ # 学员优秀作业
📌 本章核心要点总结
|
|
|
|
|---|---|---|
|
|
v1.0 四大痛点 |
|
|
|
v2.0 核心思路 |
|
|
|
ChatPromptTemplate |
|
|
|
TranslationChain |
|
|
|
PDFTranslator 重构 |
model.make_request(prompt) → translate_chain.run(content, src, tgt)
|
|
|
单例配置管理 |
|
|
|
Gradio 图形界面 |
|
|
|
Flask REST API |
|
|
|
v2.0 Feat List |
|
★📚 至此,LangChain 系列(第9~12章)已全部整理完毕,共四篇:
第9章:LangChain 入门(Model I/O) 第10章:LangChain 实战(Chains + Memory) 第11章:LangChain 实战(Data Connection + Agents) 第12章:实战 LangChain 版 OpenAI-Translator v2.0 恭喜你学完整个 LangChain 篇章!🎉
本文整理自《AI 大模型应用开发实战营》第12章,讲师:彭靖田

