290 lines
15 KiB
Plaintext
290 lines
15 KiB
Plaintext
# =============================================================================
|
||
# Life Echo API — 模板(example)
|
||
#
|
||
# 本地:复制为 .env.development(勿提交密钥),再运行 api/development.sh 会在首次自动生成 .env(从
|
||
# .env.development 复制);Settings 只读 .env(见 app/core/config.py)。
|
||
# 服务端:仓库维护 .env.staging / .env.production;workflow 按目标环境上传并复制为运行时 .env,compose 的 env_file 统一指向 .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)
|
||
# =============================================================================
|
||
LOG_LEVEL=INFO
|
||
# Agent 单行 INFO 摘要(耗时、路由、段落规模);与 LOG_LEVEL 独立,便于生产短暂排查
|
||
# LOG_AGENT_VERBOSE=0
|
||
# DEBUG 下 prompt/响应预览最大字符数
|
||
# AGENT_LOG_MAX_CHARS=4096
|
||
# DEBUG 下访谈/资料:省略 SystemMessage 正文(仅 total_len+sha12);0/false=打出全文
|
||
# AGENT_LOG_OMIT_SYSTEM_MESSAGE_BODY=1
|
||
# DEBUG 下超长单段 *.prompt:总长超过下一项时,先跳过前 N 字符再预览(0=不跳过)
|
||
# AGENT_LOG_JSON_PROMPT_PREFIX_CHARS=0
|
||
# AGENT_LOG_JSON_PROMPT_PREFIX_ONLY_IF_LEN_GT=4000
|
||
# 第三方 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_BASE_URL=https://api.deepseek.com
|
||
DEEPSEEK_MODEL=deepseek-chat
|
||
|
||
# =============================================================================
|
||
# Memory 向量(智谱 BigModel 国内 embedding-3;与 DeepSeek/OpenAI 用途分离)
|
||
# 文档:https://docs.bigmodel.cn/cn/guide/models/embedding/embedding-3
|
||
# 本期固定 1024 维;库表经迁移与 MEMORY_EMBEDDING_DIMENSION 一致。
|
||
# =============================================================================
|
||
ZHIPU_API_KEY=your_zhipu_api_key
|
||
# 默认国内通用端点(与 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
|
||
# 访谈性格(InterviewAgent):default | warm_listener | curious_guide
|
||
# CHAT_INTERVIEW_PERSONA=default
|
||
# 访谈回复长度档位(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
|
||
# 访谈:是否按本轮用户话检索记忆并注入提示词(关则不调 retrieve)
|
||
# CHAT_MEMORY_RETRIEVAL_ENABLED=true
|
||
# CHAT_MEMORY_TOP_K=8
|
||
# CHAT_MEMORY_EVIDENCE_MAX_CHARS=4096
|
||
|
||
# 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
|
||
# True:仅 is_from_voice 时走 LLM 纠错;键盘输入仅规则归一
|
||
# CHAT_INPUT_NORMALIZE_LLM_VOICE_ONLY=true
|
||
# 短时/应答/元话语:本轮跳过阶段 LLM 与记忆向量检索(仍保留访谈主 LLM);关则每轮完整路径
|
||
# CHAT_SUBSTANTIVE_HEURISTIC_ENABLED=true
|
||
# CHAT_SUBSTANTIVE_MIN_CHARS=12
|
||
# CHAT_STAGE_DETECTION_SKIP_LLM_ON_INSUFFICIENT_SIGNAL=true
|
||
# CHAT_MEMORY_RETRIEVAL_REQUIRE_SUBSTANTIVE=true
|
||
# 资料收集:短时/元话语不跑资料字段抽取 LLM(仍生成追问)
|
||
# CHAT_PROFILE_EXTRACT_REQUIRE_SUBSTANTIVE=true
|
||
|
||
# Memoir Phase1:True 时用一次「批量 JSON」做抽取+分类(单段或多段均可;失败自动回退逐段)。
|
||
# False 时始终逐段(与启用本开关前的行为一致,含防抖合并后的多段任务)。
|
||
# MEMOIR_PHASE1_BATCH_LLM_ENABLED=false
|
||
# MEMOIR_PHASE1_BATCH_LLM_MAX_TOKENS=4096
|
||
|
||
# =============================================================================
|
||
# Database
|
||
# =============================================================================
|
||
# 本地开发:
|
||
# DATABASE_URL=postgresql://postgres:postgres@localhost:5432/life_echo
|
||
# Docker / 服务端(主机名一般为 compose 服务名 postgres):
|
||
# DATABASE_URL=postgresql://postgres:postgres@postgres:5432/life_echo
|
||
DATABASE_URL=postgresql://postgres:postgres@localhost: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
|
||
# =============================================================================
|
||
# 本地开发:
|
||
# REDIS_URL=redis://localhost:6379/0
|
||
# Docker / 服务端:
|
||
# REDIS_URL=redis://redis:6379/0
|
||
REDIS_URL=redis://localhost:6379/0
|
||
REDIS_SESSION_TTL=86400
|
||
|
||
# =============================================================================
|
||
# Memory compaction(近重复 memory chunk 软排除;Celery + Redis 防抖)
|
||
# 模板统一默认开启;须同时运行 celery worker 与 celery-beat(docker-compose 已含 beat,负责 memory_compaction_sweep)。
|
||
# =============================================================================
|
||
MEMORY_COMPACTION_ENABLED=true
|
||
# MEMORY_COMPACTION_DEBOUNCE_SECONDS=105
|
||
# MEMORY_COMPACTION_LOCK_TTL_SECONDS=600
|
||
# MEMORY_COMPACTION_CHUNK_SIMILARITY_THRESHOLD=0.92
|
||
# MEMORY_COMPACTION_MIN_LAYERS_FOR_EXCLUDE=2
|
||
# MEMORY_COMPACTION_MAX_CHUNKS_PER_RUN=200
|
||
# MEMORY_COMPACTION_MAX_EXCLUDES_PER_RUN=50
|
||
# MEMORY_COMPACTION_MAX_NEIGHBORS_PER_CHUNK=25
|
||
# MEMORY_COMPACTION_TEXT_JACCARD_MIN=0.55
|
||
# 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
|
||
# 与 Phase2 / 章节物化共用;应 ≥ 最长单次叙事+物化耗时
|
||
# CHAPTER_PIPELINE_LOCK_TTL_SECONDS=360
|
||
# 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
|
||
#
|
||
# Memoir 可靠性(叙事 faithful、标题 slots、证据渗漏、Phase1→2 追踪)
|
||
# MEMOIR_FIDELITY_FAIL_OPEN_ON_PARSE_ERROR=false
|
||
# MEMOIR_NARRATIVE_EVIDENCE_OVERLAP_MIN_CHARS=14
|
||
# MEMOIR_EVIDENCE_SCENE_ANCHOR_CHECK_ENABLED=true
|
||
# MEMOIR_TITLE_SLOTS_REQUIRE_BODY_OR_ORAL_MATCH=true
|
||
# MEMOIR_TITLE_HAY_GROUNDING_STRICT_PHRASES_ENABLED=true
|
||
# MEMOIR_RECOMPOSE_RETRY_ON_LOCK_CONTENTION=true
|
||
# MEMOIR_PHASE2_SINGLEFLIGHT_IMMEDIATE=true
|
||
#
|
||
# Memory:事实检索未命中时是否退回「最近 confirmed 事实」(默认关,易串台)
|
||
# MEMORY_FACT_SEARCH_USE_RECENT_FALLBACK=false
|
||
|
||
# =============================================================================
|
||
# Auth
|
||
# =============================================================================
|
||
# 建议使用: openssl rand -hex 32
|
||
SECRET_KEY=replace_with_a_strong_random_secret
|
||
ALGORITHM=HS256
|
||
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
|
||
# 短信应用 SDK AppID
|
||
TENCENT_SMS_SDK_APP_ID=your_sms_sdk_app_id
|
||
# 短信签名内容(不包含【】符号)
|
||
TENCENT_SMS_SIGN_NAME=your_sms_sign_name
|
||
# 短信模板 ID
|
||
TENCENT_SMS_TEMPLATE_ID=your_sms_template_id
|
||
# 短信模板参数数量(1=仅验证码,2=验证码+过期时间)
|
||
# 若遇 TemplateParamSetNotMatchApprovedTemplate,请对照控制台模板配置
|
||
TENCENT_SMS_TEMPLATE_PARAM_COUNT=1
|
||
|
||
# =============================================================================
|
||
# ASR Provider(whisper | tencent)
|
||
# =============================================================================
|
||
ASR_PROVIDER=whisper
|
||
|
||
# =============================================================================
|
||
# Whisper ASR(ASR_PROVIDER=whisper 时使用)
|
||
# =============================================================================
|
||
ASR_MODEL_SIZE=small
|
||
ASR_DEVICE=cpu
|
||
ASR_COMPUTE_TYPE=int8
|
||
|
||
# GPU 环境(示例,按需启用)
|
||
# ASR_MODEL_SIZE=medium
|
||
# ASR_DEVICE=cuda
|
||
# ASR_COMPUTE_TYPE=float16
|
||
|
||
# =============================================================================
|
||
# 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
|
||
|
||
# =============================================================================
|
||
# TTS(文字转语音,Agent 回复播音)— 与 ASR 独立
|
||
# =============================================================================
|
||
# ENABLE_TTS:仅控制是否合成并下发 TTS_AUDIO;不影响用户语音转写(ASR)
|
||
ENABLE_TTS=true
|
||
TTS_PROVIDER=tencent
|
||
# 仅 TTS_PROVIDER=openai 时需要
|
||
# OPENAI_API_KEY=your_openai_api_key
|
||
# 音色 ID 见 https://cloud.tencent.com/document/product/1073/92668
|
||
TTS_VOICE_TYPE=502001
|
||
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
|
||
# 商户私钥:推荐使用文件路径,避免 .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_PLATFORM_PUBLIC_KEY_PATH=certs/wechat_platform_public_key.pem
|
||
# WECHAT_PAY_PLATFORM_PUBLIC_KEY_ID=your_wechat_platform_public_key_id
|
||
|
||
# =============================================================================
|
||
# Alipay
|
||
# =============================================================================
|
||
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
|
||
|
||
# =============================================================================
|
||
# Misc
|
||
# =============================================================================
|
||
ENABLE_TEST_SUBSCRIPTION=0
|
||
|
||
# =============================================================================
|
||
# Memoir image generation(Story 主图等;轮询 Liblib 任务)
|
||
# =============================================================================
|
||
MEMOIR_IMAGE_ENABLED=false
|
||
MEMOIR_IMAGE_POLL_INTERVAL=3
|
||
MEMOIR_IMAGE_MAX_ATTEMPTS=20
|
||
MEMOIR_IMAGE_PROVIDER=liblib
|
||
MEMOIR_IMAGE_STYLE_DEFAULT=watercolor
|
||
MEMOIR_IMAGE_SIZE_DEFAULT=1280x720
|
||
# Story 正文至少多少字才生成主图 intent / 调图(0=不限制)
|
||
STORY_IMAGE_MIN_BODY_CHARS=400
|
||
# 叙事模型输出相对口述过短则回退为口述原文
|
||
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_BASE_URL=https://openapi.liblibai.cloud
|
||
LIBLIB_TEMPLATE_UUID=your_liblib_template_uuid
|
||
|
||
# =============================================================================
|
||
# Tencent Cloud — COS(回忆录图片存储)
|
||
# =============================================================================
|
||
TENCENT_COS_SECRET_ID=your_tencent_cos_secret_id
|
||
TENCENT_COS_SECRET_KEY=your_tencent_cos_secret_key
|
||
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_TOKEN=
|