[docs]def__init__(self,template_path:str,api_key:str=None,base_url:str=None):super().__init__(api_key=api_keyoros.getenv('OPENAI_API_KEY'),base_url=base_urloros.getenv('OPENAI_BASE_URL'),)"""初始化模板LLM客户端 """assertop.exists(template_path),f'Template file does not exist: {template_path}'asserttemplate_path.endswith('.py'),'Template file must be a Python file (.py)'self._load_template(template_path)self.template_path=template_pathmsg.text(f'Template loaded from \n{template_path}')
def_load_template(self,template_path:str):""" 加载prompt模板文件并解析其中的模板变量 Parameters ---------- template_path : str 模板文件的路径(.py文件) """ifnotop.exists(template_path):raiseFileNotFoundError(f'Template file not found: {template_path}',)spec=importlib.util.spec_from_file_location('template_module',template_path,)template_module=importlib.util.module_from_spec(spec)try:spec.loader.exec_module(template_module)exceptExceptionase:raiseImportError(f'Failed to load template module: {e}')ifnothasattr(template_module,'prompt_template'):raiseAttributeError(f"Template module must define 'prompt_template' attribute: \n{template_path}",)ifnothasattr(template_module,'conditioned_frame'):raiseAttributeError(f"Template module must define 'conditioned_frame' attribute: \n{template_path}",)self.prompt_template=getattr(template_module,'prompt_template')self.conditioned_frame=getattr(template_module,'conditioned_frame')self.template_obj=Template(template_module.conditioned_frame)variables=re.findall(r'\$(\w+)',self.conditioned_frame)variables=list(set(variables))# 去重ifnotvariables:raiseValueError(f'No variables found in conditioned_frame: \n{self.conditioned_frame}',)self.variables=variablesdef_fill(self,**kwargs):""" 使用提供的参数替换模板中的变量 Parameters ---------- **kwargs 要替换的模板变量 Returns ------- str 替换后的文本 """# 检查输入的kwargs是否和variables匹配missing_vars=set(self.variables)-set(kwargs.keys())ifmissing_vars:raiseValueError(f'Missing required variables: {missing_vars}')extra_vars=set(kwargs.keys())-set(self.variables)ifextra_vars:raiseValueError(f'Unexpected variables provided: {extra_vars}')prompt=self.prompt_template.copy()prompt[-1]['content']=self.template_obj.substitute(**kwargs)returnprompt
[docs]defcall(self,**kwargs):""" 调用LLM,生成响应 Returns ------- str LLM的响应内容 """ifnotself.prompt_template:raiseValueError('Prompt template is not defined.')template_vars={k:vfork,vinkwargs.items()ifkinself.variables}messages=self._fill(**template_vars)non_template_kwargs={k:vfork,vinkwargs.items()ifknotinself.variables}response=super().call(messages=messages,**non_template_kwargs)returnresponse
def_repr_html_(self):""" 返回HTML格式的表示,以DataFrame形式显示模板信息 """data={'Name':[op.basename(self.template_path)],'Variables to fill':[', '.join(self.variables)],}df=pd.DataFrame(data)df.index=['Template Info']returndf.T._repr_html_()