1. 项目概述一个“议会”式的智能体协作框架最近在探索大语言模型LLM应用架构时我遇到了一个非常有意思的开源项目gcpdev/llm-council-skill。这个名字听起来有点抽象但它的核心思想却异常清晰且强大——它试图构建一个由多个“专家”智能体组成的“议会”Council通过协作、辩论和投票的方式来解决单一智能体难以处理的复杂问题。简单来说你可以把它想象成一个由不同领域专家组成的委员会。当你提出一个复杂问题时比如“如何为一款新的智能手表制定市场推广策略”这个框架不会只依赖一个“全能”的AI来回答。相反它会将这个任务分解并分派给不同的“议员”智能体一个负责市场分析一个负责创意文案一个负责预算规划一个负责风险评估。每个议员基于自己的专长提出方案然后它们之间会进行“讨论”信息交换和“投票”决策聚合最终形成一个综合了多方智慧的、更全面、更可靠的最终答案。这个项目源自Google Cloud PlatformGCP开发者社区其设计理念直指当前AI应用开发中的一个核心痛点单一模型或智能体在应对需要多维度知识、复杂推理和权衡取舍的任务时往往力有不逮。llm-council-skill提供了一套标准化的框架让开发者能够轻松地组建、管理和扩展这样的“AI议会”将大模型的“脑力”以更结构化的方式组织起来从而产生“112”的效果。无论你是想构建一个高级的问答系统、一个复杂的决策支持工具还是一个创意生成平台这个框架都提供了一个极具潜力的新范式。2. 核心架构与设计哲学拆解2.1 “议会”隐喻下的组件化设计llm-council-skill的架构完全遵循了“议会”的隐喻其核心组件清晰对应着现实世界中的议会运作机制。理解这些组件是掌握该框架的关键。1. Skill技能/专长这是框架的基石代表每个“议员”所具备的特定能力。一个Skill本质上是一个封装好的、可执行的函数或模块它知道如何调用特定的工具、API或执行特定的计算。例如WebSearchSkill 专精于使用搜索引擎API获取最新信息。CalculatorSkill 擅长进行数学计算和单位换算。CodeInterpreterSkill 能够执行Python代码片段来分析数据或解决问题。DALLEImageGenerationSkill 专门用于根据描述生成图像。开发者可以轻松地定义自己的Skill只需实现一个简单的接口通常是包含execute方法的类。这使得框架具备了极强的可扩展性。2. Agent智能体/议员Agent是Skill的“载体”和“大脑”。每个Agent被赋予一个特定的“角色”Role和“指令”Instruction并配备了一个或多个Skill。角色定义了Agent的视角如“你是一位资深的市场分析师”指令则明确了它在议会中的任务如“你的职责是评估市场趋势和竞争对手”。当议会主席通常是用户或一个控制Agent提出问题后相关的Agent会被激活它们利用自己的角色认知、指令约束以及所拥有的Skill来生成初步的回答或建议。3. Chain处理链Chain定义了单个Agent内部的工作流程。一个典型的Chain可能包含以下步骤解析Parse 理解输入的问题或上下文。规划Plan 决定需要使用哪个或哪些Skill。执行Execute 调用选定的Skill。生成Generate 基于Skill的执行结果结合角色和指令生成格式化的响应。Chain提供了灵活性允许你为不同的Agent定制复杂或简单的工作流。4. Council议会Council是整个系统的协调中枢。它管理着所有注册的Agent并负责执行核心的“协作-决策”流程。其工作流程通常如下任务接收与分发 接收用户查询并根据预定义的规则或路由逻辑将任务分发给一个或多个相关的Agent。响应收集 收集所有被激活Agent的初步响应。评估与辩论可选 在更高级的配置中Council可以引导Agent之间进行多轮“辩论”每个Agent可以评论其他Agent的响应并据此修正自己的观点。投票与聚合 这是Council的核心功能。它使用一个“评估器”Evaluator来对各个Agent的响应进行评分或排序。评估器本身也可以是一个LLM其提示词可能是“请根据可行性、创新性和成本效益对以下方案进行评分”。最终Council根据投票结果如最高分、加权平均等合成最终答案。2.2 设计哲学超越单一模型的局限性这个框架的设计背后蕴含着对当前LLM应用深刻的洞察专精化优于通才化 与其期待一个模型精通所有事情不如让多个“小模型”或“专精化提示”各司其职。一个经过精细调校、专门用于代码生成的模型在编程任务上通常比一个通用聊天模型表现更好。Council框架鼓励这种专精化分工。过程透明与可解释性 单一模型的回答是个“黑箱”。而在议会框架中你可以看到每个“专家”的意见、它们使用的工具Skill以及最终的投票理由。这大大增加了系统的透明度和可信度对于企业级应用至关重要。动态纠错与集体智慧 单个模型可能会“一本正经地胡说八道”幻觉。在议会中如果一个Agent给出了错误信息其他拥有相关Skill如事实核查Skill的Agent可以在辩论或评估阶段指出问题从而在系统层面降低错误率。模块化与可维护性 当需要增加新能力时你无需重写整个系统只需开发一个新的Skill并将其分配给一个现有的或新的Agent即可。这种模块化设计使得系统易于迭代和维护。实操心得 在初步设计你的Council时不要追求一次性构建一个庞大的议会。从一个简单的问题开始比如“回答需要结合实时数据和计算的问题”先设计两个Agent一个SearchAgent配备WebSearchSkill和一个CalcAgent配备CalculatorSkill。让它们协作回答“特斯拉当前股价是多少如果我现在买入100股总价是多少”。这个小原型能帮你快速理解数据流和控制逻辑。3. 从零开始构建你的第一个AI议会3.1 环境准备与基础依赖安装假设我们使用Python作为开发语言首先需要搭建环境。项目通常依赖于一些核心的LLM SDK和工具库。# 创建并激活一个虚拟环境推荐 python -m venv council-env source council-env/bin/activate # Linux/macOS # council-env\Scripts\activate # Windows # 安装核心依赖 # 假设llm-council-skill可通过pip安装或其代码在本地 # 这里我们安装可能需要的通用依赖 pip install openai1.0.0 # 用于调用GPT系列模型 pip install langchain langchain-community # 提供了丰富的工具和Agent抽象可借鉴或集成 pip install google-search-results # 用于SerpAPI实现网页搜索Skill pip install python-dotenv # 管理API密钥接下来你需要准备API密钥。创建一个.env文件在你的项目根目录OPENAI_API_KEYsk-your-openai-key-here SERPAPI_API_KEYyour-serpapi-key-here # 用于搜索示例在代码中加载它们from dotenv import load_dotenv import os load_dotenv() openai_api_key os.getenv(“OPENAI_API_KEY”)3.2 定义核心Skill让议员拥有“一技之长”我们首先实现两个最基础的Skill搜索和计算。这里我们基于一个假设的BaseSkill类来构建实际框架中会有其具体的基类。import requests import json import math import re class BaseSkill: def execute(self, input_text: str) - str: “”“执行技能的核心方法由子类实现。”“” raise NotImplementedError class WebSearchSkill(BaseSkill): “”“使用SerpAPI进行网页搜索的技能。”“” def __init__(self): self.api_key os.getenv(“SERPAPI_API_KEY”) self.base_url “https://serpapi.com/search” def execute(self, query: str) - str: params { “q”: query, “api_key”: self.api_key, “engine”: “google”, “num”: 3 # 获取前3条结果 } try: response requests.get(self.base_url, paramsparams) results response.json().get(“organic_results”, []) # 提取摘要信息 summaries [f“{r.get(‘title’, ‘’)}: {r.get(‘snippet’, ‘’)}” for r in results[:2]] return “ | “.join(summaries) if summaries else “未找到相关信息。” except Exception as e: return f“搜索过程中出错{str(e)}” class CalculatorSkill(BaseSkill): “”“执行安全数学计算的技能。仅支持基本算术和math库函数。”“” def execute(self, expression: str) - str: # 安全处理移除危险字符只允许数字、运算符、括号和部分math函数 safe_pattern r“^[0-9\-*/().\s,sin|cos|tan|log|sqrt|pi|e]$” if not re.match(safe_pattern, expression): return “错误表达式中包含不安全字符。” # 替换数学常量 expression expression.replace(“pi”, str(math.pi)).replace(“e”, str(math.e)) # 非常简单的安全评估生产环境应使用更严格的库如asteval try: # 警告eval在生产中用于用户输入是危险的此处仅为演示。 # 真实场景请使用 numexpr 或 asteval 等安全计算库。 result eval(expression, {“__builtins__”: None}, {“sin”: math.sin, “cos”: math.cos, “tan”: math.tan, “log”: math.log, “sqrt”: math.sqrt}) return str(result) except Exception as e: return f“计算错误{str(e)}”重要注意事项 上面CalculatorSkill中的eval使用是极不安全的演示代码绝对不能在接收任何用户不可控输入的线上环境使用。在实际项目中必须使用像asteval这样严格限制可执行函数的库来进行安全计算。3.3 组建Agent赋予角色与使命有了Skill我们就可以创建Agent了。每个Agent需要一个大语言模型作为其“思考核心”。我们使用OpenAI的GPT模型。from openai import OpenAI class Agent: def __init__(self, name: str, role: str, instruction: str, skills: list, model: str “gpt-3.5-turbo”): self.name name self.role role # 角色描述如“金融分析师” self.instruction instruction # 具体指令如“专注于数据分析和数值计算” self.skills {s.__class__.__name__: s for s in skills} # 技能字典 self.client OpenAI(api_keyopenai_api_key) self.model model def _build_system_prompt(self) - str: “”“构建系统提示词定义Agent的身份和能力。”“” skill_list “, “.join(self.skills.keys()) return f“””你是一位{self.role}。你的职责是{self.instruction}。 你可以使用以下工具技能[{skill_list}]。 当用户的问题需要用到某个工具时请在思考后以精确的格式调用它。 调用格式skill_name:[输入内容] 例如如果需要搜索则输出WebSearchSkill:[搜索查询] 工具调用后你会收到结果请基于结果生成最终回答。 “”” def run(self, user_query: str, context: str “”) - str: “”“运行Agent处理查询。”“” messages [ {“role”: “system”, “content”: self._build_system_prompt()}, {“role”: “user”, “content”: context “\n问题” user_query} ] response self.client.chat.completions.create( modelself.model, messagesmessages, temperature0.1, # 低温度保证输出稳定 streamFalse ) initial_response response.choices[0].message.content # 检查响应中是否包含工具调用 skill_call_match re.search(r“(\w):\s*\[([^]])\]”, initial_response) if skill_call_match: skill_name, skill_input skill_call_match.groups() if skill_name in self.skills: skill_result self.skills[skill_name].execute(skill_input.strip()) # 将工具执行结果追加到对话历史让Agent进行总结 messages.append({“role”: “assistant”, “content”: initial_response}) messages.append({“role”: “user”, “content”: f“工具{skill_name}的执行结果是{skill_result}。请基于此结合你的角色给出最终回答。”}) final_response self.client.chat.completions.create( modelself.model, messagesmessages, temperature0.1 ) return final_response.choices[0].message.content # 如果不需要调用工具直接返回初始响应 return initial_response现在我们可以实例化两个Agent# 创建技能实例 search_skill WebSearchSkill() calc_skill CalculatorSkill() # 创建“研究员”Agent擅长获取信息 researcher Agent( name“Researcher”, role“信息研究员”, instruction“你负责查找、核实和提供最新的网络信息。确保信息的时效性和相关性。”, skills[search_skill], model“gpt-4” # 可以给关键Agent分配更强的模型 ) # 创建“分析师”Agent擅长处理数据 analyst Agent( name“Analyst”, role“数据分析师”, instruction“你负责处理数值计算、数据分析和逻辑推理。确保计算过程的准确无误。”, skills[calc_skill], model“gpt-3.5-turbo” )3.4 构建Council核心协调、评估与决策最简单的Council可以是一个顺序执行或投票聚合的控制器。我们实现一个基于“评分投票”的简单Council。class SimpleCouncil: def __init__(self, agents: list): self.agents agents # 评估器也是一个Agent负责给其他Agent的答案打分 self.evaluator Agent( name“Evaluator”, role“质量评估员”, instruction“你负责评估其他专家回答的质量。根据准确性、完整性和清晰度进行评分1-10分并简要说明理由。”, skills[], model“gpt-4” ) def run(self, query: str) - dict: “”“运行议会流程收集 - 评估 - 决策。”“” print(f“议会开始审议问题{query}”) # 1. 收集阶段 responses {} for agent in self.agents: print(f“- {agent.name} 正在思考...”) response agent.run(query) responses[agent.name] response print(f“ {agent.name} 的初步意见{response[:100]}...”) # 打印前100字符 # 2. 评估阶段 print(“\n进入评估与投票阶段...”) evaluations {} for agent_name, response in responses.items(): eval_prompt f“请评估以下针对‘{query}’的回答。回答内容{response}\n请给出1-10分的评分并附上一句话理由。” eval_result self.evaluator.run(eval_prompt) # 简单解析评分实际应用中需要更稳健的解析 try: score int(re.search(r“(\d)”, eval_result.split()[0]).group(1)) score max(1, min(10, score)) # 限制在1-10分 except: score 5 # 解析失败则取中位数 evaluations[agent_name] {“score”: score, “eval_text”: eval_result} print(f“ {agent_name} 得分{score}”) # 3. 决策阶段选择最高分 best_agent max(evaluations.items(), keylambda x: x[1][“score”]) final_decision responses[best_agent[0]] return { “query”: query, “responses”: responses, “evaluations”: evaluations, “final_decision”: final_decision, “winning_agent”: best_agent[0] }3.5 运行你的第一个议会让我们用这个简单的两院议会来回答一个需要复合能力的问题。if __name__ “__main__”: council SimpleCouncil(agents[researcher, analyst]) question “截至2024年5月英伟达NVIDIA的股价是多少如果比去年同期上涨了150%那么去年的股价大约是多少” result council.run(question) print(“\n” “”*50) print(“议会审议最终结果”) print(“”*50) print(f“问题{result[‘query’]}”) print(f“\n优胜议员{result[‘winning_agent’]}) print(f“\n最终决议\n{result[‘final_decision’]}”) print(“\n--- 详细过程 ---”) for agent, resp in result[‘responses’].items(): print(f“\n{agent}:”) print(f“ 回答{resp}”) print(f“ 评估{result[‘evaluations’][agent][‘eval_text’]}”)在这个例子中ResearcherAgent会尝试搜索当前股价而AnalystAgent会尝试进行计算。Council会收集两者的答案并由Evaluator评估哪个答案更综合、更准确例如Researcher提供了实时数据Analyst正确进行了反推计算前者可能得分更高最终选择评分最高的答案作为输出。4. 高级特性与生产级优化实践4.1 实现多轮辩论与迭代优化基础的议会只是收集和投票。更强大的模式是引入多轮“辩论”让Agent们可以基于他人的回答修正自己的观点。这模拟了现实会议中的讨论过程。class DebateCouncil(SimpleCouncil): def run_with_debate(self, query: str, rounds: int 2): “”“带辩论的议会流程。”“” print(f“开始带辩论的议会审议共{rounds}轮。”) agent_responses {agent.name: “” for agent in self.agents} context “” for round_num in range(rounds): print(f“\n--- 第 {round_num 1} 轮 ---”) round_responses {} for agent in self.agents: # 构建包含历史辩论上下文的提示 debate_context context if round_num 0: others_responses “\n”.join([f“- {name}: {resp}” for name, resp in agent_responses.items() if name ! agent.name]) debate_context f“\n\n其他议员上一轮的观点\n{others_responses}\n请考虑这些观点并完善或反驳你的分析。” full_query debate_context f“\n核心问题{query}” response agent.run(full_query) round_responses[agent.name] response agent_responses[agent.name] response # 更新最新响应 print(f“ {agent.name}: {response[:80]}...”) # 更新下一轮的上下文 context “本轮讨论摘要\n” “\n”.join([f“{k}: {v}” for k, v in round_responses.items()]) # 辩论结束后进行最终评估 print(“\n辩论结束进入最终评估。”) return super().run(query) # 复用父类的评估逻辑但此时Agent的响应已是经过辩论的版本在这种模式下第一轮每个Agent基于原始问题回答。第二轮每个Agent都能看到其他Agent的第一轮回答并有机会进行补充、修正或反驳。这通常能产生更深思熟虑、更全面的集体输出。4.2 技能链与复杂工作流编排有时解决一个问题需要按顺序调用多个Skill。例如“获取某公司最新财报提取营收数据计算同比增长率并生成一句话总结”。这需要在一个Agent内部进行链式调用。我们可以扩展Agent的run方法支持简单的链式调用检测或者直接使用LangChain这样的框架来构建更复杂的SequentialChain。在自定义框架中一种实现思路是让Agent的思考过程支持多次工具调用。class ChainEnabledAgent(Agent): def run_with_chain(self, user_query: str) - str: “”“支持多步工具调用的Agent。”“” max_steps 5 messages [ {“role”: “system”, “content”: self._build_system_prompt() “ 你可以连续使用多个工具。一次只调用一个工具我会把结果返回给你然后你决定下一步。”}, {“role”: “user”, “content”: user_query} ] for step in range(max_steps): response self.client.chat.completions.create(modelself.model, messagesmessages, temperature0.1) assistant_msg response.choices[0].message.content messages.append({“role”: “assistant”, “content”: assistant_msg}) # 检查是否还有工具调用 skill_call_match re.search(r“(\w):\s*\[([^]])\]”, assistant_msg) if not skill_call_match: # 没有更多工具调用返回最终结果 return assistant_msg skill_name, skill_input skill_call_match.groups() if skill_name in self.skills: skill_result self.skills[skill_name].execute(skill_input.strip()) messages.append({“role”: “user”, “content”: f“工具{skill_name}返回{skill_result}。请继续。”}) else: messages.append({“role”: “user”, “content”: f“未知工具{skill_name}。请检查或继续你的回答。”}) return “达到最大思考步数流程终止。” messages[-1][“content”]4.3 性能、成本与可靠性优化在生产环境中部署Council框架必须考虑以下实际问题1. 异步并行执行上述示例是顺序调用Agent效率低下。在实际中应使用异步编程如asyncio来并行执行所有Agent的推理过程大幅降低总延迟。import asyncio async def run_agent_async(agent, query): # 假设Agent的run方法支持异步或可以在线程池中运行 loop asyncio.get_event_loop() return await loop.run_in_executor(None, agent.run, query) async def collect_responses_parallel(agents, query): tasks [run_agent_async(agent, query) for agent in agents] responses await asyncio.gather(*tasks, return_exceptionsTrue) # 处理异常 return {agent.name: resp for agent, resp in zip(agents, responses) if not isinstance(resp, Exception)}2. 成本控制Token消耗议会模式会调用多次LLM每个Agent一次评估器可能多次Token消耗是单一聊天的数倍。优化策略包括设置响应长度限制 在调用API时明确设置max_tokens。使用混合模型 对不那么关键的Agent如某些技能执行器使用更便宜、更快的模型如gpt-3.5-turbo对核心的“思考者”和“评估器”使用更强大的模型如gpt-4。缓存机制 对常见、结果不变或变化缓慢的查询如“计算圆周率前100位”的结果进行缓存。精简提示词 优化Agent的system_prompt和instruction去除冗余描述。3. 错误处理与鲁棒性技能调用容错 每个Skill的execute方法应有完善的异常捕获返回明确的错误信息而不是导致整个流程崩溃。Agent响应解析 对Agent输出的工具调用格式进行健壮性解析使用更正式的结构如JSON而非正则表达式。评估器降级策略 如果评估器本身调用失败应有备用决策方案如随机选择、根据Agent置信度选择或使用简单的规则如选择第一个成功的响应。4. 评估器的设计评估器是议会质量的“守门员”。一个简单的LLM评估可能不稳定。可以考虑多维度评估 设计多个评估器分别评估“事实准确性”、“创造性”、“可行性”等再进行加权汇总。基于规则的过滤 在LLM评估前先用规则过滤掉明显无效的响应如包含“我不知道”或完全离题。人类反馈循环 在关键场景将难以裁决的响应或低置信度的最终答案提交给人工审核。5. 典型应用场景与扩展思路5.1 场景一复杂研究与报告生成问题 “分析一下太阳能汽车在未来五年内进入主流家用车市场所面临的主要挑战和机遇。”议会配置MarketAnalystAgent 配备WebSearchSkill和DataAnalysisSkill负责市场规模、竞争格局。TechResearcherAgent 配备AcademicSearchSkill连接学术数据库负责技术瓶颈、研发趋势。PolicyExpertAgent 配备WebSearchSkill聚焦政府网站负责政策、法规、补贴分析。RiskEvaluatorAgent 配备CalculatorSkill用于成本效益模拟负责风险评估。SynthesizerAgent主席/评估器 不配备特定技能但使用最强模型如GPT-4负责汇总所有报告评估一致性并生成结构化的最终报告挑战1,2,3...机遇A,B,C...。5.2 场景二创意生成与内容评审问题 “为一款主打‘夜间修复’的护肤精华构思5个社交媒体短视频创意脚本。”议会配置CreativeWriterAgent 角色是“资深美妆文案”擅长生成生动、感性的描述。VisualArtistAgent 角色是“短视频导演”擅长构思画面、运镜和节奏。ScientistAgent 角色是“皮肤科专家”确保创意中提到的成分、功效表述科学、准确。TrendAnalystAgent 配备WebSearchSkill搜索社交平台热点确保创意贴合当前趋势。EditorAgent评估器 负责对所有创意脚本进行打分和排序给出修改建议并选出综合评分最高的3个。5.3 场景三代码审查与系统设计问题 “审查这段Python数据处理代码指出潜在的性能瓶颈和安全风险并提出优化建议。”议会配置CodeReviewerAgent 配备StaticAnalysisSkill可集成类似Bandit、Pylint的工具检查代码风格和常见安全漏洞。PerformanceExpertAgent 角色是“性能优化工程师”分析算法复杂度识别可能的低效操作如循环内的重复计算。DomainExpertAgent 如果代码涉及特定领域如数据库操作该Agent负责检查SQL注入风险、连接池使用等。SeniorArchitectAgent评估器 综合所有意见权衡利弊给出优先级最高的修改建议列表。5.4 扩展思路让议会更智能动态议员招募 不是固定配置Agent而是根据问题的类型从一个“技能池”中动态组合出最合适的议会成员。学习与进化 记录每次议会的决策过程和最终结果尤其是人工反馈用于微调评估器的偏好或优化各个Agent的提示词Role和Instruction。分层议会 对于极其复杂的问题可以建立“上下议院”。下议院由多个专项小组子议会组成分别处理子问题上议院则由各小组的代表组成负责综合决策。与外部系统集成 将Council框架作为“AI中间件”集成到现有工作流中。例如接收来自客服系统的问题工单议会处理后将结构化建议返回给客服人员或自动生成回复。6. 常见问题、调试技巧与避坑指南6.1 Agent输出格式不稳定无法正确解析工具调用问题 Agent有时会输出“我认为应该使用搜索 [查询]”有时又会输出“用这个工具WebSearchSkill: [查询]”导致正则表达式解析失败。解决方案强化提示词约束 在system_prompt中非常严格地规定输出格式。使用示例Few-Shot效果显著。你必须严格按照以下格式调用工具 工具调用技能名称:[输入内容] 例如WebSearchSkill:[特斯拉最新车型价格] 除了工具调用行不要输出其他任何内容。使用结构化输出 要求LLM以JSON格式输出。在支持JSON模式的API如OpenAI的response_format{ “type”: “json_object” }中这非常可靠。{ “thought”: “用户需要最新信息我应该先搜索。”, “action”: “call_tool”, “tool_name”: “WebSearchSkill”, “tool_input”: “特斯拉最新车型价格” }后处理容错 如果解析失败让Agent进入一个“修复”循环提示它“你刚才的输出格式有误请严格按照指定格式重新输出”。6.2 议会决策质量低下评估器“瞎投票”问题 评估器无法区分答案的细微差别或者总是给某个特定角色如语气更肯定的Agent高分。解决方案细化评估标准 给评估器更具体、可操作的标准。不要只说“评估质量”而是说“请从以下维度评分每项1-5分1. 是否直接回答问题2. 提供的数据/事实是否准确如涉及3. 逻辑是否清晰4. 建议是否具有可操作性。最后给出总分和简要评语。”分步评估 先让评估器判断“哪个答案的事实准确性最高”再判断“哪个答案的解决方案最可行”最后综合。这比一次性评估多个维度更可靠。引入多个评估器并投票 创建2-3个不同角色的评估器如“严谨的科学家”、“务实的工程师”、“挑剔的用户”让它们分别打分然后取平均分或进行再投票。人工校准 在初期收集一批问题的议会输出和人工评分用这些数据来微调评估器Agent的提示词使其偏好与人类对齐。6.3 技能执行失败或超时导致流程中断问题WebSearchSkill因为网络问题返回错误整个议会流程卡住或返回无用信息。解决方案完善的技能异常处理 每个Skill的execute方法必须返回一个包含状态码和信息的结构化对象而不是纯字符串。class SkillResult: def __init__(self, success: bool, data: Any, error_msg: str “”): self.success success self.data data self.error_msg error_msg设置超时和重试 对于网络请求类技能使用requests的超时参数并实现简单的重试逻辑如最多3次。Council流程容错 在Council收集响应时如果某个Agent因技能失败返回了错误结果可以将其标记为“无效”不纳入后续评估或者给它一个最低分。备用技能 为关键功能提供备用技能。例如如果主要新闻API失败可以回退到另一个备用API甚至回退到从预加载的知识库中检索。6.4 系统延迟高响应速度慢问题 议会中有5个Agent每个都需要2-3秒响应加上评估总响应时间超过15秒用户体验差。优化策略并行化 如前所述使用asyncio并行运行所有Agent是必须的。流式输出Streaming 对于最终答案的生成如果使用LLM可以采用流式输出让用户先看到一部分内容。缓存 对以下内容进行缓存技能结果 如搜索“今日天气”结果在短时间内是相同的。Agent响应 对相同或高度相似的问题可以直接返回缓存的结果。可以使用向量数据库存储问题和响应进行相似度匹配。“懒加载”评估 不要等所有Agent都完成再评估。可以设置一个超时时间只评估在时间内返回的响应超时的视为放弃投票。6.5 提示词工程Prompt Engineering的挑战问题 Agent的表现严重依赖其role和instruction的撰写调整起来费时费力。管理技巧模板化与版本控制 将每个Agent的提示词保存在单独的配置文件如YAML或数据库中并做版本控制。方便进行A/B测试。researcher_agent: role: “信息研究员” instruction: | 你负责查找、核实和提供最新的网络信息。确保信息的时效性和相关性。 你的回答必须基于你搜索到的可靠信息并注明信息可能的时间范围。 如果信息不确定或存在冲突请明确指出。 few_shot_examples: - user: “苹果公司最新财报发布时间是什么时候” assistant: “WebSearchSkill:[苹果公司 最新 财报 发布日期]” temperature: 0.1自动化测试与评估 构建一个测试集QA pairs每次修改提示词后自动运行测试查看关键指标如工具调用准确率、答案相关性的变化。使用更高级的提示技术 如“思维链”Chain-of-Thought提示强制Agent在输出答案前先输出推理过程这不仅能提高答案质量也便于调试。从简单的技能封装到复杂的多智能体协作llm-council-skill所代表的框架为我们打开了一扇新的大门。它不再将LLM视为一个万能的问答机而是将其视为可以组织、管理和协调的“智力单元”。在实际开发中你可能会从LangChain、AutoGen等其他成熟框架中汲取更多灵感但核心的“议会”思想是相通的通过分工、协作与制衡构建出更可靠、更强大、更透明的AI系统。