Files
chongming-plugins/doubao/__init__.py
T

107 lines
4.3 KiB
Python
Raw Normal View History

2026-07-21 15:43:39 +08:00
"""
豆包视觉理解 Worker 插件
2026-08-14 16:04:39 +08:00
基于 Plugin 基类统一生命周期:on_init 中按配置创建 Ark / AICC 客户端,
on_cleanup 释放客户端引用(无数据库)。
2026-07-21 15:43:39 +08:00
"""
import os
2026-07-31 16:53:38 +08:00
import logging
2026-07-27 14:28:07 +08:00
from openai import AsyncOpenAI
2026-07-21 15:43:39 +08:00
from volcenginesdkarkruntime import AsyncArk
2026-08-14 16:04:39 +08:00
from chongming_worker.plugin import Plugin
2026-07-27 14:28:07 +08:00
from .global_var import (
set_ark_client, set_aicc_client, set_is_aicc,
cleanup_all,
)
2026-08-14 16:04:39 +08:00
from .router import * # noqa: F401,F403 触发 @rpc_method 注册
logger = logging.getLogger(__name__)
class DoubaoPlugin(Plugin):
"""豆包插件 — 统一生命周期。"""
type = "doubao"
db_name = None # 无数据库
auto_bind = True # 首次初始化时自动 auto_bind_models("doubao")
2026-07-21 15:43:39 +08:00
2026-08-14 16:04:39 +08:00
async def on_init(self):
"""首次 create_workers 时调用一次:初始化豆包客户端。"""
config = self.config
logger.info("豆包插件初始化开始 (count=%s, aicc=%s)",
config.get("count", 1), config.get("is_aicc", False))
2026-07-31 16:53:38 +08:00
2026-08-14 16:04:39 +08:00
is_aicc = config.get("is_aicc", False)
set_is_aicc(is_aicc)
2026-07-21 15:43:39 +08:00
2026-08-14 16:04:39 +08:00
api_key = config.get("api_key") or os.environ.get("VOLC_ACCESSKEY")
if not api_key:
logger.error("豆包插件初始化失败: 缺少 API_KEY")
raise ValueError("缺少 API_KEY,请在配置中设置 api_key 或环境变量 VOLC_ACCESSKEY")
2026-07-31 16:53:38 +08:00
2026-08-14 16:04:39 +08:00
model = config.get("model", "doubao-seed-evolving")
os.environ["DOUBAO_MODEL"] = model
logger.info("豆包模型: %s", model)
2026-07-27 14:28:07 +08:00
2026-08-14 16:04:39 +08:00
if is_aicc:
logger.info("豆包使用 AICC 安全通信模式")
# AICC 模式:懒加载,避免非 AICC 环境导入失败
try:
from bytedance.volcengine_aicc_sdk.secure_http_client import (
AICCConfig, AsyncSecureHttpClient,
)
except ImportError as e:
logger.error("AICC SDK 导入失败: %s,请确认已安装 bytedance_volcengine_aicc_sdk", e)
raise
2026-07-21 15:43:39 +08:00
2026-08-14 16:04:39 +08:00
base_url = config.get("base_url", "https://ark.cn-beijing.volces.com/api/v3")
# ra_url 为远程证明(安全令牌)端点地址,可能与推理 base_url 不同
# 若不单独配置则默认使用 base_url 的域名 + /v1/security/token
ra_url = config.get("ra_url", base_url)
ak = config.get("ak", "")
sk = config.get("sk", "")
ra_service_name = config.get("ra_service_name", "AICC.ConfidentialInference")
ra_policy_id = config.get("ra_policy_id", "router_policy")
2026-07-21 15:43:39 +08:00
2026-08-14 16:04:39 +08:00
os.environ["DOUBAO_BASE_URL"] = base_url
logger.info("豆包 AICC base_url: %s, ra_url: %s, ra_service_name: %s, ra_policy_id: %s",
base_url, ra_url, ra_service_name, ra_policy_id)
aicc_config = AICCConfig(
ra_url=ra_url,
auth_token=api_key,
ak=ak,
sk=sk,
aicc_llm_service_name=ra_service_name,
policy_id=ra_policy_id,
)
client = AsyncOpenAI(
api_key=api_key,
base_url=base_url,
2026-09-04 14:51:12 +08:00
http_client=AsyncSecureHttpClient(aicc_config=aicc_config), # type: ignore
2026-07-31 16:53:38 +08:00
)
2026-08-14 16:04:39 +08:00
set_aicc_client(client)
logger.info("豆包 AICC 客户端已创建")
else:
logger.info("豆包使用标准 Ark SDK 模式")
# Ark 模式:使用 AsyncArk
base_url = config.get("base_url", "https://ark.cn-beijing.volces.com/api/v3")
os.environ["DOUBAO_BASE_URL"] = base_url
client = AsyncArk(base_url=base_url, api_key=api_key)
set_ark_client(client)
logger.info("豆包 Ark 客户端已创建 (base_url=%s)", base_url)
logger.info("豆包插件初始化完成")
async def on_cleanup(self):
"""cleanup 时调用:释放客户端引用。"""
cleanup_all()
logger.info("[doubao] 清理完成")
# 暴露给 app lifespan 的模块级入口(bound method,签名与旧写法完全一致)
plugin = DoubaoPlugin()
create_workers = plugin.create_workers
cleanup = plugin.cleanup