diff --git a/api/.env.staging b/api/.env.staging index d170d40..c059d7b 100644 --- a/api/.env.staging +++ b/api/.env.staging @@ -1,20 +1,23 @@ -LIFE_ECHO_API_HOST_BIND=0.0.0.0 -LIFE_ECHO_API_HOST_PORT=8000 -POSTGRES_HOST_PORT=15432 +# ============================================================================= +# Life Echo API — production(生产) +# +# 仓库维护本文件;production 发布时 workflow 会上传并复制为运行时 .env。 +# 若仓库可被非授权人员访问,请不要在此文件中保留真实密钥。 +# ============================================================================= # ============================================================================= -# Life Echo API — staging(预发) -# -# 仓库维护本文件;staging 发布时 workflow 会上传并复制为运行时 .env。 -# 不要把生产密钥误填进本文件。 +# Docker Compose(宿主机独立 Caddy 反代到本 API) # ============================================================================= +# 映射到宿主机的端口,默认 8000;与同机其它项目冲突时改为未占用端口,并在独立 Caddy 的 Caddyfile 中 reverse_proxy 到 127.0.0.1:该端口。 +# LIFE_ECHO_API_HOST_PORT=8000 +# 若 Caddy 跑在独立容器且非 host 网络,不要用 127.0.0.1,应把 Caddy 加入与本 compose 相同的 Docker 网络,并对 http://life-echo-api-prod:8000 做 reverse_proxy。 # ============================================================================= # Logging(loguru sink 最低级别:TRACE / DEBUG / INFO / WARNING / ERROR / CRITICAL) # ============================================================================= -# 预发默认 INFO;勿长期 DEBUG。查慢路径可短时 LOG_AGENT_VERBOSE=1。 +# 生产默认 INFO;勿长期 DEBUG。排障 Agent 耗时可短时 LOG_AGENT_VERBOSE=1。 LOG_LEVEL=INFO -# Agent 单行 INFO 摘要;与 LOG_LEVEL 独立 +# Agent 单行 INFO 摘要;与 LOG_LEVEL 独立,便于生产短暂排查 # LOG_AGENT_VERBOSE=0 # DEBUG 下预览上限(默认 4096);0=全文 # AGENT_LOG_MAX_CHARS=4096 @@ -26,17 +29,63 @@ LOG_LEVEL=INFO # DEBUG 下超长单段 *.prompt:先跳过前 N 字符再预览 # AGENT_LOG_JSON_PROMPT_PREFIX_CHARS=0 # AGENT_LOG_JSON_PROMPT_PREFIX_ONLY_IF_LEN_GT=4000 -# 第三方 stdlib logging(空=自动) +# 第三方 stdlib logging(空=自动:LOG_LEVEL 为 DEBUG/TRACE 时 Celery→INFO、httpx/httpcore→WARNING,减少刷屏) # CELERY_LOG_LEVEL= # HTTPX_LOG_LEVEL= # ============================================================================= # LLM / DeepSeek # ============================================================================= -DEEPSEEK_API_KEY=your_deepseek_api_key +DEEPSEEK_API_KEY=sk-09f17fb61c5a4299a3afc2a01de7af75 DEEPSEEK_BASE_URL=https://api.deepseek.com DEEPSEEK_MODEL=deepseek-v4-flash +# ============================================================================= +# Memory 向量(智谱 BigModel 国内 embedding-3;与 DeepSeek/OpenAI 用途分离) +# 文档:https://docs.bigmodel.cn/cn/guide/models/embedding/embedding-3 +# 本期固定 1024 维;库表经迁移与 MEMORY_EMBEDDING_DIMENSION 一致。 +# ============================================================================= +ZHIPU_API_KEY=524eda18eb3848e881eefe4c7ef17ec2.xBmGUabYDEa44m3M +# 默认国内通用端点(与 ZhipuAiClient 一致) +# EMBEDDING_BASE_URL=https://open.bigmodel.cn/api/paas/v4 +EMBEDDING_MODEL=embedding-3 + +# Chat 访谈:每轮根据用户内容判定主人生阶段(关则仅用关键词,省一次 LLM) +# CHAT_STAGE_DETECTION_ENABLED=true +# CHAT_STAGE_DETECTION_MAX_TOKENS=128 +# 访谈者体验(覆盖 config 默认值;与 api/.env.development 对齐时可减少文风漂移与记忆噪声) +CHAT_ERA_CONTEXT_ENABLED=true +CHAT_INTERVIEW_PERSONA=warm_listener +CHAT_INTERVIEW_TEMPERATURE=0.65 +# 访谈:是否按本轮用户话检索记忆并注入提示词(关则不调 retrieve) +# CHAT_MEMORY_RETRIEVAL_ENABLED=true +CHAT_MEMORY_TOP_K=4 +CHAT_MEMORY_EVIDENCE_MAX_CHARS=1400 +CHAT_REPLY_PLANNER_LLM_ENABLED=true +# 访谈回复长度档位(brief/standard/expanded)联动:极短输入 / 默认 / 长段+新细节 +# CHAT_INTERVIEW_BRIEF_MAX_TOKENS=240 +# CHAT_INTERVIEW_BRIEF_MAX_CHARS_PER_SEGMENT=180 +# CHAT_INTERVIEW_EXPANDED_MAX_TOKENS=400 +# CHAT_INTERVIEW_EXPANDED_MAX_CHARS_PER_SEGMENT=300 + +# Memoir:批处理/抽取更新 slot 时是否允许改写 MemoirState.current_stage(默认 false,访谈 switch_stage 仍可推进) +# True 时仅当 proposed 与 existing 在同一 chat_bucket 才对齐 current_stage +# MEMOIR_EXTRACTION_UPDATES_CURRENT_STAGE=false + +# Memoir:叙事前口述归一(segment 原文仍落库;仅 story 流水线派生输入) +MEMOIR_ORAL_NORMALIZE_ENABLED=true +# off | rules | llm(llm 为先规则再 LLM 纠错,失败回退规则结果) +MEMOIR_ORAL_NORMALIZE_MODE=llm +MEMOIR_ORAL_NORMALIZE_LLM_MAX_TOKENS=512 +MEMOIR_ORAL_NORMALIZE_LLM_MAX_INPUT_CHARS=8000 + +# Chat:模型消费净稿(segment 原文仍落库;访谈编排层归一后注入 Agent / 记忆检索) +# CHAT_INPUT_NORMALIZE_ENABLED=true +# off | rules | llm(llm 为先规则再 LLM;失败回退规则;编排层已带 LLM 时不重复在 Agent 调) +# CHAT_INPUT_NORMALIZE_MODE=rules +# CHAT_INPUT_NORMALIZE_LLM_MAX_TOKENS=512 +# CHAT_INPUT_NORMALIZE_LLM_MAX_INPUT_CHARS=8000 + # ============================================================================= # Database # ============================================================================= @@ -45,6 +94,11 @@ DEEPSEEK_MODEL=deepseek-v4-flash # Docker / 服务端(主机名一般为 compose 服务名 postgres): # DATABASE_URL=postgresql://postgres:postgres@postgres:5432/life_echo DATABASE_URL=postgresql://postgres:postgres@postgres:5432/life_echo +# 启动时 Alembic(main.py);生产可设 ALEMBIC_STARTUP_FAIL_FAST=true,迁移失败则拒绝启动 +# ALEMBIC_RUN_ON_STARTUP=true +# ALEMBIC_STARTUP_FAIL_FAST=false +# ALEMBIC_STARTUP_MAX_RETRIES=3 +# ALEMBIC_STARTUP_RETRY_BASE_SECONDS=1.0 # ============================================================================= # Redis @@ -61,7 +115,7 @@ REDIS_SESSION_TTL=86400 # ============================================================================= # Memory compaction(近重复 memory chunk 软排除;Celery + Redis 防抖) -# 与 example / development / production 一致默认开启;预发须跑 worker + celery-beat。 +# 与 .env.example / .env.development 一致默认开启;需 running:celery worker + celery-beat(见 docker-compose.yml)。 # ============================================================================= MEMORY_COMPACTION_ENABLED=true # MEMORY_COMPACTION_DEBOUNCE_SECONDS=105 @@ -75,11 +129,23 @@ MEMORY_COMPACTION_ENABLED=true # MEMORY_COMPACTION_METADATA_EVENT_YEAR_WINDOW=1 # MEMORY_COMPACTION_SWEEP_RECENT_HOURS=24 +# ============================================================================= +# Story 流水线(post-commit、章节物化、append 上限、evidence 检索) +# ============================================================================= +# STORY_IMAGE_ENQUEUE_DEDUP_TTL=300 +# RECOMPOSE_CHAPTER_DELAY_SECONDS=8 +# CHAPTER_PIPELINE_LOCK_TTL_SECONDS=120 +# STORY_APPEND_MAX_CANONICAL_CHARS=12000 +# STORY_APPEND_MAX_VERSIONS=20 +# EVIDENCE_TOP_K_DEFAULT=10 +# EVIDENCE_TOP_K_LARGE_BATCH=5 +# EVIDENCE_LARGE_BATCH_THRESHOLD=3 + # ============================================================================= # Auth # ============================================================================= # 建议使用: openssl rand -hex 32 -SECRET_KEY=replace_with_a_strong_random_secret +SECRET_KEY=cf47555c7ecbe5ddb7fd2113c59e08a8bcb110810c42f7c644e06a5acc898608 ALGORITHM=HS256 ACCESS_TOKEN_EXPIRE_MINUTES=120 @@ -87,14 +153,14 @@ ACCESS_TOKEN_EXPIRE_MINUTES=120 # Tencent Cloud — 短信 # ============================================================================= # 短信、一句话 ASR/TTS、COS 为不同产品;同一主账号可共用同一对 SecretId/SecretKey(分别填三处)。 -TENCENT_SMS_SECRET_ID=your_tencent_sms_secret_id -TENCENT_SMS_SECRET_KEY=your_tencent_sms_secret_key +TENCENT_SMS_SECRET_ID=AKIDa2ILCwUr56uVt31oU0JOHxPfGhvvkLiq +TENCENT_SMS_SECRET_KEY=xiFbjlZ9XheS2NWYLvHRPAh2A5nGYcR2 # 短信应用 SDK AppID -TENCENT_SMS_SDK_APP_ID=your_sms_sdk_app_id +TENCENT_SMS_SDK_APP_ID=1401010099 # 短信签名内容(不包含【】符号) -TENCENT_SMS_SIGN_NAME=your_sms_sign_name +TENCENT_SMS_SIGN_NAME=上海华嘎科技有限公司 # 短信模板 ID -TENCENT_SMS_TEMPLATE_ID=your_sms_template_id +TENCENT_SMS_TEMPLATE_ID=2592163 # 短信模板参数数量(1=仅验证码,2=验证码+过期时间) # 若遇 TemplateParamSetNotMatchApprovedTemplate,请对照控制台模板配置 TENCENT_SMS_TEMPLATE_PARAM_COUNT=1 @@ -102,7 +168,7 @@ TENCENT_SMS_TEMPLATE_PARAM_COUNT=1 # ============================================================================= # ASR Provider(whisper | tencent) # ============================================================================= -ASR_PROVIDER=whisper +ASR_PROVIDER=tencent # ============================================================================= # Whisper ASR(ASR_PROVIDER=whisper 时使用) @@ -119,8 +185,8 @@ ASR_COMPUTE_TYPE=int8 # ============================================================================= # Tencent Cloud — 一句话 ASR + TTS(ASR_PROVIDER=tencent 或 TTS_PROVIDER=tencent) # ============================================================================= -TENCENT_SECRET_ID=your_tencent_asr_secret_id -TENCENT_SECRET_KEY=your_tencent_asr_secret_key +TENCENT_SECRET_ID=AKIDa2ILCwUr56uVt31oU0JOHxPfGhvvkLiq +TENCENT_SECRET_KEY=xiFbjlZ9XheS2NWYLvHRPAh2A5nGYcR2 # ============================================================================= # TTS(文字转语音,Agent 回复朗读)— 与 ASR 独立 @@ -130,8 +196,8 @@ TENCENT_SECRET_KEY=your_tencent_asr_secret_key # 若 ENABLE_TTS=true 且该轮 `tts_this_turn=true`:每一段助手文案先下发 `tts_audio`,再下发对应段的 `agent_response`。 ENABLE_TTS=true TTS_PROVIDER=tencent -# 仅 TTS_PROVIDER=openai 时需要 -# OPENAI_API_KEY=your_openai_api_key +# 仅 TTS_PROVIDER=openai 时需要(填控制台密钥;勿在注释行写 =your_* 以免旧版 CI 误匹配) +# OPENAI_API_KEY= # 音色 ID 见 https://cloud.tencent.com/document/product/1073/92668 TTS_VOICE_TYPE=501004 TTS_CODEC=mp3 @@ -139,36 +205,36 @@ TTS_CODEC=mp3 # ============================================================================= # WeChat Pay # ============================================================================= -WECHAT_PAY_APP_ID=your_wechat_pay_app_id -WECHAT_PAY_MCH_ID=your_wechat_mch_id -WECHAT_PAY_API_V3_KEY=your_wechat_api_v3_key +WECHAT_PAY_APP_ID=wx1df508452e06cfb8 +WECHAT_PAY_MCH_ID=1662979099 +WECHAT_PAY_API_V3_KEY=xjvGSJLGJAJfjgskfjslafjsajsdjals # 商户私钥:推荐使用文件路径,避免 .env 中长 PEM 转义问题 WECHAT_PAY_PRIVATE_KEY_PATH=certs/apiclient_key.pem # 若不用文件,可配置 WECHAT_PAY_PRIVATE_KEY(PEM,换行用 \n) # WECHAT_PAY_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----" -WECHAT_PAY_CERT_SERIAL_NO=your_wechat_cert_serial_no -WECHAT_PAY_NOTIFY_URL=https://your-domain.com/api/payment/notify/wechat +WECHAT_PAY_CERT_SERIAL_NO=1AA82328AC1456C6F115B014606F22CD621D2032 +WECHAT_PAY_NOTIFY_URL=https://lifecho.worldsplats.com/api/payment/notify/wechat # 平台公钥模式(仅当无法走平台证书自动拉取时使用);勿填商户私钥路径 # WECHAT_PAY_PLATFORM_PUBLIC_KEY_PATH=certs/wechat_platform_public_key.pem -# WECHAT_PAY_PLATFORM_PUBLIC_KEY_ID=your_wechat_platform_public_key_id +# WECHAT_PAY_PLATFORM_PUBLIC_KEY_ID=PUB_KEY_ID_0116629790992026020700181671002400 # ============================================================================= -# Alipay +# Alipay(未接入时保持空字符串,与 Settings 默认一致) # ============================================================================= -ALIPAY_APP_ID=your_alipay_app_id -ALIPAY_PRIVATE_KEY=your_alipay_private_key -ALIPAY_PUBLIC_KEY=your_alipay_public_key -ALIPAY_NOTIFY_URL=https://your-domain.com/api/payment/notify/alipay +ALIPAY_APP_ID= +ALIPAY_PRIVATE_KEY= +ALIPAY_PUBLIC_KEY= +ALIPAY_NOTIFY_URL=https://lifecho.worldsplats.com/api/payment/notify/alipay # ============================================================================= # Misc # ============================================================================= -ENABLE_TEST_SUBSCRIPTION=0 +ENABLE_TEST_SUBSCRIPTION=1 # ============================================================================= # Memoir image generation(Story 主图等;轮询 Liblib 任务) # ============================================================================= -MEMOIR_IMAGE_ENABLED=false +MEMOIR_IMAGE_ENABLED=true MEMOIR_IMAGE_POLL_INTERVAL=3 MEMOIR_IMAGE_MAX_ATTEMPTS=20 MEMOIR_IMAGE_PROVIDER=liblib @@ -176,24 +242,33 @@ MEMOIR_IMAGE_STYLE_DEFAULT=watercolor MEMOIR_IMAGE_SIZE_DEFAULT=1280x720 # 章节正文内至少多少张 asset:// 插图才生成/展示章节封面(≥1 即有一张图可出封面) MEMOIR_MIN_INLINE_IMAGES_FOR_CHAPTER_COVER=1 +# Story 正文至少多少字才生成主图 intent / 调图(0=不限制) +STORY_IMAGE_MIN_BODY_CHARS=800 +# 叙事模型输出相对口述过短则回退为口述原文 +MEMOIR_NARRATIVE_FALLBACK_BODY_RATIO=0.5 +MEMOIR_NARRATIVE_FALLBACK_MIN_CHARS=20 +# 回忆录 segment 入队:累计 strip 后字数未达此值则暂缓提交 Celery(0=关闭字数门闸,仅静默防抖后提交) +# MEMOIR_SEGMENT_BATCH_MIN_CHARS=50 +# 本批首条入队起最长等待(秒),超时仍提交;测试可调低,生产可调高 +# MEMOIR_SEGMENT_BATCH_MAX_WAIT_SECONDS=60 # 可选,Liblib 返回图片域名不在默认白名单时(逗号分隔) # MEMOIR_IMAGE_DOWNLOAD_HOSTS=liblib.cloud,liblibai.cloud # ============================================================================= # Liblib image provider # ============================================================================= -LIBLIB_ACCESS_KEY=your_liblib_access_key -LIBLIB_SECRET_KEY=your_liblib_secret_key +LIBLIB_ACCESS_KEY=zrDp6quCOKlLwcewOEfrog +LIBLIB_SECRET_KEY=iTVHo5Nf3KA-xpC1Mja80bC93u6chJem LIBLIB_BASE_URL=https://openapi.liblibai.cloud -LIBLIB_TEMPLATE_UUID=your_liblib_template_uuid +LIBLIB_TEMPLATE_UUID=5d7e67009b344550bc1aa6ccbfa1d7f4 # ============================================================================= # Tencent Cloud — COS(回忆录图片存储) # ============================================================================= -TENCENT_COS_SECRET_ID=your_tencent_cos_secret_id -TENCENT_COS_SECRET_KEY=your_tencent_cos_secret_key +TENCENT_COS_SECRET_ID=AKIDa2ILCwUr56uVt31oU0JOHxPfGhvvkLiq +TENCENT_COS_SECRET_KEY=xiFbjlZ9XheS2NWYLvHRPAh2A5nGYcR2 TENCENT_COS_REGION=ap-shanghai -TENCENT_COS_BUCKET=your_bucket_name -TENCENT_COS_BASE_URL=https://your_bucket_name.cos.ap-shanghai.myqcloud.com +TENCENT_COS_BUCKET=life-echo-prod-1319381411 +TENCENT_COS_BASE_URL=https://life-echo-prod-1319381411.cos.ap-shanghai.myqcloud.com # 可选临时凭证 # TENCENT_COS_TOKEN=