Files
hubian 05950a3c84 feat: 多智能体竞标调度系统 v1.0.0
核心组件:
- Orchestrator: 意图理解、任务拆分、竞标管理、结果验证
- Worker: 竞标任务、执行交付
- TaskBoard: 状态管理、信息存储
- BidEvaluator: 竞标评估算法
- ExecutionMonitor: 执行监控、超时处理
- LLMClient: 大模型接口调用

功能特性:
- 竞标机制:Agent主动竞争任务
- 动态调度:串行/并行任务智能调度
- 智能容错:超时切换、验证重试
- 质量保证:结果验证、历史追踪

Web界面:首页、请求列表、任务列表、Agent管理
API接口:请求/任务/Agent管理、测试接口
端口:19015
2026-04-12 01:54:15 +08:00

279 lines
11 KiB
HTML

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>多智能体竞标调度系统</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/remixicon@3.5.0/fonts/remixicon.css" rel="stylesheet">
<style>
body { background-color: #f5f7fa; }
.hero-section {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 60px 0;
}
.stat-card {
background: white;
border-radius: 12px;
padding: 20px;
box-shadow: 0 2px 12px rgba(0,0,0,0.08);
}
.feature-card {
background: white;
border-radius: 12px;
padding: 30px;
box-shadow: 0 2px 12px rgba(0,0,0,0.08);
transition: transform 0.2s;
}
.feature-card:hover {
transform: translateY(-5px);
}
.input-area {
background: white;
border-radius: 12px;
padding: 30px;
box-shadow: 0 2px 12px rgba(0,0,0,0.08);
}
.result-area {
background: #1a1a2e;
border-radius: 12px;
padding: 20px;
color: #eee;
min-height: 300px;
}
.agent-badge {
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
padding: 8px 16px;
border-radius: 20px;
font-size: 0.85rem;
}
</style>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
<a class="navbar-brand" href="/">
<i class="ri-robot-2-line"></i> 多智能体竞标调度系统
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
<li class="nav-item"><a class="nav-link active" href="/">首页</a></li>
<li class="nav-item"><a class="nav-link" href="/requests">请求列表</a></li>
<li class="nav-item"><a class="nav-link" href="/tasks">任务列表</a></li>
<li class="nav-item"><a class="nav-link" href="/agents">Agent管理</a></li>
</ul>
</div>
</div>
</nav>
<div class="hero-section">
<div class="container text-center">
<h1 class="display-4"><i class="ri-robot-2-fill"></i> 多智能体竞标调度系统</h1>
<p class="lead">任务竞标 · 动态调度 · 智能容错</p>
<div class="mt-4">
<span class="agent-badge me-2"><i class="ri-code-line"></i> 代码专家</span>
<span class="agent-badge me-2"><i class="ri-search-line"></i> 搜索专家</span>
<span class="agent-badge me-2"><i class="ri-edit-line"></i> 写作专家</span>
<span class="agent-badge"><i class="ri-bar-chart-line"></i> 分析专家</span>
</div>
</div>
</div>
<div class="container py-4">
<!-- 统计卡片 -->
<div class="row mb-4">
<div class="col-md-3">
<div class="stat-card text-center">
<i class="ri-message-3-line fs-1 text-primary"></i>
<h3 id="stat-requests">0</h3>
<p class="text-muted">用户请求</p>
</div>
</div>
<div class="col-md-3">
<div class="stat-card text-center">
<i class="ri-task-line fs-1 text-success"></i>
<h3 id="stat-tasks">0</h3>
<p class="text-muted">任务总数</p>
</div>
</div>
<div class="col-md-3">
<div class="stat-card text-center">
<i class="ri-robot-line fs-1 text-warning"></i>
<h3 id="stat-agents">4</h3>
<p class="text-muted">注册Agent</p>
</div>
</div>
<div class="col-md-3">
<div class="stat-card text-center">
<i class="ri-flashlight-line fs-1 text-danger"></i>
<h3 id="stat-active">0</h3>
<p class="text-muted">活跃执行</p>
</div>
</div>
</div>
<!-- 输入区域 -->
<div class="row mb-4">
<div class="col-md-6">
<div class="input-area">
<h5><i class="ri-chat-3-line"></i> 发送请求</h5>
<div class="mb-3">
<textarea id="user-input" class="form-control" rows="5"
placeholder="输入你的请求,例如:帮我写一个Python爬虫,爬取新闻网站..."></textarea>
</div>
<button id="submit-btn" class="btn btn-primary w-100">
<i class="ri-send-plane-fill"></i> 发送请求
</button>
<div class="mt-3">
<h6>快速测试:</h6>
<button class="btn btn-outline-secondary btn-sm me-2" onclick="quickTest('intent')">意图分析</button>
<button class="btn btn-outline-secondary btn-sm me-2" onclick="quickTest('split')">任务拆分</button>
<button class="btn btn-outline-secondary btn-sm" onclick="quickTest('full')">完整流程</button>
</div>
</div>
</div>
<div class="col-md-6">
<div class="result-area">
<h6><i class="ri-terminal-line"></i> 执行日志</h6>
<div id="log-output" style="font-family: monospace; white-space: pre-wrap; max-height: 280px; overflow-y: auto;">
等待输入...
</div>
</div>
</div>
</div>
<!-- 功能介绍 -->
<div class="row">
<div class="col-md-4">
<div class="feature-card">
<i class="ri-award-line fs-1 text-primary"></i>
<h5 class="mt-3">竞标机制</h5>
<p>Agent主动竞争任务,展示能力和方案,规划Agent综合评估选择最佳执行者。</p>
</div>
</div>
<div class="col-md-4">
<div class="feature-card">
<i class="ri-flow-chart fs-1 text-success"></i>
<h5 class="mt-3">动态调度</h5>
<p>串行任务严格按依赖执行,并行任务最大化并发,智能分配执行顺序。</p>
</div>
</div>
<div class="col-md-4">
<div class="feature-card">
<i class="ri-shield-check-line fs-1 text-warning"></i>
<h5 class="mt-3">智能容错</h5>
<p>超时自动切换备选Agent,验证失败给予重试机会,失败记录用于改进。</p>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
// 加载统计
function loadStats() {
fetch('/api/stats')
.then(r => r.json())
.then(data => {
document.getElementById('stat-requests').textContent = data.total_requests || 0;
document.getElementById('stat-tasks').textContent = data.total_tasks || 0;
document.getElementById('stat-agents').textContent = data.total_agents || 0;
document.getElementById('stat-active').textContent = data.active_executions || 0;
});
}
// 日志输出
function log(text, type = 'info') {
const logArea = document.getElementById('log-output');
const time = new Date().toLocaleTimeString();
const color = type === 'error' ? '#ff6b6b' : type === 'success' ? '#51cf66' : '#74c0fc';
logArea.innerHTML += `<span style="color:${color}">[${time}] ${text}</span>\n`;
logArea.scrollTop = logArea.scrollHeight;
}
// 提交请求
document.getElementById('submit-btn').addEventListener('click', async () => {
const input = document.getElementById('user-input').value.trim();
if (!input) {
log('请输入请求内容', 'error');
return;
}
log('发送请求...');
document.getElementById('submit-btn').disabled = true;
try {
const response = await fetch('/api/request', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({content: input})
});
const data = await response.json();
if (data.error) {
log(`错误: ${data.error}`, 'error');
} else {
log(`请求ID: ${data.id}`, 'success');
log(`状态: ${data.status}`);
if (data.task_graph) {
const tasks = Object.keys(data.task_graph.tasks);
log(`拆分任务: ${tasks.length} 个`);
}
if (data.final_result) {
log(`结果: ${JSON.stringify(data.final_result)}`, 'success');
}
}
} catch (e) {
log(`请求失败: ${e}`, 'error');
}
document.getElementById('submit-btn').disabled = false;
loadStats();
});
// 快速测试
async function quickTest(type) {
const input = document.getElementById('user-input').value.trim() || '帮我写一个Python爬虫';
log(`测试 ${type}...`);
try {
const url = type === 'intent' ? '/api/test_intent' :
type === 'split' ? '/api/test_split' : '/api/request';
const response = await fetch(url, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(type === 'full' ? {content: input} : {prompt: input})
});
const data = await response.json();
if (data.error) {
log(`错误: ${data.error}`, 'error');
} else {
log(`结果:`, 'success');
log(JSON.stringify(data.intent || data.tasks || data, null, 2));
}
} catch (e) {
log(`测试失败: ${e}`, 'error');
}
loadStats();
}
// 初始化
loadStats();
</script>
</body>
</html>