公众号最近更新得很少,有两部分原因:
一是AI的基本原理就是那些,尤其是Prompt技巧方面,在讲完之后我觉得需要额外补充的不多;
二是最近Cursor 让我具备了编程写代码的能力,去创造一个新的产品,或者自动化工作流实现一个复杂的工作对我而言有更强的吸引力。

我非常建议在AI领域获得了一定基础的同学该去试试AI编程,我也有大量的YouTube/B站视频在做对应的教学:
1. Cursor入门介绍&写插件演示
https://www.bilibili.com/video/BV17oHjexEro/
2. Cursor高级技巧与实战
https://www.bilibili.com/video/BV1YAtReqEkH/
3. 用Cursor做一个带注册登录功能的AI网站
https://www.bilibili.com/video/BV17dxEeBEqU/
4. 用Cursor写一个完整的AI native App
https://www.bilibili.com/video/BV1Hu2EYkEg4/
5. 用Cursor写本地自动化脚本
https://www.bilibili.com/video/BV1wKtgeZE6q/
6. 用Cursor写文章
https://www.bilibili.com/video/BV1S7H9e2EA7/

自动化书籍翻译
AI时代的纺织女工
我今天想通过这个自动化完成一本英文书籍翻译的例子,来让你了解使用AI完成自动化工具的魅力。
我估计很多人都有尝试过在和ChatGPT聊天的时候,给它发个长文,文章链接或者pdf文档的方式,希望他一次性完成翻译。但是ChatGPT确实是做不到这件事的,有两个原因:
现在ChatGPT及大多数AI的上下文长度大概是128k,也就是大约6.4万汉字或单词,更长的内容ChatGPT是读取不了,至少不是真正在读的;
-
而且,比这个上下文长度限制更夸张的是,其实AI单次输出的token最大长度一般只有4096,也就是2000字左右,要他一次性输出更长的内容他是真做不到。
所以,怎么办呢?多数人的方式应该是自己分割长度,几段几段地发送给ChatGPT,让他完成之后再自己进行拼接。想象一下你可能要苦苦地等待输出,再拼接100次!有没有AI时代的女工的感觉?
但实际上,你完全可以通过调用OpenAI API的方式,让GPT循环重复地完成它需要做的事,一次性完成你想要完成的任务,比如翻译一本《老人与海》,我只需要执行python文件,然后等待3分钟就好了。
什么是API和API key
这里给不了解编程的同学简单介绍下,所谓API(Application Programming Interface,应用程序编程接口)是一种让应用程序之间按预先定义的规则和协议进行互相通信和交互的工具。
应用间API的调用是件非常常见,但我们平时没有感知的事,比如当你用各种天气应用查看查看天气预报时,天气应用可能在后台使用API从天气服务提供商(如和风天气、OpenWeatherMap等)获取实时天气数据和预报。又比如你在携程查找酒店,通过内置地图查看酒店地点时,也是携程使用地图服务提供商的API获取地图图面和地点的地理信息。但是你自己平时使用时可能毫无感知,因为作为消费者,我们需要的只是服务,而不需要开发层面的知识。
API key(密钥)是调用API时需要传输的身份密钥,用于验证身份以及API提供方对调用方计费等。OpenAI API key则顾名思义就是OpenAI针对自己所提供的ChatGPT等服务,在接受开发者/用户接口调用时所需的密钥。
API的调用不在ChatGPT Plus会员的免费范围之内,需要按使用量进行付费,像OpenAI的你需要在这里预先充值才可以:OpenAI充值入口https://platform.openai.com/settings/organization/billing/overview

当然,现在OpenAI只支持海外的信用卡进行申请,如果你没有的话,可以先尝试使用国内其他公司(如通义千问、deepseek等)的API服务,或者通过?Wildcard:https://bewildcard.com/?code=AIHS 申请一张境外信用卡去进行充值。
书籍翻译的解决思路
在使用脚本去调用OpenAI翻译时,其实也会遇到下述几个问题:
1、AI的上下文有限,通常的128K没法直接读完一本书,更别提一般每次输出只有4098的token数了,所以需要把书籍进行分割;
2、你需要写更好的prompt去达到一定的翻译质量,避免机翻感,这需要对LLM和翻译工作都有一定的理解;
3、全书来说,如果分割翻译的话,很容易出现同一个词/名字,前后翻译不一致的问题,以及翻译风格很容易受AI随机性的影响。
如果前面我的专栏文章看得认真的话,也会发现有很容易的解决方案。
下面我把这个Python脚本直接附在上面,你可以理解下实现的逻辑,也可以直接拿来就用(不知道怎么运行的话找ChatGPT问问就好)。
"""书籍翻译器作者:AI进化论-花生(YouTube/B站)这个程序可以将英文文本文件翻译成中文,并提供两种翻译风格:直接翻译和鲁迅风格的翻译。使用说明:1. 确保已安装所有必要的库(openai, python-dotenv, tkinter)。2. 在同目录下创建一个 .env 文件,并在其中设置你的 OpenAI API 密钥:OPENAI_API_KEY=你的密钥3. 运行程序,它会弹出窗口让你选择输入文件和输出目录。4. 程序会自动将文本分割成适当大小的块,并进行翻译。5. 翻译结果会保存在选定的输出目录中。可调整的参数:- split_text 函数中的 min_words 和 max_words:控制每个文本块的大小。- translate_text_direct 和 translate_text_stylized 函数中的 model 参数:可以更改为其他可用的 OpenAI 模型。- translate_text_stylized 函数中的 system_prompt:可以修改翻译风格指南。注意:使用此程序需要 OpenAI API 密钥,可能会产生费用。请确保了解 API 的使用条款和定价。"""import osimport reimport openaifrom dotenv import load_dotenvimport tkinter as tkfrom tkinter import filedialog# 加载环境变量load_dotenv()# 设置OpenAI API密钥openai.api_key = os.getenv("OPENAI_API_KEY")def split_text(text, min_words=1000, max_words=2000):"""将文本分割成chunks,每个chunk包含1000-2000个单词。优先在段落换行处分割,如果超过1500个单词仍未找到换行,则在句子结尾处分割。"""chunks = []current_chunk = ""current_words = 0paragraphs = text.split('\n')for paragraph in paragraphs:words = paragraph.split()if current_words + len(words) <= max_words:current_chunk += paragraph + '\n'current_words += len(words)else:if current_words >= min_words:chunks.append(current_chunk.strip())current_chunk = paragraph + '\n'current_words = len(words)else:sentences = re.split(r'(?<=[.!?])\s+', paragraph)for sentence in sentences:sentence_words = sentence.split()if current_words + len(sentence_words) <= max_words:current_chunk += sentence + ' 'current_words += len(sentence_words)else:if current_words >= min_words:chunks.append(current_chunk.strip())current_chunk = sentence + ' 'current_words = len(sentence_words)else:current_chunk += sentence + ' 'chunks.append(current_chunk.strip())current_chunk = ""current_words = 0current_chunk += '\n'if current_chunk:chunks.append(current_chunk.strip())return chunksdef translate_text_direct(text):"""使用OpenAI API进行直接翻译。"""system_prompt = """你是一位专业的具有20年经验的翻译家,精通中英文文学翻译。请对以下英文文本进行准确的翻译。只需返回翻译结果,不要做任何解释或说明。注意"old man"应该直接翻译为"老人"。"""user_prompt = f"请翻译以下英文文本:\n{text}"response = openai.ChatCompletion.create(model="gpt-4o-mini", # 或者使用 "gpt-4" 如果有访问权限messages=[{"role": "system", "content": system_prompt},{"role": "user", "content": user_prompt}])return response.choices[0].message.content.strip()def translate_text_stylized(text, first_translation):"""使用OpenAI API进行风格化翻译。"""system_prompt = """你是著名作家鲁迅,正在帮助用户对他的翻译进行风格化和润色。根据提供的英文原文和直译结果,按鲁迅的风格进行翻译和润色。只需返回润色后的翻译结果,不要做任何解释或说明。你的翻译应该保持鲁迅的特点:- 语言犀利简练,常带讽刺和批判意味- 善用比喻和象征,但更倾向于朴实无华的表达- 关注社会现实,常带有深刻的思考- 善用白话文,但不失文学性- 注意"old man"应该直接翻译为"老人"原文:The old man was thin and gaunt with deep wrinkles in the back of his neck.直译:老人又瘦又憔悴,脖子后面有深深的皱纹。鲁迅风格:那老人,瘦骨嶙峋,颈后皱纹如沟壑,仿佛承载了无数苦难与岁月的重量。原文:The sea was very dark and the light made prisms in the water.直译:海水非常黑暗,光线在水中形成棱镜。鲁迅风格:漆黑的海面上,光线折射出棱镜般的光影,如同这个世界的真相,总是在黑暗中闪烁不定。"""user_prompt = f"""英文原文:{text}第一次直译结果:{first_translation}请根据原文和直译结果,按鲁迅的风格进行翻译和润色。只需返回翻译结果,不要做任何解释或说明。"""response = openai.ChatCompletion.create(model="gpt-4o-mini", # 或者使用 "gpt-4" 如果有访���权限messages=[{"role": "system", "content": system_prompt},{"role": "user", "content": user_prompt}])return response.choices[0].message.content.strip()def translate_book(input_file, output_dir):"""翻译整本书并保存结果。"""# 创建输出目录os.makedirs(output_dir, exist_ok=True)# 获取输入文件的基本名称(不包含路径和扩展名)base_name = os.path.splitext(os.path.basename(input_file))[0]# 创建输出文件first_translation_file = os.path.join(output_dir, f"{base_name}_first_translation.txt")second_translation_file = os.path.join(output_dir, f"{base_name}_second_translation.txt")combined_translation_file = os.path.join(output_dir, f"{base_name}_combined_translation.txt")# 打开输出文件with open(first_translation_file, 'w', encoding='utf-8') as f_first, \open(second_translation_file, 'w', encoding='utf-8') as f_second, \open(combined_translation_file, 'w', encoding='utf-8') as f_combined, \open(input_file, 'r', encoding='utf-8') as f_input:book_text = f_input.read()chunks = split_text(book_text)for i, chunk in enumerate(chunks):print(f"正在翻译第 {i+1}/{len(chunks)} 个chunk...")# 第一次翻译(直接翻译)first_trans = translate_text_direct(chunk)f_first.write(first_trans + "\n\n")f_first.flush() # 立即写入文件# 第二次翻译(风格化翻译)second_trans = translate_text_stylized(chunk, first_trans)f_second.write(second_trans + "\n\n")f_second.flush() # 立即写入文件# 直接组合原文和第二次翻译f_combined.write(f"{chunk}\n\n{second_trans}\n\n")f_combined.write("\n--- Chunk 分隔线 ---\n\n")f_combined.flush() # 立即写入文件print(f"翻译完成!结果已保存到 {output_dir} 目录。")print(f"第一次翻译结果:{first_translation_file}")print(f"第二次翻译结果:{second_translation_file}")print(f"中英文对照结果:{combined_translation_file}")def main():root = tk.Tk()root.withdraw() # 隐藏主窗口# 选择输入文件input_file = filedialog.askopenfilename(title="选择英文书籍文件", filetypes=[("Text files", "*.txt")])if not input_file:print("未选择文件,程序退出。")return# 选择输出目录output_dir = filedialog.askdirectory(title="选择输出目录")if not output_dir:print("未选择输出目录,程序退出。")returnprint(f"选择的输入文件:{input_file}")print(f"选择的输出目录:{output_dir}")translate_book(input_file, output_dir)if __name__ == "__main__":main()
one more thing,我现在做了个叫「AI编程:从入门到精通」的知识星球,致力于帮1000个人做出自己的第一个网站,上架人生首款app,感兴趣的可以看看。

?点击阅读原文有惊喜