ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

多智能体框架AgentScope:从消息总线到工程化实践

多智能体框架AgentScope:从消息总线到工程化实践

1. 从“玩具”到“工程”:为什么我们需要一个多智能体框架

最近在折腾AI应用,尤其是想搞点多智能体协作的东西,比如让几个大模型扮演不同角色,一起完成一个复杂的任务。一开始,我的想法很简单:不就是调几个API,写几个函数,让它们互相发消息吗?我随手写了个脚本,用OpenAI的接口,让一个“产品经理”智能体生成需求,再让一个“程序员”智能体写代码。看起来跑通了,但问题很快就来了。

当我想增加一个“测试员”智能体来审查代码时,消息传递的逻辑立刻变得混乱。谁该在什么时候收到什么消息?消息内容是什么格式?一个智能体的输出如何结构化地成为另一个智能体的输入?更头疼的是,我想记录下整个对话过程用于复盘,或者当某个智能体“胡说八道”时能快速定位和干预。我的脚本迅速膨胀成一团乱麻,调试起来像在走迷宫。

我相信很多开发者都有过类似的经历。我们用一个for循环和几个if-else,就能快速验证一个多智能体协作的想法,这很棒。但一旦你想把这个“玩具”变成一个健壮的、可维护的、可扩展的“工程化”应用时,就会遇到一系列基础设施层面的挑战。这,正是像AgentScope这样的框架要解决的问题。它不是一个束缚你创意的笼子,而是一个为你处理所有脏活累活的基础设施团队,让你能专注于智能体本身的行为逻辑和业务价值。

简单说,AgentScope的核心价值在于,它提供了一套标准化的“脚手架”和“工具箱”,专门用于构建和管理多智能体应用。它把智能体间的通信、状态管理、流程编排、可观测性这些繁琐但必需的工程问题,封装成了清晰、易用的接口。这就好比,你想盖房子,框架为你准备好了标准化的钢筋、水泥和施工流程,你不用再从烧制砖头开始。

2. AgentScope的核心架构:消息总线与智能体“公寓”

要理解AgentScope,不能只看它提供的几个Agent类,得先看清它设计的“地基”。这个地基的核心,我认为是它的消息传递模型智能体生命周期管理。我们可以把它想象成一栋专门出租给“智能体”的公寓楼。

2.1 消息总线:公寓楼里的内部电话系统

在这栋公寓楼里,智能体们(房客)不能直接砸对方的门。所有通信必须通过一个中央的“内部电话系统”——这就是消息总线(Message Bus)。在AgentScope中,这个角色主要由Message类和底层的分发机制承担。

一个Message不是一个简单的字符串。它是一个结构化的数据对象,通常包含:

  • name: 发送者标识。
  • content: 消息内容(可以是文本、字典、甚至任何Python对象)。
  • url: 可选,关联的文件或资源链接。

为什么需要结构化?举个例子,智能体A发送了一个包含代码和解释的消息。如果只是字符串,智能体B需要费力地去解析哪里是代码,哪里是注释。而通过结构化的content(比如{"code": “print(‘hello’)”, “explanation”: “这是一个示例”}),接收者就能直接获取语义明确的字段。

更重要的是,消息总线管理着消息的路由。它确保消息能准确送达目标智能体,并且可以方便地实现广播(发给所有智能体)、组播(发给特定群组)等模式。框架还处理了消息的序列化、持久化(如果你想保存对话历史)和潜在的消息队列问题,这些都是你在裸写脚本时需要自己反复造轮子的部分。

2.2 智能体(Agent):标准化的“房客”与自定义装修

AgentScope提供了一些基础“房客”模板,也就是内置的Agent类,比如:

  • UserAgent: 代表人类用户,通常用于模拟用户输入或作为交互接口。
  • DialogAgent: 一个基于大语言模型的对话智能体,它封装了与LLM(如GPT、文心一言等)的交互,包括构造Prompt、调用API、解析响应。
  • ServiceAgent: 可以调用外部工具或服务的智能体,比如执行代码、查询数据库、调用API。

这些内置智能体帮你解决了最通用的模式。但真正的力量在于“自定义装修”。你可以通过继承这些基础类,来创建具有特定技能、记忆或决策逻辑的智能体。

例如,创建一个“代码评审专家”智能体:

from agentscope.agents import DialogAgent from agentscope.message import Msg class CodeReviewAgent(DialogAgent): def __init__(self, name, model_config_name): super().__init__(name=name, model_config_name=model_config_name) # 可以在这里初始化该智能体的专属知识库或规则 self.review_rules = ["检查语法错误", "评估代码效率", "确保符合PEP8规范"] def reply(self, incoming_message: Msg) -> Msg: # 在调用父类(即LLM)的回复逻辑前,可以预处理输入 enhanced_prompt = f""" 你是一个资深代码评审专家。请根据以下规则进行评审: {self.review_rules} 需要评审的代码: {incoming_message.content} 请给出详细的评审意见,包括问题、风险和改进建议。 """ # 修改传入消息的内容,再交给父类的LLM处理 modified_msg = Msg(self.name, enhanced_prompt, role="user") return super().reply(modified_msg)

通过继承和重写reply方法,你就能轻松地给智能体注入特定的行为模式,而无需关心消息是如何收发的、LLM的token如何管理、上下文窗口如何维护——这些都由框架层处理好了。

2.3 环境与流程编排:公寓的公共空间与活动流程

智能体们住在各自的房间里,通过消息总线打电话。那它们怎么协同完成一个任务呢?比如“一起写一份项目计划书”。这就需要流程编排(Orchestration)

AgentScope提供了PipelineWorkflow等抽象来定义智能体间的协作流程。你可以把它看作是公寓的“公共活动流程表”。

一个最简单的顺序管道示例:

from agentscope.pipelines import SequentialPipeline # 假设我们已经创建了三个智能体 product_manager = DialogAgent(name="PM", ...) programmer = DialogAgent(name="Dev", ...) tester = DialogAgent(name="QA", ...) # 创建一个顺序执行的管道 pipeline = SequentialPipeline( agents=[product_manager, programmer, tester], pipeline_name="软件研发流水线" ) # 运行管道:PM生成需求 -> Dev根据需求写代码 -> QA测试代码 initial_message = Msg("user", "我们需要一个计算斐波那契数列的函数。") final_result = pipeline.run(initial_message)

在这个管道里,框架会自动将上一个智能体的输出消息,作为下一个智能体的输入消息。你还可以构建更复杂的流程,比如包含条件分支(IfElsePipeline)、循环(ForLoopPipeline),或者并行执行(ParallelPipeline)。这种声明式的编排方式,让复杂的多智能体交互逻辑变得清晰、可视且易于维护。

3. 从零搭建一个实战项目:多智能体头脑风暴会议

理论讲得再多,不如亲手搭一个。我们来实战一个经典场景:多智能体头脑风暴会议。目标是创建一个会议系统,包含一个主持人(Moderator)、若干个领域专家(如技术专家、市场专家、设计专家),让它们针对一个议题进行多轮讨论,最终由主持人汇总成一份创新方案。

3.1 第一步:环境搭建与模型配置

首先,安装AgentScope。推荐使用pip,并指定版本以获得稳定体验。

pip install agentscope

接下来是模型配置。AgentScope支持多种模型后端(OpenAI、Azure、DashScope、Ollama等)。我们需要在项目根目录创建一个config.yaml(或configs.py)来集中管理配置。这是非常重要的一步,它能将模型API密钥、基地址等敏感或易变信息从代码中分离出来。

# config.yaml model_configs: # 定义一个名为“gpt-4”的配置 gpt-4: model_type: “openai” # 指定模型类型 config_name: “gpt-4” # 配置名称,在代码中引用 model_name: “gpt-4-turbo-preview” # 具体的模型名称 api_key: “your-openai-api-key-here” # 你的API密钥 # 可选参数 max_tokens: 2000 temperature: 0.7 # 可以定义多个配置,例如备用模型或不同能力的模型 qwen-max: model_type: “dashscope” config_name: “qwen-max” model_name: “qwen-max” api_key: “your-dashscope-api-key-here”

在代码中,我们通过配置名来加载模型,而不是硬编码密钥:

import agentscope from agentscope.agents import DialogAgent # 初始化AgentScope,加载配置文件 agentscope.init(model_configs="./config.yaml") # 创建智能体时,直接引用配置名 moderator = DialogAgent(name="主持人", model_config_name="gpt-4") tech_expert = DialogAgent(name="技术专家", model_config_name="gpt-4")

关键经验:务必使用配置文件管理模型密钥!这不仅是安全最佳实践,也极大方便了后续模型的切换和对比实验。比如,你可以轻松地将“技术专家”的模型从gpt-4换成qwen-max,只需修改配置名,而无需改动智能体初始化代码。

3.2 第二步:创建定制化的智能体角色

基础DialogAgent只是个“白板”,我们需要赋予它们角色和个性。通过重写__init__reply方法来实现。

from agentscope.agents import DialogAgent from agentscope.message import Msg class ModeratorAgent(DialogAgent): """主持人智能体,负责引导会议、总结发言。""" def __init__(self, name, model_config_name, topic): super().__init__(name=name, model_config_name=model_config_name) self.topic = topic self.discussion_rounds = 0 self.summary_points = [] def reply(self, incoming_message: Msg) -> Msg: # 分析当前讨论状态 if “总结” in incoming_message.content or self.discussion_rounds >= 3: # 触发总结流程 summary_prompt = f“基于以下讨论要点:{self.summary_points},请撰写一份关于‘{self.topic}’的最终创新方案报告。” final_msg = Msg(self.name, summary_prompt, role=“user”) response = super().reply(final_msg) return Msg(self.name, f“【最终方案】\n{response.content}”, role=“assistant”) else: # 引导下一轮讨论 self.discussion_rounds += 1 guide_prompt = f“当前议题:{self.topic}。这是第{self.discussion_rounds}轮讨论。请基于之前的对话,提出一个新的、深入的见解或质疑,以推动讨论。之前的讨论要点有:{self.summary_points[-3:] if self.summary_points else ‘暂无’}” guide_msg = Msg(self.name, guide_prompt, role=“user”) return super().reply(guide_msg) def record_point(self, point): """记录讨论要点""" self.summary_points.append(point) class ExpertAgent(DialogAgent): """领域专家基类""" def __init__(self, name, model_config_name, expertise): super().__init__(name=name, model_config_name=model_config_name) self.expertise = expertise # 如“区块链技术”、“用户体验设计” def reply(self, incoming_message: Msg) -> Msg: # 在回复时,强调自己的专家身份和视角 expert_prompt = f“你是一名{self.expertise}专家。请从你的专业角度出发,对以下内容发表看法:\n\n{incoming_message.content}。你的回答应体现专业深度,并可以适当质疑或补充其他观点。” expert_msg = Msg(self.name, expert_prompt, role=“user”) response = super().reply(expert_msg) # 可以在这里简单提取观点关键词,用于主持人记录(实际项目可能需要更复杂的NLP) if “观点” in response.content or “建议” in response.content: # 这里简化处理,实际应更精细 self.moderator.record_point(f“{self.name}: {response.content[:100]}...”) return response

这里的关键是,我们通过定制reply方法,在消息到达大模型之前,为其穿上了“角色”的外衣(即修改了Prompt)。同时,ModeratorAgent内部维护了讨论状态(轮次、要点),实现了简单的状态管理。

3.3 第三步:设计会议流程与消息循环

有了智能体,我们需要设计它们如何互动。这里我们不使用高级的Pipeline,而是手动实现一个简单的循环,以便更清晰地理解消息流。

def run_brainstorming_session(topic, experts_config): """ 运行头脑风暴会议 Args: topic: 会议议题 experts_config: 专家列表,如 [('AI伦理', 'gpt-4'), ('产品设计', 'gpt-4')] """ # 1. 创建智能体 moderator = ModeratorAgent(name=“主持人”, model_config_name=“gpt-4”, topic=topic) experts = [] for expertise, model_cfg in experts_config: expert = ExpertAgent(name=f“{expertise}专家”, model_config_name=model_cfg, expertise=expertise) # 简单传递主持人引用,用于记录观点(生产环境需更优雅的设计,如通过消息) expert.moderator = moderator experts.append(expert) # 2. 初始化:主持人开场 print(f“议题:{topic}”) opening = moderator.reply(Msg(“system”, “请宣布会议开始并介绍议题。”)) print(f“[主持人] {opening.content}”) # 3. 多轮讨论循环 for round_num in range(1, 4): # 进行3轮讨论 print(f“\n——— 第{round_num}轮讨论 ———”) for expert in experts: # 专家针对主持人上一轮的话(或开场白)进行发言 expert_response = expert.reply(opening) print(f“[{expert.name}] {expert_response.content}”) # 主持人记录并准备引导下一轮 # 这里简化:将专家回复直接作为主持人的新输入 opening = Msg(expert.name, expert_response.content, role=“user”) # 4. 总结 print(f“\n——— 会议总结 ———”) # 发送一个触发总结的信号给主持人 summary_trigger = Msg(“system”, “讨论已进行三轮,请进行总结。”) final_summary = moderator.reply(summary_trigger) print(f“[主持人] {final_summary.content}”) return final_summary.content # 运行会议 if __name__ == “__main__”: final_report = run_brainstorming_session( topic=“如何设计一个负责任且用户友好的AI健康助手”, experts_config=[(“AI伦理”, “gpt-4”), (“医疗健康”, “gpt-4”), (“用户体验”, “gpt-4”), (“数据安全”, “gpt-4”)] ) # 可以将final_report保存到文件或数据库 with open(“brainstorming_report.md”, “w”, encoding=“utf-8”) as f: f.write(final_report)

这个流程清晰地展示了多智能体应用的核心循环:消息驱动。每个智能体的reply方法被触发,产生新的Message,这个Message又成为其他智能体或下一轮循环的输入。框架的价值在于,它让Message的创建、传递和处理变得规范且可追踪。

4. 深入原理:AgentScope如何管理对话状态与上下文

当我们使用DialogAgent与LLM对话时,一个核心问题是:LLM本身是无状态的。如何让智能体“记住”之前的对话?这就是对话状态(Dialog State)上下文管理(Context Management)要解决的问题。AgentScope在这方面做了精心的设计,理解它对于高效使用和调试至关重要。

4.1 记忆(Memory)模块:智能体的“记事本”

在AgentScope中,每个Agent通常都有一个memory属性。这不是指LLM的参数权重,而是指智能体与外界交互的历史记录。对于DialogAgent,其memory默认是一个DialogMemory对象,它就像一个“记事本”,按顺序记录着这个智能体说过和听过的话。

当你调用agent.reply(message)时,背后发生了以下几步:

  1. 记忆写入:将传入的incoming_message(用户或其他智能体说的话)添加到memory中。
  2. 上下文构造:框架从memory中提取最近的一些消息(考虑LLM的token限制),并按照一定的模板(如ChatML格式、OpenAI格式)组装成LLM能理解的“上下文”。
  3. LLM调用:将组装好的上下文发送给LLM API。
  4. 记忆写入与返回:将LLM返回的响应包装成Message,也添加到memory中,然后返回给调用者。
# 这是一个简化的内部逻辑示意 class DialogAgent: def reply(self, incoming_message): # 1. 记住收到的消息 self.memory.add(incoming_message) # 2. 从记忆中构建Prompt上下文 prompt_messages = self._format_messages(self.memory.get_messages()) # 3. 调用LLM llm_response = self.model.call(prompt_messages) # 4. 将响应包装成消息,并记住它 response_message = Msg(self.name, llm_response, role=“assistant”) self.memory.add(response_message) return response_message

4.2 上下文窗口与记忆管理策略

LLM有token数限制,不能把从盘古开天辟地以来的所有对话都塞进去。因此,DialogMemory需要管理策略。常见策略有:

  • 固定窗口:只保留最近N条消息。
  • Token数限制:只保留总token数小于上限的最新消息。
  • 摘要压缩:将较早的对话压缩成一段摘要。

AgentScope允许你配置这些策略。例如,在初始化DialogAgent时,你可以指定一个自定义的memory对象。

from agentscope.memory import TemporaryMemory # 创建一个临时记忆,只保留最近5轮对话 temp_memory = TemporaryMemory(store_frequency=5) agent = DialogAgent( name=“短期记忆助手”, model_config_name=“gpt-4”, memory=temp_memory # 使用自定义记忆 )

踩坑提示上下文管理是成本与效果的平衡点。保留太多历史,会浪费token(增加费用和延迟),甚至可能超出模型上下文长度导致报错。保留太少,智能体可能“健忘”,无法进行连贯的长对话。在实践中,你需要根据任务性质来调整。对于头脑风暴会议,可能需要较长的记忆来保持讨论连贯;对于一个简单的问答工具,可能只需要最近一两轮对话。

4.3 共享记忆与独立记忆

在我们的头脑风暴例子中,每个专家智能体都有自己的独立记忆。但有时候,我们需要智能体共享一部分记忆。例如,一个“团队知识库”智能体,它的记忆应该对所有其他智能体可见。

AgentScope通过灵活的memory引用可以实现这一点。你可以让多个智能体指向同一个memory对象。

from agentscope.memory import BufferMemory # 创建一个共享的记忆缓冲区 shared_team_memory = BufferMemory() # 创建两个智能体,共享同一份记忆 agent_a = DialogAgent(name=“A”, model_config_name=“gpt-4”, memory=shared_team_memory) agent_b = DialogAgent(name=“B”, model_config_name=“gpt-4”, memory=shared_team_memory) # 当A说了一句话,这句话会被存入shared_team_memory msg_from_a = agent_a.reply(Msg(“user”, “我们项目的目标是...”)) # 当B回复时,它能“看到”A刚才说的话,因为它们的记忆是共享的 msg_from_b = agent_b.reply(msg_from_a)

这种设计非常强大,可以模拟出团队共识、公共白板等协作场景。理解记忆模块的工作原理,是进行高级多智能体系统设计的基础。

5. 高级特性与生产级考量

当我们把Demo推向实际应用时,会面临更多工程挑战。AgentScope提供了一系列特性来应对这些挑战。

5.1 可观测性(Observability)与日志记录

调试多智能体系统就像调试一个分布式系统,日志至关重要。AgentScope内置了灵活的日志系统。

import agentscope import logging # 设置日志级别和格式 agentscope.init( model_configs=“./config.yaml”, # 设置项目名称,用于日志区分 project=“MultiAgent-Brainstorm”, # 配置日志 logging_level=logging.INFO, # 可以将日志保存到文件 save_dir=“./logs” ) # 在代码中,你可以使用标准的logging模块记录特定信息 logger = logging.getLogger(__name__) logger.info(“头脑风暴会议开始...”)

框架会自动记录关键事件,如消息发送/接收、模型调用开始/结束、管道步骤执行等。查看这些日志,你可以清晰地追踪到消息在智能体网络中的流动路径,以及每个环节的耗时,这对于性能分析和故障排查不可或缺。

5.2 持久化(Persistence)与状态恢复

对于长时间运行或重要的智能体会话,你可能需要将会话状态(主要是记忆)保存下来,以便后续恢复。AgentScope的memory对象通常支持序列化。

import pickle import json # 保存某个智能体的记忆到文件 def save_agent_memory(agent, filepath): memory_data = agent.memory.get_messages() # 获取原始消息列表 # 使用pickle保存(二进制,保存完整对象) with open(filepath, “wb”) as f: pickle.dump(memory_data, f) # 或者保存为JSON(可读性好,但可能丢失复杂对象信息) # with open(filepath, ‘w’, encoding=‘utf-8’) as f: # json.dump([msg.to_dict() for msg in memory_data], f, ensure_ascii=False, indent=2) # 从文件加载记忆并恢复智能体状态 def load_agent_memory(agent, filepath): with open(filepath, “rb”) as f: memory_data = pickle.load(f) agent.memory.clear() for msg_dict in memory_data: # 假设保存的是Msg对象的字典形式 agent.memory.add(Msg(**msg_dict))

在生产环境中,你可能会将会话状态存入数据库(如Redis、PostgreSQL),并为每个会话分配一个唯一的session_id。这样,即使服务重启,也能从断点继续。

5.3 错误处理与智能体“熔断”

多智能体系统中,任何一个环节出错(如LLM API调用失败、网络超时、智能体逻辑异常)都可能导致整个流程崩溃。健壮的系统必须有错误处理机制。

AgentScope的模型调用层通常已经包含了一些重试逻辑。但你需要在业务逻辑层也考虑容错。

from openai import APIError, Timeout import time class RobustDialogAgent(DialogAgent): def reply(self, incoming_message, max_retries=3): for attempt in range(max_retries): try: return super().reply(incoming_message) except (APIError, Timeout) as e: logger.warning(f“{self.name} 第{attempt+1}次调用失败: {e}”) if attempt < max_retries - 1: wait_time = 2 ** attempt # 指数退避 time.sleep(wait_time) else: # 所有重试都失败,返回一个降级响应 logger.error(f“{self.name} 所有重试均失败,返回降级响应。”) return Msg(self.name, “抱歉,我暂时无法处理您的请求,请稍后再试或联系管理员。”, role=“assistant”) except Exception as e: # 捕获其他未预期的异常 logger.error(f“{self.name} 发生未预期错误: {e}”, exc_info=True) return Msg(self.name, “系统内部出现错误。”, role=“assistant”)

此外,对于管道(Pipeline)中的智能体,你可以考虑实现“熔断”机制。如果某个智能体连续失败多次,可以暂时将其从流程中跳过或替换,防止单个故障点拖垮整个系统。

5.4 性能优化:异步与流式响应

当智能体数量增多或任务复杂时,同步顺序执行可能成为性能瓶颈。AgentScope支持异步(Async)操作,允许智能体并行执行。

import asyncio from agentscope.agents import DialogAgent from agentscope.message import Msg async def parallel_agent_task(agent, message): """异步执行单个智能体的回复任务""" response = await agent.areply(message) # 注意是 areply 异步方法 return response async def main_async(): agents = [DialogAgent(name=f“Agent{i}”, ...) for i in range(5)] initial_msg = Msg(“user”, “请从你的视角分析这个问题。”) # 并行调用所有智能体 tasks = [parallel_agent_task(agent, initial_msg) for agent in agents] responses = await asyncio.gather(*tasks) for agent, resp in zip(agents, responses): print(f“{agent.name}: {resp.content[:50]}...”) # 运行异步主函数 asyncio.run(main_async())

对于需要长时间生成内容的场景(如撰写长报告),流式响应(Streaming)可以提升用户体验。AgentScope的模型包装器通常也支持流式输出,你可以逐步获取并处理生成的token,而不是等待全部生成完毕。

6. 超越基础:构建复杂的智能体生态系统

掌握了单机和基础协作后,我们可以展望更复杂的架构。AgentScope能够支撑起一个智能体“生态系统”。

6.1 分层架构:管理者、执行者与工具智能体

在一个大型系统中,可以设计不同层级的智能体:

  • 管理者/协调者(Manager/Coordinator):高层智能体,负责分解任务、分配子任务给执行者、并汇总结果。它可能拥有更强的模型(如GPT-4)和更复杂的决策逻辑。
  • 执行者(Worker):专门负责某项具体任务的智能体,如代码生成、数据分析、文本总结。它们可能使用性价比更高的模型(如GPT-3.5-Turbo)。
  • 工具智能体(Tool Agent):封装了特定工具或API调用的智能体,如ServiceAgent。它们不一定依赖大模型,而是执行确定性的操作(运行代码、查询数据库)。

这种分层架构使得系统易于管理和扩展。管理者智能体可以通过Pipeline来编排多个执行者智能体的工作流。

6.2 动态智能体创建与资源池

在某些场景下,你可能需要根据运行时需求动态创建或销毁智能体。例如,一个客服系统中,每来一个新用户会话,就动态创建一个专属的客服智能体,会话结束后销毁以释放资源。

这需要结合工厂模式(Factory Pattern)和资源池(Pool)的概念。你可以维护一个智能体配置模板和模型连接池,当需要时快速实例化,避免每次创建都重新加载大模型等重量级资源。

6.3 与外部系统的集成

真正的生产力工具必须能与现有系统打通。AgentScope智能体可以轻松集成:

  • 数据库:通过ServiceAgent调用SQL查询或ORM。
  • API服务:智能体可以构造HTTP请求,调用内部或外部的RESTful API。
  • 消息队列:让智能体监听Kafka、RabbitMQ等消息队列,实现事件驱动的响应。
  • 前端界面:通过WebSocket或Server-Sent Events (SSE) 将智能体的流式响应推送到网页或App前端。

例如,创建一个可以查询天气的WeatherServiceAgent

import requests from agentscope.agents import ServiceAgent from agentscope.message import Msg class WeatherServiceAgent(ServiceAgent): def __init__(self, name, api_key): super().__init__(name=name) self.api_key = api_key self.base_url = “https://api.weatherapi.com/v1” def reply(self, incoming_message: Msg) -> Msg: # 解析消息内容,提取城市名(这里简化处理) city = incoming_message.content.get(“city”, “Beijing”) try: response = requests.get( f“{self.base_url}/current.json”, params={“key”: self.api_key, “q”: city} ) response.raise_for_status() data = response.json() weather_info = f“{city}当前天气:{data[‘current’][‘condition’][‘text’]},温度{data[‘current’][‘temp_c’]}°C。” return Msg(self.name, weather_info, role=“assistant”) except requests.RequestException as e: return Msg(self.name, f“获取天气信息失败:{e}”, role=“assistant”)

通过这种方式,你将大模型的推理能力与外部世界的实时数据和业务逻辑连接了起来,构建出真正有用的智能应用。

从最初手忙脚乱的脚本,到如今能够设计并实现一个结构清晰、功能健壮的多智能体系统,框架的价值在于它提供的不仅仅是代码工具,更是一种工程化的思维模式。它强迫你思考智能体的边界、消息的契约、状态的归属和流程的编排。当你开始用AgentScope的视角去设计系统时,你会发现,构建复杂的AI协作应用,不再是一个充满未知和混乱的探险,而是一个有蓝图、有工具、有章可循的建造过程。剩下的,就是充分发挥你的创意,去解决那些真正有趣的问题了。

返回列表