使用ai进行技术文档的翻译(目录)

使用ai进行技术文档的翻译(目录) 碎碎念那边有说到有二次开发的口头机会文档基本是英文。之后现在ai应用又挺流行且ai应用在翻译也是很早一个技能所以就想着翻译一下需要的文档信息了。也算是ai辅助学习了吧总体思路是这样的先获取相关的目录之后根据目录去处理具体的页面最后连起来可用。1、获取相关的目录1.1、获取 ObjectARX and Managed .NET 部分目录找到了接口传送的json地址https://help.autodesk.com/view/OARX/2026/CHS/data/toctree.json数据比较多直接使用ai先不说长度够不够对token消耗多不多仅考虑题目随时可能会发而且从收到题目到处理交付的时间只有7天所以我仅需要 ObjectARX and Managed .NET 目录下的东西。【预处理1获取子json】所以我要先遍历这个json之后截取 ObjectARX and Managed .NET 目录及子目录保存成一个新的子json。关键代码如下def find_node_by_value(node, target, depth0): 通过值查找节点 if isinstance(node, dict): for key, value in node.items(): indent * depth if value target: print(f{indent}✅ 找到返回节点) return node # 递归搜索并接收返回值 result find_node_by_value(value, target, depth 1) if result: return result # 向上传递 elif isinstance(node, list): for i, item in enumerate(node): result find_node_by_value(item, target, depth 1) if result: return result return None本来是想根据 json 拿 ai 自动生成一个静态的可用的网站的不过后来因为数据太多我电脑又太老了所以改变了策略。使用数据库保存信息之后再用代码正常组装。【预处理2遍历子json存入未翻译的目录树】获取完了子 json接下来就是遍历他保留树的结构把他存进数据库里方便之后使用。把子 json 给 ai让 ai 统计了下这个 json 的 key 和对应的数量实践发现他的统计会有一些误差但是还是可以用的他统计出来主要的 key 为ttl、id、ln、children、type从数据来看 id 和 ln 都似乎是地址不过 ln 会比 id 少点抽查了几个 id 的也都能访问所以我决定存的信息包括ttl、id 还有其目录结构和 ttl 对应的中文翻译。大概这么一个表字段有id主键自增id、parent_id对应的父id、title对应 json 的 ttl、title_cn之后要存的对应ttl的中文翻译、url对应 json 的 id要做一些些处理 ?guid具体的id测试角度?keyvalue是get请求参数、level所属层级、sort_order所属层级的排序、created_at创建时间部分参考代码如下def escape_sql_string(s): 转义SQL字符串 if s is None: return NULL s str(s).replace(\\, \\\\).replace(, \\) return f{s} def traverse_json(node, id_counter, parent_id, depth, sort_order, sql_values): 递归遍历JSON收集SQL值 if isinstance(node, dict): # 获取当前节点的ID current_id id_counter[0] id_counter[0] 1 # 提取节点信息 title node.get(ttl, ) url node.get(id, ) # 构建SQL值 sql_value f({current_id}, {parent_id}, {escape_sql_string(title)}, {escape_sql_string(url)}, {depth}, {sort_order}) sql_values.append(sql_value) # 打印进度 print(f处理: {title[:50]} (ID: {current_id})) # 处理子节点 if children in node and node[children]: for i, child in enumerate(node[children]): traverse_json( child, id_counter, current_id, # 子节点的父ID是当前节点ID depth 1, i 1, sql_values ) elif isinstance(node, list): for i, item in enumerate(node): traverse_json( item, id_counter, parent_id, depth, i 1, sql_values ) def generate_single_insert_sql(data, table_name默认表名): 生成单条INSERT语句包含所有VALUES sql_values [] id_counter [1] # ID从1开始 print(开始遍历JSON...) traverse_json(data, id_counter, 0, 0, 1, sql_values) if not sql_values: return print(f\n共生成 {len(sql_values)} 条记录) # 构建单条INSERT语句 prefix fINSERT INTO {table_name} (id, parent_id, title, url, level, sort_order) VALUES \n values_part ,\n.join(sql_values) return prefix values_part ;这个代码生成的sql集合的根节点要做额外处理根目录的父节点要设置为null也可以在代码里面加个标记判断。【预处理3AI翻译title】作为一个失业的宝子来说几块钱也是钱呀嘤嘤嘤羡慕有工作的宝子单位付账哦……不推广但是如果我没工作之前我估计翻译正文要白嫖下……测试的角度解决开发问题哈哈哈pai要米网页不要米……脑子一转无头浏览器UI自动化约等于……这边预处理是用的api……因为目录比较多翻译考虑要不要用流式结果流式并不能改善上下文长度最后还是不用流式。这里要注意几个点可能可以节约下token1.流式和非流式本身没有太大的区别计算都是按照中文、英文、符号来算的不是按照返回方式的当然命中和非命中价格也不一样。但是敲重点流式和非流式取值的部分代码不一样比如python语言非流式获取 response.choices[0].message.content 流式获取 for chunk in response: if chunk.choices[0].delta.content:chunk.choices[0].delta.content 具体可以查下对应的官网api2.你发送的和他返回的才是上下文和也就是说本来比如8K上限你的关键字提示文案超级详细精准命中但是你的提示文案你的素材已经6K了那么能输出的只剩2K了同理要是你的你的提示文案你的素材是4k那么能输出的就还有4K了解这个会关系到你分几次去请求避免结果被截断。所以可以人为的先做预处理节约你的提示文案和素材当然富裕的可以先不考虑。3.要是你要上下文关联需要反哺历史给ai这样似乎又增加了本不富裕的提示文案素材还好我的仅翻译就行不过为了不截断请求所以需要合适的分批因为计算价格的方式就决定了多次分批会增加的成本是请求部分的内容所以就决定了素材也要对应的切分。我采用了分批查询数据库且为了更好的压缩素材我把查询结果转换成字典字典的id作为keytitle作为value我要求返回翻译的时候把原来id对应的值替换成翻译的结果并且也要求返回的时候用紧凑模式。部分参考代码如下def query_to_json(start_id, end_id): 执行查询并返回数据列表 conn None try: conn pymysql.connect(**DB_CONFIG) with conn.cursor(pymysql.cursors.DictCursor) as cursor: sql fSELECT id, title FROM document_tree WHERE id {start_id} AND id {end_id} # 要是id有规律就用上面的没有可用的序号标记就用limit和offset # sql fSELECT id, title FROM document_tree where title_cn is null limit {start_id} , {end_id} print(-- * 20) print(sql) print(-- * 20) cursor.execute(sql) results cursor.fetchall() return results except Exception as e: print(f查询失败 [{start_id}, {end_id}): {e}) return [] finally: if conn: conn.close() def generate_new_sql(dict_str: str, batch_num: int, output_file: str) - bool: # 根据传入的字典翻译 print(f正在流式生成新的字典 (批次 {batch_num})...) print(dict_str) user_prompt f请将以下字典的value翻译成中文翻译的内容覆盖,保持紧凑。要求直接输出紧凑格式的字典不要添加任何注释或说明,原始字典信息:{dict_str} try: response client.chat.completions.create( modeldeepseek-chat, messages[ {role: system, content: 你是CAD C#二次开发专家擅长中英文翻译。}, {role: user, content: user_prompt} ], streamFalse ) content response.choices[0].message.content print(content) data json.loads(content) with open(output_file, a, encodingutf-8) as f: # 考虑sql要直接运行所以直接用sql的注释来写批次 f.write(f\n-- Batch {batch_num} \n) # 直接遍历字典生成更新的sql for key, value in data.items(): sql fUPDATE document_tree SET title_cn {value.replace(, )} WHERE id {key};\n print(sql) f.write(sql) print(f 批次 {batch_num} 完成) return True except Exception as e: print(f AI调用失败: {e}) return False if __name__ __main__: x 150 y 16 total_queried 0 skipped_batches 0 output_file rD:\CAD学习准备\cadBook\new_更新翻译sql1.txt print(开始处理...) print(f总数据量预估: {x * y} 条) print( * 60) for i in range(y): start_id x * i end_id x * (i 1) print(f\n批次 {i 1}/{y}: 查询ID范围 [{start_id}, {end_id})) json_result, results query_to_json(start_id, end_id) # json_result, results query_to_json(start_id, x) # print( * 60) # print(foffset:{start_id},limit:{x}) # print( * 60) if not results: print(f 批次 {i 1} 无数据跳过) skipped_batches 1 continue total_queried len(results) print(f 查询到 {len(results)} 条记录) # results 是数组直接转字典 result_dict {item[id]: item[title] for item in results} # 紧凑格式输出 # ensure_asciiFalse 允许输出非 ASCII 字符如中文不转义为 \uXXXX # separators(,, :) 使用逗号和冒号作为分隔符移除多余空格使输出紧凑 # 压缩成最小字符串发给AI compressed json.dumps(result_dict, ensure_asciiFalse, separators(,, :)) # 调用AI ok generate_new_sql(compressed, i 1, output_file) if ok: print(f 批次 {i 1} 处理成功) else: print(f 批次 {i 1} 处理失败) print(\n * 60) print(处理完成) print(f 查询总记录数: {total_queried})运行生成的更新sql至此目录的数据都已经准备好了。可以使用sql直接用也可以好看点加上后端请求前端渲染展示。嘛补个数据库成果图