1. 项目概述:从“单打独斗”到“团队协作”的智能体范式演进
最近在折腾一个挺有意思的东西,叫Spec Kit Agents。这名字听起来有点拗口,但内核其实很清晰:它是一种基于规范驱动开发理念构建的、能够协同工作的智能体工作流框架。简单来说,它试图解决当前AI应用开发中的一个核心痛点——如何让多个大语言模型智能体(Multi-Agent)不再是各自为战的“孤岛”,而是能像一个训练有素的团队一样,基于统一的上下文(Context)和明确的规范(Specification)来高效、可靠地完成复杂任务。
如果你尝试过用单个ChatGPT或Claude去处理一个涉及多步骤、多领域知识的复杂问题,比如从一份模糊的产品需求文档开始,最终生成一个可运行的后端API代码、前端界面和部署脚本,你大概率会感到力不从心。模型可能会“遗忘”之前的对话细节,或者在长链条推理中偏离最初的目标。这就是“单智能体”的局限性。而Multi-Agent系统通过引入多个具备不同角色和能力的智能体进行分工协作,理论上能更好地应对这类问题。但新的挑战随之而来:如何协调它们?如何确保它们对任务的理解一致?如何管理它们之间交互产生的庞大、杂乱的上下文信息?
Spec Kit Agents给出的答案就是“Context-Grounded”和“Spec-Driven”。它强调工作流中的每一个智能体,其行动和决策都必须“扎根”于一个共享的、结构化的上下文环境中,并且严格遵循预先定义或动态生成的规范(Spec)。这不仅仅是让几个AI聊天机器人互相@一下那么简单,而是一套旨在提升智能体系统确定性、可观测性和可维护性的工程化框架。对于开发者而言,这意味着你可以像编写API接口文档一样,去“编程”你的智能体团队,明确它们的职责、输入输出格式以及协作协议,从而构建出更稳定、更易调试的AI原生应用。
2. 核心理念拆解:规范、上下文与智能体工作流的三角关系
要理解Spec Kit Agents,必须吃透它名字里的三个关键词:Spec(规范)、Context(上下文)和Agentic Workflows(智能体工作流)。这三者构成了一个稳固的三角支撑关系,缺一不可。
2.1 Spec(规范):智能体团队的“宪法”与“API文档”
在传统软件开发中,我们通过编写详细的接口文档(API Spec)来约定不同模块如何通信。Spec Kit Agents将这一思想引入了智能体协作领域。这里的“规范”远不止是自然语言的任务描述,它是一套机器可读、可执行的指令集合,定义了工作流中每个环节的“游戏规则”。
规范的核心要素通常包括:
- 角色定义:明确每个智能体是谁,它的核心职责是什么。例如,“架构师”智能体负责技术选型,“代码生成器”智能体负责根据设计编写代码,“测试员”智能体负责编写单元测试。
- 输入/输出格式:严格规定智能体接收和传递信息的结构。这通常是JSON Schema或类似的结构化描述。例如,要求“需求分析”智能体的输出必须是一个包含
user_stories(用户故事)、acceptance_criteria(验收标准)和non_functional_requirements(非功能性需求)字段的JSON对象。 - 行动约束与边界:规定智能体能做什么、不能做什么。例如,规定“代码生成”智能体只能使用Python语言和FastAPI框架,不得引入未经许可的外部库。
- 成功标准与验证逻辑:如何判断一个智能体的任务完成了?这可能包括自动化的检查点,比如生成的代码是否能通过语法检查,输出的设计文档是否包含了所有必填字段。
注意:规范的制定并非一劳永逸。一个高级的Spec Kit Agents框架会支持“动态规范”,即工作流中的某个智能体(如“规范生成器”)可以根据上游的上下文,动态地为下游智能体生成或调整规范,这使得工作流具备了极强的适应性。
2.2 Context(上下文):共享的、版本化的“团队记忆”
在Multi-Agent系统中,上下文管理是最大的挑战之一。如果每个智能体都只拥有对话历史的片段,或者上下文以非结构化的长文本形式传递,很快就会导致信息混乱、遗忘和冲突。
Spec Kit Agents倡导的“Context-Grounded”是指:
- 结构化上下文:工作流中的所有中间状态、决策记录、智能体间的消息,都以结构化的方式(如属性图、知识图谱或特定的数据结构)存储在一个共享的“上下文环境”中。这不像普通的聊天记录,而更像一个项目管理的看板(Kanban)或数据库。
- 精准的上下文路由:每个智能体在执行时,并非获得全部历史信息,而是根据其角色和当前任务,从共享上下文中精准检索出最相关的片段。这避免了无关信息的干扰,也解决了大模型有限的上下文窗口问题。
- 上下文的版本与溯源:任何对上下文的修改都有记录。你可以清晰地追溯:最终生成的代码,是基于哪一版的需求分析?架构设计又是在哪个环节被修订的?这对于调试和审计至关重要。
一个生活化的类比:想象一个外科手术团队。主刀医生(智能体A)、麻醉师(智能体B)、护士(智能体C)共享同一份结构化的患者病历(结构化上下文),并遵循严格的手术规程(规范)。他们之间不需要重复询问患者过敏史(避免信息冗余),每个人只关注与自己职责相关的生命体征数据(精准上下文路由),并且所有操作都被手术记录仪记下(版本与溯源)。Spec Kit Agents要打造的就是这样一个高效、专业的AI团队协作环境。
2.3 Agentic Workflows(智能体工作流):可编排、可观测的执行引擎
有了规范和上下文,就需要一个引擎来驱动整个协作流程。这就是工作流编排器(Orchestrator)的角色。它负责:
- 调度与执行:按照预定义的或动态生成的流程图,依次或并行地激活相应的智能体。
- 上下文管理:维护和更新共享上下文,为每个被调用的智能体准备输入。
- 规范注入与验证:在调用智能体前,将对应的规范与相关上下文一起作为提示词(Prompt)的一部分输入;在智能体返回结果后,根据规范中的验证逻辑进行检查。
- 异常处理与重试:当某个智能体任务失败或输出不符合规范时,编排器能根据策略决定重试、转交人工或触发备用流程。
这种工作流模式,使得复杂的AI应用从“一次性的魔法咒语”变成了“可重复、可调试的自动化流水线”。这也是SDD(规范驱动开发)思想在AI工程化中的具体实践:先定义清晰的接口和契约(Spec),再实现具体的执行单元(Agent),最后通过编排器将它们组装成应用(Workflow)。
3. 核心架构与组件深度解析
一个典型的Spec Kit Agents框架会包含以下几个核心层,理解它们是如何协同工作的,是进行实战开发的基础。
3.1 规范层(Specification Layer)
这是整个系统的设计蓝图。在这一层,开发者需要定义两样东西:
- 智能体规格(Agent Spec):描述单个智能体的能力契约。通常是一个YAML或JSON文件。
# 示例:一个“API设计器”智能体的规格 name: api_designer description: “根据产品需求,设计RESTful API接口规范。” capabilities: - input_processing: “解析用户故事和验收标准” - output_generation: “生成OpenAPI 3.0规范的YAML文档” input_schema: type: object required: [user_stories, domain_model] properties: user_stories: {type: array} domain_model: {type: object} output_schema: type: object required: [openapi_spec] properties: openapi_spec: {type: string, format: yaml} design_rationale: {type: string} constraints: - “必须遵循RESTful设计原则” - “每个端点必须包含清晰的请求/响应示例” - 工作流规格(Workflow Spec):描述智能体之间的协作关系。这可以是一个有向无环图(DAG)。
# 示例:一个简单的“需求到API代码”工作流 workflow: name: requirement_to_api agents: - spec: “@/specs/requirement_analyzer.yaml” id: analyzer - spec: “@/specs/api_designer.yaml” id: designer - spec: “@/specs/code_generator.yaml” id: coder steps: - name: analyze agent: analyzer input: “{{initial_prompt}}” # 从初始输入获取 - name: design agent: designer input: “{{analyzer.output}}” # 依赖上一步输出 - name: generate agent: coder input: “{{designer.output}}”
实操心得:在定义output_schema时,务必尽可能严格和详细。一个模糊的schema(如output: string)会导致下游智能体解析困难。好的做法是,自己先手动模拟几次该智能体“应该”输出的理想格式,然后反向提炼出schema。这步工作越细致,后续工作流的稳定性越高。
3.2 上下文管理层(Context Management Layer)
这是系统的“中央数据库”。其设计直接决定了工作流的性能和智能体的“记忆力”。常见的实现模式有:
- 全局状态存储:一个所有智能体都能读写(受权限控制)的键值存储或文档数据库。简单,但容易产生冲突。
- 黑板模式(Blackboard):共享的、结构化的数据空间。智能体作为“知识源”向黑板上发布信息,其他智能体订阅感兴趣的部分。Spec Kit Agents更倾向于这种模式,因为它天然支持解耦和事件驱动。
- 向量数据库加持:对于需要基于语义进行上下文检索的场景(例如,“从所有历史讨论中找出关于‘用户认证’的相关决策”),可以将上下文的文本片段向量化存储。当智能体需要背景信息时,编排器通过向量相似度搜索,为其动态组装最相关的上下文片段。
一个关键设计选择是上下文的“切片”与“摘要”。不可能也无必要将整个项目历史全量喂给每个智能体。因此,上下文管理层需要提供工具:
- 切片:根据智能体角色和任务类型,自动从全局上下文中提取相关片段(如“仅提供最近三次关于数据库设计的讨论记录”)。
- 摘要:对于冗长的上下文(如一篇长文档),可以先由专门的“摘要智能体”生成摘要,再将摘要注入下游任务,以节省Token并聚焦重点。
3.3 智能体运行时层(Agent Runtime Layer)
这一层负责具体执行智能体。一个智能体在运行时,其生命周期大致如下:
- 提示词组装:编排器将三部分内容组合成最终的提示词(Prompt):
- 系统指令:来自其
Agent Spec中的角色、约束描述。 - 任务指令:当前步骤的具体任务描述。
- 相关上下文:从上下文管理层获取的、经过切片/摘要的精准信息。
- 系统指令:来自其
- 调用大模型:将组装好的提示词发送给底层的大语言模型(如GPT-4、Claude 3或本地部署的模型)。这里就涉及到异构LLM服务的问题。不同的智能体任务可能适合不同的模型(例如,创意任务用Claude,严谨代码用GPT-4,简单分类用低成本模型)。框架需要能统一管理不同模型的API,并处理各自的速率限制、计价方式等,这正是类似“Chimera”或“actor-attention-critic”等研究中关注的多智能体服务调度与性能优化问题。
- 输出解析与验证:收到模型回复后,首先尝试按照
output_schema进行解析(如解析JSON)。如果解析失败,可能触发自动重试或降级处理(如请求模型重新生成)。解析成功后,根据constraints进行业务逻辑验证。 - 结果提交:将验证通过的输出,按照预定格式提交到上下文管理层,更新共享状态,并通知工作流编排器进入下一步。
注意事项:智能体的“稳定性”是工程化的关键。除了重试机制,还应考虑为关键智能体设置“备用模型”(fallback model)。例如,主要使用GPT-4,当达到速率限制或发生错误时,自动切换到Claude 3 Haiku。这需要运行时层有良好的容错和降级策略。
3.4 编排与观测层(Orchestration & Observability Layer)
这是整个工作流的大脑和仪表盘。一个成熟的编排器应具备:
- 可视化编排界面:允许开发者通过拖拽方式设计工作流,定义智能体节点和依赖关系。
- 执行引擎:支持顺序、并行、分支(if-else)、循环(for-loop)等控制流。
- 观测与调试工具:这是SDD实战中提效的关键。你需要能实时看到:
- 工作流执行到了哪一步?
- 每个智能体接收到的具体提示词是什么?(提示词溯源)
- 每个智能体的原始输出和解析后的结果是什么?
- 上下文状态是如何随时间变化的?
- 哪一步耗时最长?哪个智能体调用成本最高?
- 版本管理:对工作流规格、智能体规格进行版本控制,并能将执行记录与特定版本关联,便于回滚和对比。
4. 实战构建:从零设计一个“技术博客生成”工作流
让我们通过一个具体的例子,将上述理论付诸实践。我们的目标是构建一个能自动生成一篇关于“如何用Python实现二叉树遍历”技术博客的智能体工作流。
4.1 第一步:需求分析与规范定义
首先,我们拆解任务。一篇好的技术博客通常包含:吸引人的标题、清晰的摘要、目录、理论知识讲解、代码示例、复杂度分析、总结等部分。我们可以为每个部分设计一个专门的智能体。
定义智能体规格(示例:code_example_agent.yaml):
name: code_example_generator description: “根据算法主题和理论讲解,生成清晰、可运行、带有注释的Python代码示例。” model: gpt-4-turbo # 指定使用模型,代码生成对准确性要求高 input_schema: type: object required: [algorithm_topic, theoretical_explanation] properties: algorithm_topic: type: string description: “算法主题,如‘二叉树前序遍历’” theoretical_explanation: type: string description: “上一步‘理论讲解智能体’生成的讲解文本” language: type: string enum: [python] default: python output_schema: type: object required: [code_snippet, explanation, time_complexity, space_complexity] properties: code_snippet: type: string description: “完整的、可运行的代码块,包含类定义和测试用例” explanation: type: string description: “对代码关键部分的逐行解释” time_complexity: type: string pattern: “^O\\(.+\\)$” # 验证输出格式为O(...) space_complexity: type: string pattern: “^O\\(.+\\)$” constraints: - “代码必须遵循PEP 8规范” - “必须包含至少一个使用示例” - “复杂度分析必须正确”类似地,我们定义title_generator,outline_generator,theory_explainer,blog_integrator等智能体的规格。
定义工作流规格(generate_blog_workflow.yaml):
workflow: name: technical_blog_generation input: topic: “二叉树遍历” key_points: “覆盖前序、中序、后序的递归和迭代实现” target_audience: “初级到中级Python开发者” agents: - ref: “./specs/title_generator.yaml” - ref: “./specs/outline_generator.yaml” - ref: “./specs/theory_explainer.yaml” - ref: “./specs/code_example_generator.yaml” - ref: “./specs/blog_integrator.yaml” steps: - name: generate_title agent: title_generator input: “{{workflow.input}}” - name: generate_outline agent: outline_generator input: “{{workflow.input}} + {{steps.generate_title.output}}” # 结合初始输入和标题 depends_on: [generate_title] - name: explain_theory agent: theory_explainer input: “{{steps.generate_outline.output.sections[0]}}” # 假设大纲的第一个部分是理论 depends_on: [generate_outline] - name: generate_code_for_preorder agent: code_example_generator input: algorithm_topic: “二叉树前序遍历” theoretical_explanation: “{{steps.explain_theory.output}}” depends_on: [explain_theory] # ... 类似步骤生成中序、后序遍历代码 - name: integrate_blog agent: blog_integrator input: “{{所有前面步骤的输出}}” depends_on: [generate_title, generate_outline, explain_theory, generate_code_for_preorder, ...]4.2 第二步:实现上下文管理与智能体调用
我们选择使用一个简单的内存型“黑板”作为共享上下文。每个步骤的输出都会以一个固定的键(如step_name:output)存储到黑板上。下游智能体的输入模板({{steps.xxx.output}})会被编排器替换为黑板中对应的实际值。
对于智能体调用,我们使用LangChain或LlamaIndex这类框架的底层能力,但用我们自己的规范层进行封装。核心代码如下(概念示例):
class SpecDrivenAgent: def __init__(self, spec_path: str, llm_client): self.spec = self._load_spec(spec_path) # 加载YAML规格 self.llm = llm_client def run(self, task_input: dict, context: Blackboard) -> dict: # 1. 组装提示词 system_message = self._build_system_message(self.spec) user_message = self._build_user_message(task_input, context, self.spec) # 2. 调用LLM raw_response = self.llm.chat_completion( messages=[system_message, user_message], model=self.spec.get(“model”, “gpt-3.5-turbo”) ) # 3. 解析与验证 parsed_output = self._parse_output(raw_response, self.spec[“output_schema”]) if not self._validate_constraints(parsed_output, self.spec[“constraints”]): raise AgentValidationError(“输出不符合约束条件”) # 4. 返回结构化结果 return parsed_output class WorkflowOrchestrator: def __init__(self, workflow_spec_path: str, agents_registry: dict): self.workflow_spec = self._load_workflow_spec(workflow_spec_path) self.agents = agents_registry self.context = Blackboard() def execute(self, initial_input: dict): self.context.set(“workflow.input”, initial_input) for step in self.workflow_spec[“steps”]: # 解析依赖,获取输入数据 step_input = self._resolve_step_input(step, self.context) # 获取对应的智能体实例 agent = self.agents[step[“agent”]] # 执行智能体 step_output = agent.run(step_input, self.context) # 将结果存入上下文 self.context.set(f“steps.{step[‘name’]}.output”, step_output) final_output = self.context.get(f“steps.{self.workflow_spec[‘steps’][-1][‘name’]}.output”) return final_output4.3 第三步:加入观测与调试
在生产环境中,我们需要记录每一步的详细日志。这不仅仅是打印信息,而是结构化的可观测性数据:
# 在Agent.run和Orchestrator.execute中插入观测点 def run(self, task_input: dict, context: Blackboard) -> dict: trace_id = generate_trace_id() logger.info(f“[{trace_id}] Agent {self.spec[‘name’]} started.”, extra={ “spec”: self.spec, “input”: task_input, “context_snapshot”: context.get_relevant_snapshot() }) # ... 调用LLM ... logger.info(f“[{trace_id}] Agent {self.spec[‘name’]} finished.”, extra={ “raw_response”: raw_response, “parsed_output”: parsed_output, “token_usage”: llm_response.usage }) return parsed_output这些日志可以发送到像Prometheus+Grafana或专用的APM工具中,从而生成仪表盘,监控工作流成功率、各步骤耗时、LLM调用成本等关键指标。
5. 进阶话题与避坑指南
在实际部署和开发Spec Kit Agents工作流时,你会遇到一些更具挑战性的问题。以下是一些常见陷阱和应对策略。
5.1 处理智能体间的冲突与共识
当多个智能体对同一问题有不同见解时(例如,“架构师”选择了MongoDB,而“数据库优化师”认为应该用PostgreSQL),怎么办?
- 策略一:设立仲裁者:引入一个更高层级的“首席架构师”或“决策者”智能体。当冲突发生时,将争议点和双方论据提交给仲裁者做最终决定,并将决定记录到上下文中。
- 策略二:基于规则的冲突消解:在规范中预先定义规则。例如,“所有数据库选型争议,最终以‘数据一致性要求优先级高于读写速度’这一规则裁决”。
- 策略三:探索式工作流:设计并行分支。让持不同意见的智能体分别沿着自己的方案向下执行一小段(如生成初步设计),再由一个评估智能体对两个中间结果进行评估,选择更优的路径继续。这类似于强化学习中的探索。
实操心得:冲突不一定是坏事,它往往能暴露需求或设计中的模糊点。将关键的冲突和最终的决策理由清晰地记录在上下文中,其价值有时甚至大于最终产出,因为它形成了项目的“决策日志”,对于后续维护和复盘至关重要。
5.2 工作流的动态性与适应性
现实任务往往不是线性的。如何让工作流根据中间结果动态调整?
- 条件分支:在工作流规格中支持
if条件。例如,if: “{{steps.code_review.output.score}} < 80”,则跳转到steps.refactor_code,否则继续。 - 循环:支持
for-each或while循环。例如,对一个需求列表中的每一项,循环执行“分析-设计-实现”子工作流。 - 动态智能体选择:根据上下文内容,动态决定调用哪个智能体。例如,如果分析出需求涉及图像处理,则调用“计算机视觉专家”智能体;如果涉及金融计算,则调用“量化金融专家”智能体。这需要一套智能体注册与发现机制,以及一个根据上下文进行路由的“调度器”。
5.3 成本控制与性能优化
Multi-Agent工作流意味着多次调用LLM,成本可能急剧上升。优化策略包括:
- 智能体粒度设计:不要过度细分。如果一个简单任务能被一个提示词解决,就不要拆成两个智能体。智能体间的通信(上下文传递)本身也有开销。
- 模型分级使用:采用“金字塔”模型策略。轻量级任务(如格式检查、简单分类)使用低成本模型(如GPT-3.5-Turbo、Claude Haiku);核心创意、复杂推理任务才使用顶级模型(如GPT-4、Claude Opus)。这就是异构LLM服务调度的价值。
- 上下文压缩与摘要:如前所述,积极使用摘要智能体来压缩传递给下游的上下文,能显著减少Token消耗。
- 缓存与记忆:对于相同或相似的输入,智能体的输出应该是确定的。可以引入缓存层,对智能体的输入进行哈希,如果命中缓存则直接返回历史结果,避免重复调用LLM。这对于那些相对稳定的任务(如根据固定模板生成代码)非常有效。
5.4 评估与持续改进
如何衡量一个Spec Kit Agents工作流的好坏?
- 客观指标:
- 任务完成率:工作流从头到尾成功执行的比例。
- 人工干预率:需要人工介入纠正或决策的步骤比例。
- 单步输出质量:通过自动化检查(如代码编译通过率、文档格式合规率)或小模型评分来评估。
- 端到端结果质量:最终产出物(如生成的应用程序)通过功能测试、用户体验测试的比例。
- 成本与耗时:平均每次执行消耗的Token费用和总时间。
- 主观指标:通过专家评审或用户反馈,对最终产物的实用性、创造性进行打分。
- 改进循环:建立基于评估结果的反馈机制。将失败的案例、低分的输出作为新的训练数据或提示词优化素材,持续迭代各个智能体的规格(特别是系统指令部分)和工作流设计。
6. 典型问题排查与调试技巧
即使设计再完善,在实际运行中也会遇到各种问题。以下是一个快速排查指南:
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
智能体输出不符合output_schema | 1. 提示词中未明确要求JSON格式。 2. output_schema过于复杂,模型难以一次生成正确。3. 模型“幻觉”产生多余字段或文本。 | 1.强化系统指令:在系统提示中明确“你必须以严格的JSON格式响应,且仅包含指定字段”。 2.分步生成:将复杂输出拆解。先让智能体生成核心内容,再让一个“格式校验与修正”智能体将其转化为目标Schema。 3.使用结构化输出功能:如果LLM API支持(如OpenAI的JSON Mode, Anthropic的Structured Outputs),务必启用。 |
| 工作流在某一环节卡住或循环 | 1. 依赖关系定义有循环。 2. 某个智能体输出不稳定,导致条件分支判断反复横跳。 3. 上下文状态未正确更新。 | 1.检查工作流DAG:确保其是无环的。可视化工具很有帮助。 2.增加确定性:为条件判断增加“缓冲”或“投票”机制。例如,连续三次评估得分低于阈值才触发重构,避免单次波动。 3.打印调试:在编排器中输出每一步执行前后的上下文快照,检查数据流是否正确。 |
| 最终结果质量低下 | 1. 任务链过长,信息衰减或扭曲。 2. 某个关键智能体能力不足。 3. 初始需求(Input)模糊。 | 1.引入复盘与修正环节:在工作流末尾增加一个“质量评估与修订”循环。评估不通过,则带着修改意见重新进入流程的特定环节。 2.升级模型或优化提示词:对瓶颈智能体,尝试使用更强的模型,或投入更多精力优化其系统指令和示例。 3.增强需求澄清:在流程最前端,增加一个“需求澄清智能体”,与用户进行多轮交互,将模糊需求转化为清晰、结构化的规格说明书,再进入主流程。 |
| LLM API调用频繁失败或超时 | 1. 网络或提供商问题。 2. 速率限制(Rate Limit)。 3. 单次请求Token过长或响应时间太久。 | 1.实现重试与退避机制:对网络错误和可重试的服务端错误(如429 Too Many Requests)进行指数退避重试。 2.请求队列与限流:在编排器层面实现一个全局的请求队列,针对不同API密钥和模型实施速率控制。 3.优化提示词与上下文:持续压缩上下文,移除不必要的信息。考虑对长响应模型设置更短的 max_tokens,或使用流式响应。 |
独家调试技巧:建立一个“回放调试”模式。将某次失败工作流的所有输入(包括初始输入和每个智能体收到的完整提示词)保存下来。然后,你可以离线、单步地重新执行任何一个智能体,修改它的提示词或尝试不同的模型,观察输出变化。这能帮你精准定位是哪个环节、哪种指令出了问题,效率远高于盲目地调整整个工作流。
Spec Kit Agents所代表的规范驱动、上下文共享的智能体工作流模式,本质上是在为AI应用开发引入软件工程中久经考验的模块化、契约化和可观测性思想。它初看起来增加了前期的设计复杂度,但换来的却是后期开发、调试和维护效率的指数级提升。当你需要构建的不是一次性的智能对话,而是稳定、可靠、可复用的AI生产流程时,这种投入是绝对值得的。开始的最佳方式,就是从一个你熟悉的小型、具体的任务入手,定义两个智能体,让它们基于一份简单的规范进行协作,亲身体验一下这种“团队编程”的魅力与挑战。