atoms框架通过multimodelrouter并行调用多模型,用structuredparser结合pydantic schema统一解析原始响应,再经去重合并输出结构化结果。
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜

你需要让Atoms框架同时调用多个大模型并统一解析返回结果,避免手动写三套解析逻辑、字段映射错乱、JSON结构不一致导致程序崩溃。
准备多模型适配器实例
先确保每个模型都已注册为Atoms兼容的适配器。打开项目中的adapters/目录,确认存在qwen_adapter.py、glm_adapter.py、deepseek_adapter.py三个文件,且每个都继承自BaseModelAdapter并实现invoke()方法。
在config.yaml中检查models区块是否完整声明了三个模型的endpoint、price_per_1k_input等字段,【缺一个模型配置会导致路由失败时静默跳过,不会报错】。
初始化时用MultiModelRouter(config_path="config.yaml")加载全部适配器,它会自动按provider字段名绑定对应类。
发起并行调用并获取原始响应
调用router.batch_invoke(prompts=["分析用户情绪", "总结会议纪要"], models=["qwen", "glm", "deepseek"]),该方法返回list[dict],每个元素含model_name、raw_response(原始HTTP响应体)、status_code字段。
注意:不要直接对raw_response做json.loads()——不同模型返回结构差异极大,Qwen返回choices[0].message.content,GLM返回data.choices[0].content,DeepSeek则带usage嵌套在根层级。硬解析必出KeyError。
用统一Schema定义结构化输出
创建Pydantic v2模型AnalysisResult,字段必须覆盖所有模型可能返回的关键信息:
class AnalysisResult(BaseModel):
text: str = Field(..., description="核心分析结论,非空")
confidence: float = Field(0.0, ge=0.0, le=1.0, description="置信度,若模型未提供则设为0.5")
model_used: str = Field(..., description="实际调用的模型名,如'qwen-32b')"
tokens_used: int = Field(0, ge=0, description="输入+输出token总数,若不可得则为0")
这一步是解析成败的关键:字段名和类型约束必须严格匹配你后续要提取的数据维度,【description字符串会被注入到系统提示词中,影响模型是否主动返回该字段】。
执行结构化解析
方法一:使用Atoms内置的StructuredParser
实例化parser = StructuredParser(schema=AnalysisResult),然后遍历batch_invoke()返回的每个原始响应,调用parser.parse(response["raw_response"], model_name=response["model_name"])。
方法二:手动注入schema到模型提示中(仅当需要强控制时)
构造prompt前缀:"请严格按JSON格式输出,只包含以下字段:text、confidence、model_used、tokens_used。不要任何额外说明或markdown标记。" + json.dumps(AnalysisResult.model_json_schema(), indent=2),再拼接用户原始prompt。
方法三:用正则兜底提取(防崩必备)
当parse()抛出ValidationError时,启用备用路径:用re.search(r'"text":\s*"([^"]+)"', raw_str)提取text,用re.search(r'"confidence":\s*(\d*\.?\d+)', raw_str)提取confidence,其余字段填默认值。这步能防止某一个模型返回脏数据拖垮整个批次。
合并与去重处理
第一步:按model_used分组,统计各模型的tokens_used总和,写入cost_report.csv供财务核对。
第二步:若多个模型返回的text相似度>85%(用cosine_similarity比对sentence-transformers向量),保留confidence最高的那个结果,丢弃其余。
第三步:将最终选中的AnalysisResult实例序列化为dict,直接传给下游数据库写入或API响应返回。











