微网站定制多久,知名网站建设联系电话,重庆网站建,网站建设培训班目录 理解 ContextMixin什么是 ContextMixin#xff1f;主要组件实现细节 测试 ContextMixin示例#xff1a;ModelX1. 配置优先级2. 多继承3. 多继承重写4. 配置优先级 在本文中#xff0c;我们将探索 ContextMixin 类#xff0c;它在多重继承场景中的集成及其在 Python 配… 目录 理解 ContextMixin什么是 ContextMixin主要组件实现细节 测试 ContextMixin示例ModelX1. 配置优先级2. 多继承3. 多继承重写4. 配置优先级 在本文中我们将探索 ContextMixin 类它在多重继承场景中的集成及其在 Python 配置和上下文管理中的应用。此外我们将通过测试验证其功能以了解它如何简化模型配置的处理。让我们深入了解代码片段的详细解释。 理解 ContextMixin
什么是 ContextMixin
ContextMixin 是一个用于高效管理上下文和配置的 Python 类。继承该类的模型或对象能够
通过灵活的优先级规则处理上下文private_context和配置private_config。管理与 LLMprivate_llm实例的交互。支持动态设置属性的覆盖机制。
主要组件 私有上下文和配置 private_context和 private_config 被设计为内部属性为每个实例提供灵活的作用域。这些属性默认值为 None但可以显式覆盖。 LLM 管理 通过 private_llm 集成 LLM支持从配置动态初始化。
实现细节
以下是核心 ContextMixin 类
from typing import Optionalfrom pydantic import BaseModel, ConfigDict, Field, model_validatorfrom metagpt.config2 import Config
from metagpt.context import Context
from metagpt.provider.base_llm import BaseLLMclass ContextMixin(BaseModel):Mixin class for context and configmodel_config ConfigDict(arbitrary_types_allowedTrue, extraallow)# Pydantic has bug on _private_attr when using inheritance, so we use private_* instead# - https://github.com/pydantic/pydantic/issues/7142# - https://github.com/pydantic/pydantic/issues/7083# - https://github.com/pydantic/pydantic/issues/7091# Env/Role/Action will use this context as private context, or use self.context as public contextprivate_context: Optional[Context] Field(defaultNone, excludeTrue)# Env/Role/Action will use this config as private config, or use self.context.config as public configprivate_config: Optional[Config] Field(defaultNone, excludeTrue)# Env/Role/Action will use this llm as private llm, or use self.context._llm instanceprivate_llm: Optional[BaseLLM] Field(defaultNone, excludeTrue)model_validator(modeafter)def validate_context_mixin_extra(self):self._process_context_mixin_extra()return selfdef _process_context_mixin_extra(self):Process the extra fieldkwargs self.model_extra or {}self.set_context(kwargs.pop(context, None))self.set_config(kwargs.pop(config, None))self.set_llm(kwargs.pop(llm, None))def set(self, k, v, overrideFalse):Set attributeif override or not self.__dict__.get(k):self.__dict__[k] vdef set_context(self, context: Context, overrideTrue):Set contextself.set(private_context, context, override)def set_config(self, config: Config, overrideFalse):Set configself.set(private_config, config, override)if config is not None:_ self.llm # init llmdef set_llm(self, llm: BaseLLM, overrideFalse):Set llmself.set(private_llm, llm, override)propertydef config(self) - Config:Role config: role config context configif self.private_config:return self.private_configreturn self.context.configconfig.setterdef config(self, config: Config) - None:Set configself.set_config(config)propertydef context(self) - Context:Role context: role context contextif self.private_context:return self.private_contextreturn Context()context.setterdef context(self, context: Context) - None:Set contextself.set_context(context)propertydef llm(self) - BaseLLM:Role llm: if not existed, init from role.config# print(fclass:{self.__class__.__name__}({self.name}), llm: {self._llm}, llm_config: {self._llm_config})if not self.private_llm:self.private_llm self.context.llm_with_cost_manager_from_llm_config(self.config.llm)return self.private_llmllm.setterdef llm(self, llm: BaseLLM) - None:Set llmself.private_llm llmContextMixin 通过 Pydantic 进行模型验证和数据管理在处理任意字段时提供了灵活性。 测试 ContextMixin
示例ModelX
为了演示 ContextMixin 的工作原理我们创建了一个简单的模型 ModelX继承自 ContextMixin, 验证 ModelX 能正确继承默认属性同时保留 ContextMixin 的功能。
ContextMixin 可以无缝集成到多重继承的层次结构中, ModelY 结合了 ContextMixin 和 WTFMixin继承了两者的字段和功能。
class ModelX(ContextMixin, BaseModel):a: str ab: str bclass WTFMixin(BaseModel):c: str cd: str dclass ModelY(WTFMixin, ModelX):passdef test_config_mixin_1():new_model ModelX()assert new_model.a aassert new_model.b b
test_config_mixin_1()1. 配置优先级
from metagpt.configs.llm_config import LLMConfigmock_llm_config LLMConfig(llm_typemock,api_keymock_api_key,base_urlmock_base_url,app_idmock_app_id,api_secretmock_api_secret,domainmock_domain,
)
mock_llm_config_proxy LLMConfig(llm_typemock,api_keymock_api_key,base_urlmock_base_url,proxyhttp://localhost:8080,
)def test_config_mixin_2():i Config(llmmock_llm_config)j Config(llmmock_llm_config_proxy)obj ModelX(configi)assert obj.config iassert obj.config.llm mock_llm_configobj.set_config(j)# obj already has a config, so it will not be setassert obj.config i
test_config_mixin_2()2. 多继承
def test_config_mixin_3_multi_inheritance_not_override_config():Test config mixin with multiple inheritancei Config(llmmock_llm_config)j Config(llmmock_llm_config_proxy)obj ModelY(configi)assert obj.config iassert obj.config.llm mock_llm_configobj.set_config(j)# obj already has a config, so it will not be setassert obj.config iassert obj.config.llm mock_llm_configassert obj.a aassert obj.b bassert obj.c cassert obj.d dprint(obj.__dict__.keys())print(obj.__dict__)assert private_config in obj.__dict__.keys()test_config_mixin_3_multi_inheritance_not_override_config()dict_keys([private_context, private_config, private_llm, a, b, c, d])
{private_context: None, private_config: Config(extra_fieldsNone, project_path, project_name, incFalse, reqa_file, max_auto_summarize_code0, git_reinitFalse, llmLLMConfig(extra_fieldsNone, api_keymock_api_key, api_typeLLMType.OPENAI: openai, base_urlmock_base_url, api_versionNone, modelNone, pricing_planNone, access_keyNone, secret_keyNone, session_tokenNone, endpointNone, app_idmock_app_id, api_secretmock_api_secret, domainmock_domain, max_token4096, temperature0.0, top_p1.0, top_k0, repetition_penalty1.0, stopNone, presence_penalty0.0, frequency_penalty0.0, best_ofNone, nNone, streamTrue, seedNone, logprobsNone, top_logprobsNone, timeout600, context_lengthNone, region_nameNone, proxyNone, calc_usageTrue, use_system_promptTrue), embeddingEmbeddingConfig(extra_fieldsNone, api_typeNone, api_keyNone, base_urlNone, api_versionNone, modelNone, embed_batch_sizeNone, dimensionsNone), omniparseOmniParseConfig(extra_fieldsNone, api_key, base_url), proxy, searchSearchConfig(extra_fieldsNone, api_typeSearchEngineType.DUCK_DUCK_GO: ddg, api_key, cse_id, search_funcNone, params{engine: google, google_domain: google.com, gl: us, hl: en}), browserBrowserConfig(extra_fieldsNone, engineWebBrowserEngineType.PLAYWRIGHT: playwright, browser_typechromium), mermaidMermaidConfig(extra_fieldsNone, enginenodejs, pathmmdc, puppeteer_config, pyppeteer_path/usr/bin/google-chrome-stable), s3None, redisNone, repair_llm_outputFalse, prompt_schemajson, workspaceWorkspaceConfig(extra_fieldsNone, pathWindowsPath(d:/llm/metagpt/workspace), use_uidFalse, uid), enable_longterm_memoryFalse, code_review_k_times2, agentops_api_key, metagpt_tti_url, languageEnglish, redis_keyplaceholder, iflytek_app_id, iflytek_api_secret, iflytek_api_key, azure_tts_subscription_key, azure_tts_region), private_llm: metagpt.provider.openai_api.OpenAILLM object at 0x00000128F0753910, a: a, b: b, c: c, d: d}3. 多继承重写
mock_llm_config_zhipu LLMConfig(llm_typezhipu,api_keymock_api_key.zhipu,base_urlmock_base_url,modelmock_zhipu_model,proxyhttp://localhost:8080,
)def test_config_mixin_4_multi_inheritance_override_config():Test config mixin with multiple inheritancei Config(llmmock_llm_config)j Config(llmmock_llm_config_zhipu)obj ModelY(configi)assert obj.config iassert obj.config.llm mock_llm_configobj.set_config(j, overrideTrue)# override obj.configassert obj.config jassert obj.config.llm mock_llm_config_zhipuassert obj.a aassert obj.b bassert obj.c cassert obj.d dprint(obj.__dict__.keys())assert private_config in obj.__dict__.keys()assert obj.config.llm.model mock_zhipu_model
test_config_mixin_4_multi_inheritance_override_config()dict_keys([private_context, private_config, private_llm, a, b, c, d])4. 配置优先级
from pathlib import Path
import pytest
from metagpt.actions import Action
from metagpt.config2 import Config
from metagpt.const import CONFIG_ROOT
from metagpt.environment import Environment
from metagpt.roles import Role
from metagpt.team import Teampytest.mark.asyncio
async def test_config_priority():If actions config is set, then its llm will be set, otherwise, it will use the roles llmhome_dir Path.home() / CONFIG_ROOTgpt4t Config.from_home(gpt-4-turbo.yaml)if not home_dir.exists():assert gpt4t is Nonegpt35 Config.default()gpt35.llm.model gpt35gpt4 Config.default()gpt4.llm.model gpt-4-0613a1 Action(nameSay, instructionSay your opinion with emotion and dont repeat it, configgpt4t)a2 Action(nameSay, instructionSay your opinion with emotion and dont repeat it)a3 Action(nameVote, instructionVote for the candidate, and say why you vote for him/her)# it will not work for a1 because the config is already setA Role(nameA, profileDemocratic candidate, goalWin the election, actions[a1], watch[a2], configgpt4)# it will work for a2 because the config is not setB Role(nameB, profileRepublican candidate, goalWin the election, actions[a2], watch[a1], configgpt4)# dittoC Role(nameC, profileVoter, goalVote for the candidate, actions[a3], watch[a1, a2], configgpt35)env Environment(descUS election live broadcast)Team(investment10.0, envenv, roles[A, B, C])assert a1.llm.model gpt-4-turbo if Path(home_dir / gpt-4-turbo.yaml).exists() else gpt-4-0613assert a2.llm.model gpt-4-0613assert a3.llm.model gpt35await test_config_priority()如果有任何问题欢迎在评论区提问。