)
从 Python 版 fay 平滑迁移到 fay-java三步搬家 19 类依赖替换对照前端零改动摘要本文是 fay-java 系列最后一篇讲如何把 Python 版 fay 换成 fay-java。核心结论先行只有system.conf转格式和memory/若要留历史真正需要从 Python 版拿其余要么仓库自带、要么启动自动生成。全文给出① 三步搬家流程②20 个配置键的完整对照表system.conf → application.yml③ 密钥落位表④19 类 pip 依赖 → Java 替代的完整对照表这是「Python→Java」最值钱的干货⑤ 迁移后验证清单与回滚。含迁移流程图与配置/密钥代码骨架。一、迁移的前提认知在动手之前先想清楚一件事fay-java 和 Python 版 fay 的关系是「对外可观测行为对齐内部实现自由」。对齐的部分自由的部分六端口协议与报文框架Flask → Spring BootREST 路由与响应形状并发模型gevent → JUCconfig.json/ SQLite / 记忆 JSON 文件格式配置载体system.conf → application.yml——依赖选型32 个 pip → 13 个 Maven结论你的前端、设备端、历史数据全都不用改。二、迁移前必须停掉 Python 版两版端口完全重合5000/10001/10002/10003/9001/8765不能同时运行。同机切换前先停掉 Python 版。三、三步搬家整个迁移流程① 停掉 Python 版端口重合不能同跑② 搬数据按需仅 memory/ 真正必搬③ 搬配置system.conf → application.yml④ 搬密钥→ fay-secrets.yml / FAY_*⑤ 启动验证六端口 mvn test回滚停 Java 直接启动 Python3.1 第 1 步搬数据按需先分清数据文件的「性质」——可再生的默认值没必要搬不可再生的历史数据才搬文件 / 目录性质是否需要搬system.conf系统配置要但要转格式见第 2 步config.json人设 / 交互 / 记忆开关建议搬同格式直接放同名文件memory/聊天记录 / 画像 / 记忆流仅当要延续历史时才搬唯一不可再生qa.csv指令问答库不用搬仓库自带你的内容可拷过来覆盖samples/、logs/运行期产物不用搬启动自动创建config/action_rules.csv动作规则只有改过才搬关于config.json的细节容易踩坑两版同格式都是json.dumps(sort_keysTrue, indent4)直接放同名文件即可键序缩进都不用改缺失也不影响启动全走内置默认值推荐做法是在管理页「人设」页重填保存会自动生成⚠config.json里的interact.QnA是问答库文件名默认qa.csv不是密钥、也不含路径前缀保持默认即可。3.2 第 2 步搬配置完整键名对照system.conf是 INIsnake_caseJava 版改成application.yml的fay.*kebab-case。先看一个迁移示例# system.confINI, snake_caseasr_mode ali tts_module azure gpt_api_key sk-xxx gpt_base_url https://api.example.com/v1 gpt_model_engine sensenova# ↓ 对应 application.ymlkebab-case密钥另放 fay-secrets.ymlfay:asr:mode:alitts:module:azurellm:base-url:https://api.example.com/v1model:sensenova下面是完整对照表不是摘录覆盖 system.conf 全部键system.conf键名application.yml键名start_modefay.start-modefay_urlfay.fay-urlproxy_configfay.proxy-configasr_modefay.asr.modelocal_asr_ipfay.asr.local-iplocal_asr_portfay.asr.local-portali_nls_key_id/ali_nls_key_secret/ali_nls_app_keyfay.asr.ali.key-id/.key-secret/.app-keytts_modulefay.tts.moduleali_tss_key_id/ali_tss_key_secret/ali_tss_app_keyfay.tts.ali.key-id/.key-secret/.app-keyms_tts_key/ms_tts_regionfay.tts.ms.key/.regionvolcano_tts_appidfay.tts.volcano.appidvolcano_tts_access_tokenfay.tts.volcano.access-tokenvolcano_tts_clusterfay.tts.volcano.clustervolcano_tts_voice_typefay.tts.volcano.voice-typegpt_api_key/gpt_base_url/gpt_model_enginefay.llm.api-key/.base-url/.modelbig_model_api_key/big_model_base_url/big_model_enginefay.big-model.api-key/.base-url/.modelembedding_api_key/embedding_base_url/embedding_api_modelfay.embedding.api-key/.base-url/.model四个补充说明都很关键fay.asr.local-port非法值从抛异常改为回退默认 10197复用规则fay.big-model.*与fay.embedding.*留空时复用fay.llm.*的同名项——但Embedding 若指向不同服务商如阿里云百炼fay.embedding.api-key必须单独填否则拿 LLM 的 key 去请求会 401baidu-emotion百度情感分析是 Java 侧新增system.conf无对应项改配置需重启只有config.json是热加载application.yml的fay.*在启动期绑定。3.3 第 3 步搬密钥完整落位表密钥不再写在配置文件里改填fay-secrets.ymlgitignore或FAY_*环境变量# fay-secrets.ymlgitignore密钥外置fay:llm:api-key:sk-xxxxbig-model:api-key:sk-yyyyembedding:api-key:sk-zzzz# 不同服务商必须单独填否则 401asr:ali:key-id:LTAIxxxxkey-secret:xxxxapp-key:xxxxtts:ali:key-id:LTAIxxxxkey-secret:xxxxapp-key:xxxx完整落位表配置项fay-secrets.yml路径环境变量阿里 NLS ASRfay.asr.ali.{key-id,key-secret,app-key}FAY_ASR_ALI_KEYID/FAY_ASR_ALI_KEYSECRET/FAY_ASR_ALI_APPKEY阿里 TTSfay.tts.ali.{key-id,key-secret,app-key}FAY_TTS_ALI_KEYID/FAY_TTS_ALI_KEYSECRET/FAY_TTS_ALI_APPKEY小模型 LLMfay.llm.api-keyFAY_LLM_APIKEY大模型fay.big-model.api-keyFAY_BIGMODEL_APIKEYEmbeddingfay.embedding.api-keyFAY_EMBEDDING_APIKEY四、依赖对照Python 那一堆库Java 用什么替代这是「Python → Java」迁移时大家最关心的问题。Python 版 32 个 pip 包Java 版压缩到 13 个 Maven 直接依赖下面是完整替代对照Python 库Java 侧替代flask/flask_cors/flask-httpauthSpring Boot Web CorsConfigBasicAuthFilterrequestsJDKjava.net.http.HttpClientwebsockets/ws4py/websocket-clientJava-WebSocketpyaudio/pygame/wave/audioopjavax.sound.sampledAudioMathnumpy/scipy纯 Javashort[]/byte[]运算 线性插值重采样langchain/langchain_openai/langgraphLangChain4j 自研状态机mcpMCP Java SDKtenacity自研RetryHelperscheduleScheduledExecutorServicepsutilOSHIdifflib自实现QuickRatiopytzjava.time.ZoneIdpydub ffmpegProcessBuilder调外部 ffmpeg可选edge_tts自实现 WS SecMsGecToken mp3spiazure-cognitiveservices-speechAzure Speech REST APIaliyun-python-sdk-core自实现 NLS token 签名 WSMyThread自研ManagedThreadssentence_transformers/chromadb未迁移Embedding 走 DashScope APIopenpyxl/python-docx/bs4/opencv-python/simhash未迁移当前版本未使用从这张表能看出几个迁移策略能用 JDK 自带的就用 JDKrequests→HttpClient、pyaudio→javax.sound、pytz→java.time、schedule→ScheduledExecutorService纯算法手写替代 numpy/scipyVAD 的 RMS、音频重采样用 short[] 运算去掉最大的 native 依赖自研协议替代 SDKedge_tts 的 DRM token、阿里 NLS 的 token 签名都自实现避免依赖不稳定的第三方 SDK未使用的能力直接砍openpyxl/python-docx/bs4/opencv/simhash这些当前版本没用到不迁移。五、迁移后验证清单项验证方式六端口启动日志确认 5000/10001/10002/10003/9001/8765 均监听引擎选择生效POST /api/get-data返回音色列表与fay.tts.module一致密钥导入生效启动日志出现 embedding 预热成功如 1024 维契约不回退mvn test338 用例全绿重点看it/ApiContractCompatTest、it/ProtocolCompatTest前端零改动Live2D 前端直连 10002管理页直连 5000历史数据聊天记录、成员画像、记忆流可直接读出六、回滚想切回 Python 版停掉 Java 进程、直接启动 Python 版即可。两版共用同一份数据文件system.conf若已删除从备份恢复或按第三节的配置对照表反向填回。七、迁移的成本到底是多少用一句话总结这套迁移的真实成本真正「必须从 Python 版拿」的只有system.conf转格式和memory/若要留历史其余要么仓库自带、要么启动自动生成。而且换来的是告别 conda/pip 环境、告别 gevent/pyaudio/numpy 的 native 依赖32 个 pip 包 → 13 个 Maven 依赖且全部无需编译 native 扩展338 个自动化测试兜底Python 版几乎无自动化测试Spring Boot 工程化治理依赖注入、线程池、结构化日志。对 Java 团队来说这是一次很划算的切换。系列完结 · 项目地址这套系列共 8 篇从总览到迁移完整覆盖了 fay-java祝大家国庆节快乐Giteehttps://gitee.com/liutao-lx/fay-javaGitHubhttps://github.com/liutao-lx/fay-java上游 Python 版 fayhttps://gitee.com/xszyou/fay许可GPL-3.0如果这套文章或项目对你有帮助欢迎点赞、收藏、关注、Star。也欢迎在评论区交流你的数字人落地场景——遇到问题提 issue我看到会尽快回复。