gemini 2.0 flash groq.t remove chatgpt? notes on how the logistic for router, aggregator, and consensus layer works ->指预期返回类型 main: 初始化setting.py里面setting类里面的open_router_api_key以及open_router_base_url CORSMiddleware: cross origin resource sharing指一个网页调用另外一个网页的api的 控制协议; credentials指跨境访问时可以允许哪些凭证,比如cookie(在请求之间允许的信息) ;methods指post, get等方法,这里是全部允许;headers是HTTP头部信息 structlog用于日志记录 api/ChatRouter settings utils/load_json setting.py: Message类有role和content base_router.py: request是处理http请求的工具,request.session是创立了一个实体,维持某些对话格式 rstrip是为了把/去掉避免后面拼接endpoint出错 CompletionRequest类 适用于一次对话情景,只有一个prompt ChatRquest类 适用于多次对话以后的返回,list[Message]是一个由多个Message组成的列表,可以让LLM熟悉 较长的上文情景 Base_router类 init 里面setting类里面的open_router_api_key以及open_router_base_url self.headers(headers是一个字典)用于表示希望接受怎样的返回,基础为application/json,表示希望接受json返回 如果有给定的api_key,那么就在headers里面添加一个Authorization: Bearer {self.api_key} #url以及headers是request库里面的session实体里面需要有的参数 header在这里用于表明期望的返回结果。但也可以有认证端信息,客户信息, 以及缓存信息等 get 向api发送请求然后返回一个字典里面的json结构 拼接base_url和endpoint得到完整的链接 .json()是request里面的方法 #param以及json也是session实体里面有的参数,param会被自动拼接到url后面 json会被放在请求的body里面,不会被拼接在url后面,会自动设置header application/json post 发送大体量的json文件,理解为传输prompt AsyncbaseRouter类 多了一个await然后在设定AsyncClient的时候就声明了timeout量,async在于可以通过 await实现等待其他函数,不阻塞其他函数的执行 close()调用了aclose关掉了这个AsyncClient的实体,关闭之后不能重新使用这个实体进行 请求,需要重新创建 openrouter.py: OpenRouterProvider类 get_availables_model 设定endpoint为/models,返回一个字典,每一个key是模型名,value是模型的描述 json文件的格式,里面可以存放json,字典,数组等 get_model_endpoints 一个模型可能有应对各个不同用途的接口 AsyncOpenRouterProvider 是异步函数版本的send_compoletion和send_chat_completion api/chat.py: pydantic定义数据模型,利用python的定义注解(冒号后面的类型定义)来定义数据结构 Field是额外的限制条件 Chat Message类: (联系了llm的api, consensus learning, 以及fast api本身) system_message和user_message都由Field定义 ChatRouter类 setup里面包括唯一的post接口: self._router.post("/") message要符合ChatMessage类型 定义一个initial_conversation = list[Message]里面每个元素都是Message 使用run_consensus从llm获得返回值(params有provider, consensus_config, initial_conversation) router(self)返回router本身 consensus/consensus.py: run_consens函数 调用send_round进行initial round, 获得第一个aggregated_response 然后每次依据initial conversation以及aggregated_response进行interation 返回string build_improvement_conversation函数 主要作用于conversation conversation是initial_conversation的shallow copy 创立一个包含consensus.config里面aggregated_response的conversation 同时有包含了现有的aggregated_response _get_response_for_model函数 返回一个tuple,如果没有aggregated_responnse, initial_conversation加入payload,如果有使用build_improvement_conversation 其作用主要是每次更新新的aggregated_response 然后parse_chat_response(response) tuple第一个字符串是model.model_id, text是parse之后的text send_round函数(返回字典) ayncio.gather同时处理多个任务 tasks是一个由get_respponnse_for_model的call构成的list, 使用gather,里面 的星号在执行这些函数,获得了一个字典返回值 key是tuple里面的model.model_id, value是text consensus/aggregator.py: _concatenate_aggregator函数(param是responses) 生成model:text并且每对key和value之间有换行 centralized_llm_aggregator函数 params里面的aggregated_response是send_round返回的字典 把aggregator_config.context这个iterable里面的每一个元素放到message list里面 在message里面添加被_concatenate_aggregate转换为多行string的字典 message里面加入aggregator_config.prompt里面的每个元素 从api获得的json格式的response里面显然有多个choices,选取第一个choices选取message 的value的content,这里是嵌套的字典结构 async_centralized_llm_aggregator聚合多个模型的生成结果 settings.py: create_path函数 _file_是的路径settings的路径,path把其转换为path类型,获得其所在文件夹的绝对路径 再到上一层目录,那么就是src Message类 有role和content ModelConfig类 有model_id, max_tokens, temperature AggregatorConfig类 model, approach(centralized, vote等选择choices的方式), context和prompt两者都是list[Message] ConsensusConfig类 aggregated_propmt_type属于user assistant或者system中的一种 从一个json文件中获取models(非aggregator)以及aggregator的参数 返回一个cls作为新的ConsensusConfig实体 Settings类 cors_origins,允许所有的类访问 model_config用于pydantic数据类型配置,使用utf8解码之类 model_dump把setting转换为通用的字典类 / prompt logistic initial_conversation = [ {"role": "system", "content": message.system_message}, {"role": "user", "content": message.user_message}, ] answer = run_consensus( self.provider, self.consensus_config, initial_conversation, ) self.consensus_config: (from_json) models: list[ModelConfig] aggregator_config: AggregatorConfig improvement_prompt: str () iterations: int aggregated_prompt_type: Literal["user", "assistant", "system"] aggregator_config = AggregatorConfig( model=aggregator_model, approach=aggr_data.get("approach", ""), (empty right now) context=aggr_data.get("aggregator_context", []), prompt=aggr_data.get("aggregator_prompt", []), ) centralized_llm_aggregator messages [aggregator_config.context message: role: system, content: aggregated_responses exist as str with change line ] async_centralized_lln_aggregator messages [aggregator_config.context message:role: system, content: aggregated_responses exist as dictionary aggregator_config.prompt] judge llm gets all the different responses from each llm and came back with a aggregated_response every iteration, different responses is from aggregated_response and initial conversation(updated version) initial_conversation role: system, content: consenses: aggregated_response improvement prompt different responses got send to judge and came back with aggregated_response and continues context is content when role is system 1. figure out which model is the best aggregator 2. optimize the prompt 3.turn llm as a judge, determine whether the following content is wrong, if wrong, generate the context again