32-day8-multi-agent
基于 IT 工程团队角色(需求分析师、架构师、测试工程师)的分布式多智能体 实验
🎯 实验目标
3 个 Specialist Agent 分别扮演 IT 团队中的「需求分析师」「架构师」「测试工程师」,
运行在“不同主机”(通过hosts伪装),由 Coordinator 协调完成一个技术方案的生成与验证。
📁 项目结构
day08_qwen_distributed/
├── agents/
│ ├── analyst.py → http://analyst.local:8001
│ ├── architect.py → http://architect.local:8002
│ └── tester.py → http://tester.local:8003
├── coordinator_1.py
├── coordinator_2.py
├── start_all.sh
├── stop_all.sh
├── .env
└── logs/ (自动创建)
第一步:配置 hosts 文件和防火墙(模拟多主机)
只需要使用root用户实施一次,同学不需要再做。
# /etc/hosts
127.0.0.1 analyst.local
127.0.0.1 architect.local
127.0.0.1 tester.local
ufw allow 8001/tcp
ufw allow 8002/tcp
ufw allow 8003/tcp
ufw allow 8011/tcp
ufw allow 8012/tcp
ufw allow 8013/tcp
✅ 程序运行后通过
http://analyst.local:8001访问“需求分析服务”
✅ 程序运行后通过http://architect.local:8002访问“架构设计服务”
✅ 程序运行后通过http://tester.local:8003访问“功能测试服务”
第二步:虚拟环境,依赖安装
# 创建目录
mkdir -p day8_many/agents && cd day8_many
# 创建虚拟环境(Python 3.10+)
python3 -m venv day8venv
source day8venv/bin/activate
# 升级 pip
pip install --upgrade pip -i https://mirrors.aliyun.com/pypi/simple/
# 安装python依赖包
pip install fastapi uvicorn[standard] requests langchain-community dashscope python-dotenv
# 创建 .env 文件
echo "DASHSCOPE_API_KEY=替换为您的实际API-Key" > .env
🧩 第三步:三个 IT 角色 Agent(FastAPI)
agents/analyst.py —— 需求分析师
tee agents/analyst.py <<'EOFA'
# analyst.py - 带实时日志的需求分析师
from fastapi import FastAPI
from langchain_community.chat_models import ChatTongyi
import uvicorn
import os
import argparse
from dotenv import load_dotenv
load_dotenv()
app = FastAPI(title="需求分析师 Agent")
llm = ChatTongyi(
model="qwen-turbo",
temperature=0.7,
dashscope_api_key=os.getenv("DASHSCOPE_API_KEY")
)
@app.post("/analyze")
def analyze(payload: dict):
requirement = payload.get("requirement", "")
print(f"\n📥 [收到需求] {requirement}")
prompt = (
f"作为IT需求分析师,请针对以下需求提供3条关键技术要点或实现思路:\n"
f"「{requirement}」\n"
"要求:简洁、可落地、避免空泛描述。"
)
response = llm.invoke(prompt)
print(f"📤 [返回分析] {response.content[:120]}...")
return {"role": "analyst", "content": response.content}
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--port", type=int, default=8001, help="监听端口")
args = parser.parse_args()
print(f"🚀 需求分析师服务已启动,监听端口: {args.port}")
print("📝 等待其他服务调用...\n")
uvicorn.run(app, host="0.0.0.0", port=args.port, reload=False)
EOFA
agents/architect.py —— 架构师
tee agents/architect.py <<'EOFB'
# architect.py - 带实时日志的架构师
from fastapi import FastAPI
from langchain_community.chat_models import ChatTongyi
import uvicorn
import os
import argparse
from dotenv import load_dotenv
load_dotenv()
app = FastAPI(title="架构师 Agent")
llm = ChatTongyi(
model="qwen-turbo",
temperature=0.2,
dashscope_api_key=os.getenv("DASHSCOPE_API_KEY")
)
@app.post("/design")
def design(payload: dict):
raw_ideas = payload.get("raw_ideas", "")
print(f"\n📥 [收到分析结果] {raw_ideas[:100]}...")
prompt = (
"作为系统架构师,请将以下技术思路整理成一段清晰、专业、可执行的方案描述:\n"
f"{raw_ideas}\n"
"要求:使用标准技术术语,逻辑连贯,适合写入设计文档。"
)
response = llm.invoke(prompt)
print(f"📤 [返回设计] {response.content[:120]}...")
return {"role": "architect", "content": response.content}
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--port", type=int, default=8002, help="监听端口")
args = parser.parse_args()
print(f"🚀 架构师服务已启动,监听端口: {args.port}")
print("📝 等待其他服务调用...\n")
uvicorn.run(app, host="0.0.0.0", port=args.port, reload=False)
EOFB
agents/tester.py —— 测试工程师
tee agents/tester.py <<'EOFC'
# tester.py - 带实时日志的测试工程师
from fastapi import FastAPI
from langchain_community.chat_models import ChatTongyi
import uvicorn
import os
import argparse
from dotenv import load_dotenv
load_dotenv()
app = FastAPI(title="测试工程师 Agent")
llm = ChatTongyi(
model="qwen-turbo",
temperature=0.1,
dashscope_api_key=os.getenv("DASHSCOPE_API_KEY")
)
@app.post("/review")
def review(payload: dict):
design = payload.get("design", "")
print(f"\n📥 [收到设计方案] {design[:100]}...")
prompt = (
"作为资深测试工程师,请严格审查以下技术方案是否存在以下问题:\n"
"- 技术选型不合理\n"
"- 存在安全或性能隐患\n"
"- 假设不成立或脱离实际\n"
"- 违反工程最佳实践\n\n"
"如有问题,请直接给出修正建议;如无,请回复'✅ 方案合理,无明显风险'。\n\n"
f"方案:{design}"
)
response = llm.invoke(prompt)
print(f"📤 [返回评审] {response.content[:120]}...")
return {"role": "tester", "content": response.content}
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--port", type=int, default=8003, help="监听端口")
args = parser.parse_args()
print(f"🚀 测试工程师服务已启动,监听端口: {args.port}")
print("📝 等待其他服务调用...\n")
uvicorn.run(app, host="0.0.0.0", port=args.port, reload=False)
EOFC
🧠 第三步:Coordinator(协调器)
coordinator_1.py
tee coordinator_1.py <<'EOFD'
# coordinator.py
import requests
class ITTeamCoordinator:
AGENTS = {
"analyst": "http://analyst.local:8001/analyze",
"architect": "http://architect.local:8002/design",
"tester": "http://tester.local:8003/review"
}
def run(self, requirement: str):
print(f"\n🎯 收到新需求: {requirement}\n")
try:
# Step 1: 需求分析师
print("📞 调用 [需求分析师] (analyst.local:8001)...")
res = requests.post(self.AGENTS["analyst"], json={"requirement": requirement}, timeout=30).json()
print(f"✅ 需求分析师输出:\n{res['content'][:150]}...\n")
# Step 2: 架构师
print("📞 调用 [架构师] (architect.local:8002)...")
design = requests.post(self.AGENTS["architect"], json={"raw_ideas": res["content"]}, timeout=30).json()
print(f"✅ 架构师输出:\n{design['content'][:150]}...\n")
# Step 3: 测试工程师
print("📞 调用 [测试工程师] (tester.local:8003)...")
review = requests.post(self.AGENTS["tester"], json={"design": design["content"]}, timeout=30).json()
print(f"✅ 测试工程师反馈:\n{review['content'][:150]}...\n")
return review["content"]
except requests.exceptions.RequestException as e:
print(f"❌ 调用 Agent 时出错: {e}")
return None
except KeyError as e:
print(f"❌ Agent 返回格式异常,缺少字段: {e}")
return None
def main():
coord = ITTeamCoordinator()
print("🚀 IT 多智能体协作系统已启动!")
print("💡 请输入你的技术需求(例如:'如何用 AI 监控服务器异常?')")
print("📌 输入 'quit' 或 'exit' 退出。\n")
while True:
try:
user_input = input("📝 你的需求 > ").strip()
if not user_input:
continue
if user_input.lower() in ("quit", "exit", "q"):
print("\n👋 再见!感谢使用 IT 智能协作团队。")
break
result = coord.run(user_input)
if result:
print("=" * 70)
print("🔧 最终交付方案(经测试验证):")
print(result)
print("=" * 70)
else:
print("⚠️ 本次协作未能完成,请检查各 Agent 是否正常运行。")
except KeyboardInterrupt:
print("\n\n👋 收到中断信号,正在退出...")
break
except Exception as e:
print(f"💥 未知错误: {e}")
if __name__ == "__main__":
main()
EOFD
coordinator_2.py
tee coordinator_2.py <<'EOFD'
# coordinator_2.py
import requests
class ITTeamCoordinator:
AGENTS = {
"analyst": "http://analyst.local:8011/analyze",
"architect": "http://architect.local:8012/design",
"tester": "http://tester.local:8013/review"
}
def run(self, requirement: str):
print(f"\n🎯 收到新需求: {requirement}\n")
try:
# Step 1: 需求分析师
print("📞 调用 [需求分析师] (analyst.local:8011)...")
res = requests.post(self.AGENTS["analyst"], json={"requirement": requirement}, timeout=30).json()
print(f"✅ 需求分析师输出:\n{res['content'][:150]}...\n")
# Step 2: 架构师
print("📞 调用 [架构师] (architect.local:8012)...")
design = requests.post(self.AGENTS["architect"], json={"raw_ideas": res["content"]}, timeout=30).json()
print(f"✅ 架构师输出:\n{design['content'][:150]}...\n")
# Step 3: 测试工程师
print("📞 调用 [测试工程师] (tester.local:8013)...")
review = requests.post(self.AGENTS["tester"], json={"design": design["content"]}, timeout=30).json()
print(f"✅ 测试工程师反馈:\n{review['content'][:150]}...\n")
return review["content"]
except requests.exceptions.RequestException as e:
print(f"❌ 调用 Agent 时出错: {e}")
return None
except KeyError as e:
print(f"❌ Agent 返回格式异常,缺少字段: {e}")
return None
def main():
coord = ITTeamCoordinator()
print("🚀 IT 多智能体协作系统已启动!")
print("💡 请输入你的技术需求(例如:'如何用 AI 监控服务器异常?')")
print("📌 输入 'quit' 或 'exit' 退出。\n")
while True:
try:
user_input = input("📝 你的需求 > ").strip()
if not user_input:
continue
if user_input.lower() in ("quit", "exit", "q"):
print("\n👋 再见!感谢使用 IT 智能协作团队。")
break
result = coord.run(user_input)
if result:
print("=" * 70)
print("🔧 最终交付方案(经测试验证):")
print(result)
print("=" * 70)
else:
print("⚠️ 本次协作未能完成,请检查各 Agent 是否正常运行。")
except KeyboardInterrupt:
print("\n\n👋 收到中断信号,正在退出...")
break
except Exception as e:
print(f"💥 未知错误: {e}")
if __name__ == "__main__":
main()
EOFD
▶ 第四步:启动脚本 start_all.sh
tee start_all.sh <<'EOFH'
#!/bin/bash
mkdir -p logs
nohup python agents/analyst.py > logs/analyst.log 2>&1 &
nohup python agents/architect.py > logs/architect.log 2>&1 &
nohup python agents/tester.py > logs/tester.log 2>&1 &
echo "✅ IT 团队已启动:需求分析师(8001) | 架构师(8002) | 测试工程师(8003)"
echo "⏳ 等待服务就绪..."
sleep 3
EOFH
bash start_all.sh;
▶ 第五步:关闭脚本 stop_all.sh
tee stop_all.sh <<'EOFJ'
#!/bin/bash
pkill -f analyst.py
pkill -f architect.py
pkill -f tester.py
EOFJ
🎓 课堂演示1
演示1:一键启动start_all.sh+ coordinator_1.py → 展示完整流程
python coordinator_1.py
输入需求:
“设计一个防止学生在在线考试中作弊的 AI 系统”
可能输出流程:
- 需求分析师:
“1. 实时摄像头行为分析;2. 屏幕内容监控;3. 异常操作模式检测...” - 架构师:
“本系统采用端侧+云端协同架构,通过 WebRTC 采集视频流,使用轻量级 CNN 模型检测异常行为...” - 测试工程师:
“⚠️ 屏幕监控涉及隐私合规风险,建议改为‘仅提取窗口焦点和应用列表’,避免截屏。”
→ 完全符合真实 IT 项目评审流程!
✅ 案例特点
| 优势 | 说明 |
|---|---|
| 工程真实 | 每个角色独立部署、独立演进 |
| 概念清晰 | 需求 → 设计 → 验证,软件工程经典流程 |
| 可扩展 | 可加“DevOps 工程师”做部署方案,“安全审计员”做合规检查 |
🎓 课堂演示2
演示2:手动前台启动 + coordinator_2.py → 适合展示实时协作细节(看得见每个角色在“思考”)
开4个窗口,
窗口1 (共4个)
python agents/analyst.py --port 8011
窗口2 (共4个)
python agents/architect.py --port 8012
窗口3 (共4个)
python agents/tester.py --port 8013
窗口4 (共4个)
# 单个测试
curl -X POST http://localhost:8011/analyze \
-H "Content-Type: application/json" \
-d '{"requirement":"设计一个校园二手书交易平台"}'
# 集体测试
python coordinator_2.py
浙公网安备 33010602011771号