1. 摘要
我使用 TRAE SOLO 从零构建了 Agora——一个多 Agent 圆桌讨论中间件。它让多个 AI Agent 围坐一桌,围绕议题进行结构化讨论、达成共识、输出结论。
项目包含完整的 Web UI、REST API、SSE 实时推送、4 种发言模式、3 种可见性策略、角色专属提示词系统,以及会议精炼/总结功能。(现已开源:Agnet会议中间件)
全程由 SOLO 驱动开发,从架构设计到 Bug 修复,SOLO 承担了超过 99% 的编码工作。(包括这篇帖子
)
2. 背景
我是一名业余开发者,日常使用 Trae 时经常需要让多个 AI Agent 协作完成复杂任务,多个Agent分工不仅可以提升开发效率,还可以节省上下文,保留更多开发过程中的细节,大大提升代码质量。
然而trae暂时没有类似专家会议的功能,我面临的挑战是:
- 我需要在Agent之间传达消息,工作交接容易出错
- 多个 Agent 各种独立工作,容易跑题、重复、陷入误区
- Agent 之间的共识和分歧难以追踪
- 无法实时观察讨论过程,调试困难
- 需要给每个Agent重复强调项目规范和细节
缺乏一个通用的、可视化的多 Agent 讨论中间件
我希望构建一个开箱即用的多 Agent 议事平台:创建房间、指定角色、开始讨论——就这么简单。
3. 实践过程
3.1 任务拆解
我将整个项目拆分为以下阶段:
- 核心架构:FastAPI 后端 + SQLite 存储 + SSE 实时推送
- 房间与 Agent 管理:创建房间、注册 Agent、状态流转
- 发言机制:4 种发言模式(轮流/随机/主持人指定/自由)
- Web UI:首页、房间页、设置页、消息详情页
- 高级功能:精炼、共识、导出、自定义角色、会议总结
- 提示词系统:角色专属提示词拆分与动态生成
3.2 SOLO 能力的使用
在整个开发过程中,我深度使用了 SOLO 的以下能力:
代码搜索与理解
SOLO 能够快速定位代码中的关键逻辑。例如在排查"房间页面不显示角色卡片"的 Bug 时,SOLO 通过搜索 loadRoom() 函数,精准定位到 textContent 赋值销毁子元素的 DOM 问题——这种 Bug 人工排查往往需要打断点调试很久。
大规模代码生成
整个 agora.py 超过 2000 行,包含 50+ 个 API 端点。SOLO 能够根据需求描述一次性生成完整的路由、数据模型和业务逻辑。例如"添加自定义角色 CRUD"这个需求,SOLO 一次性生成了数据库表、4 个 API 端点、前端弹窗 UI,包括头像上传、表单验证等。
Bug 诊断与修复
开发过程中遇到了多个棘手 Bug,SOLO 都能快速定位根因:
- 提示词语法错误:
PRESET_ROLE_PROMPTS字典中的 ASCII 双引号导致 Python 字符串被截断,SOLO 通过运行测试脚本发现SyntaxError,并将内部引号替换为中文引号 - API 字段名不匹配:提示词中写
agent_name,但 Pydantic 模型实际字段是speaker/agent/name,SOLO 通过交叉比对模型定义和提示词内容修复了 3 处不一致 - SSE 事件缺失:发言后页面不刷新,SOLO 分析 SSE 事件流发现
speak接口只推送了new_message,缺少status_changed事件
迭代式开发
SOLO 最强大的能力是理解上下文并持续迭代。我只需要用自然语言描述问题和期望,SOLO 就能在现有代码基础上精确修改。例如:
“帮助页面的提示词应该只提示 agent 如何连接服务器,注册成功时服务器返回角色专属提示词”
SOLO 理解了这是一个架构级变更,自动完成了:后端新增 PRESET_ROLE_PROMPTS、SPEAKER_GUIDE、RECORDER_GUIDE 模板,修改注册接口返回 prompt 字段,前端简化帮助页提示词,新增自定义角色提示词输入和编辑弹窗。
3.3 关键 Prompt 与操作过程
以下是开发中的几个关键交互:
Prompt 1 - 项目启动:
“帮我搭建一个基于 FastAPI 的多 Agent 议事中间件,支持创建房间、Agent 注册、轮流发言、SSE 实时推送,带 Web UI”
SOLO 一次性生成了完整的项目骨架:FastAPI 应用、SQLite 数据库、SSE 端点、4 个 HTML 页面。
Prompt 2 - 架构优化:
“提示词应该拆分,先用通用提示词让agent连接到服务器,注册时返回角色专属提示词,避免每个 agent 读取全量提示词浪费上下文”
SOLO 理解了提示词分层架构的需求,自动完成了后端模板系统、注册回调、前端 UI 的全套修改。
Prompt 3 - Bug 反馈:
“房间页面进去后不显示任何角色状态卡片、主持人操作项、发言框”
SOLO 分析了 loadRoom() 的执行流程,发现 textContent 赋值销毁了 room-id-display span,导致后续 JS 抛出 TypeError 使整个函数崩溃。
3.4 踩过的坑
坑 1:textContent 的 DOM 破坏
设置父元素的 textContent 会销毁所有子元素。当 h1 内嵌套了 span#room-id-display,设置 h1.textContent = roomData.name 后 span 被移除,后续 getElementById('room-id-display') 返回 null,整个 loadRoom() 崩溃。解决方案是将房间名包裹在独立的 <span> 中。
坑 2:SSE 事件不完整导致页面不刷新
speak 接口只推送了 new_message 事件,但前端只在 status_changed 事件时刷新 agent 列表和轮次。导致发言者绿框不切换、轮次不推进、页面需要手动刷新。解决方案是在发言后额外推送 status_changed 事件。
坑 3:提示词中的字段名与 API 模型不匹配
给 Agent 的提示词中写了 agent_name,但实际 Pydantic 模型字段分别是 speaker(SpeakReq)、agent(ConsensusReq)、name(RegisterAgentReq)。Agent 按提示词调用 API 会直接 422 报错。这种跨层一致性问题是 AI 辅助开发中特别需要注意的。
坑 4:会议结束后 Agent 状态未更新
关闭房间时只更新了房间状态为 closed,没有将 Agent 设为 offline,导致页面显示所有角色仍在线。解决方案是在 close_room 中增加批量更新 Agent 状态的 SQL。
4. 成果展示
项目仓库
GitHub: GitHub - moyu929/Agora: Agnet会议中间件 · GitHub
核心功能一览
| 功能 | 说明 |
|---|---|
| 创建/暂停/恢复/关闭/重新打开 | |
| 预设 4 种角色 + 自定义角色(头像/名称/提示词) | |
| 轮流发言、随机发言、主持人指定、自由发言 | |
| 全量可见、增量可见、仅当前轮次 | |
| SSE 事件流 + Long-polling 通知 | |
| 记录员精炼发言内容,原文/精炼版对比 | |
| Agent 标注共识/分歧,优先级分类 | |
| 会议结束后请求记录员生成总结 | |
| Markdown / JSON 格式导出 | |
| 注册即返回角色专属提示词,2 步完成接入 |
5. 效果与总结
提效效果
- 开发效率:整个项目从零到开源发布,核心开发周期约 2 天。如果纯手工编码,仅 50+ 个 API 端点 + 4 个前端页面 + SSE 实时推送,预估至少需要 1-2 周
- Bug 修复速度:SOLO 定位 Bug 的速度远超人工调试。
- 代码质量:SOLO 生成的代码遵循项目已有模式,风格一致,且能自动发现跨层不一致问题
SOLO 在流程中的角色
SOLO 在这个项目中扮演了全栈开发伙伴的角色:
- 架构师:理解需求后设计整体架构(FastAPI + SQLite + SSE + 前端单页)
- 开发者:生成超过 90% 的代码,包括后端路由、前端 UI、CSS 样式
- 调试器:通过测试脚本和代码分析快速定位 Bug 根因
- 重构者:理解架构变更意图并自动完成跨文件修改




