AI Agent字数 4313阅读时长11 分钟

Agent Roundtable:构建一个本地多 Agent 专家圆桌系统

记录我如何搭建一个本地多 Agent 专家圆桌项目:用可配置角色、RAG 知识库、模型配置和 Streamlit UI,把问题交给多个专家 Agent 讨论并生成 Markdown 报告。

最近我搭建了一个多 Agent 聊天项目:agent_roundtable

它的想法很直接:我给一个主题,系统请几位不同方向的“专家 Agent”轮流发言,主持人负责追问、串联和总结,最后把整场讨论保存成一份 Markdown 报告。

这不是一个单纯的聊天机器人,而是一个可以配置角色、配置模型、接入本地知识库,并把讨论过程沉淀为文档的本地 Agent 工作流。

我更愿意把它理解成一个“专家圆桌工具”:不是让一个模型一次性回答所有问题,而是把问题拆给不同视角的 Agent,让它们围绕同一主题展开讨论。

一、为什么要做这个项目

我之前一直在思考一个问题:如果我要做一个真正有用的 AI Agent 系统,它到底应该长什么样?

单 Agent 很容易上手。你给它一个提示词,让它回答问题、调用工具、生成总结,这已经能做很多事。但当问题变复杂以后,单 Agent 的局限也很明显:

  • 它容易把多个视角混在一起。
  • 它很难稳定扮演多个专业角色。
  • 它的回答常常像一篇综合作文,而不是一场真实讨论。
  • 它很难明确区分“宏观经济视角”“投资视角”“AI 技术视角”“哲学视角”“历史战略视角”。

所以我想做一个多 Agent 圆桌。

一个主题可以交给不同专家分别讨论。宏观专家看制度和周期,投资专家看现金流和风险,AI 专家看技术演化,哲学专家看概念和价值判断,历史战略专家看长期结构。

这样做以后,输出就不再只是“一个模型的答案”,而更像是一场结构化讨论。

二、这个项目现在能做什么

agent_roundtable 目前是一个本地运行的 Python 项目,支持命令行和本地网页 UI 两种方式。

它现在主要能做几件事:

  • 用命令行或本地 Streamlit UI 启动多 Agent 圆桌。
  • 每个 Agent 可以单独配置 provider、模型和 API key 环境变量名。
  • API key 只放在 .env,不会写进 JSON、YAML、日志或报告。
  • 主线专家可以读取各自的本地长文资料,并通过 RAG 检索相关内容。
  • 运行结果会自动保存到 logs/,生成 Markdown 报告。
  • 报告中会标明每条发言使用的 providermodel
  • 没有 API key 时,也可以用 --mock 先跑通完整流程。

目前项目里有两条内置圆桌:

圆桌说明
experts宏观、投资、AI、哲学、历史战略五位主题专家
persona_inspired巴菲特、芒格、达利欧、哈耶克风格启发的副线

这里要特别说明:persona_inspired 只是“风格启发”,不是冒充本人,也不代表本人观点。它的作用是借用某种思考风格来组织回答。

三、我对 Agent 的理解

Agent 这个词现在很热,但如果讲得太玄,反而不好理解。

我的理解是:Agent 不是“会聊天的模型”,而是一个能围绕目标执行任务的系统单元。它通常包括几部分:

  • 一个角色或目标。
  • 一套提示词和行为约束。
  • 一些可调用工具。
  • 一段可被更新的状态。
  • 必要时还会有记忆、知识库和工作流控制。

普通聊天是“问一句,答一句”。Agent 更像是“为了完成一件事,自己判断下一步该做什么”。

如果加入 Tool Use,Agent 就可以调用搜索、文件、数据库、代码执行等工具。如果加入 RAG,Agent 就可以先查资料再回答。如果加入工作流,多个 Agent 之间就可以按一定顺序协作。

这也是我做 agent_roundtable 的原因:我不想只停留在提示词层面,而是想把角色、知识、模型调用和运行流程都程序化。如果想更系统地从智能体基础、ReAct 范式到记忆与 RAG 入门,可以参考 《Hello-Agents:从零开始构建 AI Agent 的开源教程》

四、为什么是多 Agent,而不是一个超级 Agent

一个超级 Agent 当然也可以回答复杂问题,但我更喜欢多 Agent 的形式。

原因很简单:现实中的复杂判断,本来就不是一个声音完成的。

比如讨论“AI 对投资和就业的长期影响”,至少可以拆成几种视角:

视角关注点
宏观经济专家生产率、就业结构、政策周期、制度变化
投资专家商业模式、现金流、估值、风险补偿
AI 研究者模型能力、算力、数据、工具链演化
哲学专家人的价值、劳动意义、技术伦理
历史战略专家技术革命、产业迁移、国家竞争

如果让一个模型一次性回答,它可能也会覆盖这些点,但它很难形成真正的视角差异。

多 Agent 的好处是:每个 Agent 都有自己的角色卡、知识范围、说话风格和盲点。讨论时,不同角色会从不同方向切入,主持人再把这些观点串起来。

这比单纯写一个超长 prompt 更稳,也更容易扩展。

五、RAG 在这个项目里的作用

RAG 可以通俗理解为“开卷考试”。

普通 LLM 回答问题,主要依赖模型参数里已有的知识。RAG 则是在生成回答之前,先从外部知识库里检索相关资料,再把检索到的内容交给模型参考。

agent_roundtable 里,我把本地长文资料放在 knowledge/ 目录下。每个专家可以对应自己的知识目录,例如:

knowledge/macro_economist/
knowledge/investing_master/
knowledge/ai_researcher/
knowledge/philosophy_expert/
knowledge/history_strategist/

然后通过命令建立索引:

python -m rag.ingest --expert-name macro_economist --embedding-provider keyword

目前我优先支持 keyword 检索,因为它不需要额外 API key,适合本地测试和入门使用。后续如果要做更强的语义检索,可以继续接入 embedding 模型。

这个设计对我很重要。

我不希望专家 Agent 只靠模型自己的“印象”回答。我更希望它可以读取我提前准备的书籍、论文、长文资料,把这些资料作为它的知识背景。

这样一来,Agent 就不只是一个角色扮演提示词,而是一个有本地知识来源的专家系统雏形。

六、项目结构

项目结构大致如下:

agent_roundtable/
├── main.py
├── ui/
│   └── app.py
├── src/
│   ├── graph.py
│   ├── agents.py
│   ├── llm.py
│   ├── model_catalog.py
│   ├── agent_llm_config.py
│   ├── loader.py
│   ├── logger.py
│   ├── prompts.py
│   └── state.py
├── agents/
│   ├── domain_experts/
│   └── persona_inspired/
├── councils/
├── configs/
│   └── agent_llms.json
├── knowledge/
├── rag/
├── vector_db/chroma/
├── logs/
├── tests/
├── requirements.txt
└── .env.example

几个关键目录的作用:

目录作用
agents/存放 Agent 的角色卡
councils/定义哪些 Agent 一起组成圆桌
configs/存放运行配置,尤其是每个 Agent 使用什么模型
knowledge/存放本地长文资料
rag/负责切分文档、建立索引和检索资料
logs/存放每次运行生成的 Markdown 报告
ui/本地 Streamlit 界面
src/项目核心逻辑

我比较喜欢这种分层方式。角色是角色,模型配置是模型配置,知识库是知识库,运行日志是运行日志。它们不要混在一起。

七、Agent 角色卡如何设计

在这个项目里,每个 Agent 都有自己的 YAML 角色卡。

一个 Agent 角色卡通常包括:

  • 名称。
  • 角色。
  • 世界观。
  • 说话风格。
  • 优点。
  • 盲点。
  • 对应的 RAG 知识目录。
  • Agent 类型。

例如,一个能源专家可以这样设计:

name: "Energy Expert"
role: "能源与产业政策专家"
worldview: "从能源供需、基础设施、地缘政治和技术替代分析问题"
speaking_style: "清晰、谨慎,先讲约束再讲判断"
strengths:
  - "能源供需分析"
  - "产业链拆解"
weaknesses:
  - "可能低估金融市场短期波动"
catchphrases:
  - "先看能源约束"
rag_expert_name: "energy_expert"
agent_type: "domain_expert"
profile:
  focus:
    - "能源安全"
    - "电力系统"
    - "油气与新能源"

这里的重点不是“写得像人设小说”,而是把 Agent 的分析边界固定下来。

一个好的专家 Agent,应该知道自己擅长什么,也知道自己可能忽略什么。否则所有 Agent 最后都会变成同一种声音。

八、模型配置为什么单独放

我把每个 Agent 使用什么模型,单独放在 configs/agent_llms.json

这样做有一个好处:角色和模型解耦。

角色卡只描述“这个 Agent 是谁”。JSON 配置只描述“这个 Agent 用哪个 provider、哪个模型、哪个 API key 环境变量”。

例如:

{
  "agents": {
    "macro_economist": {
      "provider": "openrouter",
      "model": "nvidia/nemotron-3-super-120b-a12b:free",
      "api_key_env": "OPENROUTER_API_KEY_1"
    },
    "ai_researcher": {
      "provider": "openrouter",
      "model": "nvidia/nemotron-3-ultra-550b-a55b:free",
      "api_key_env": "OPENROUTER_API_KEY_1"
    }
  }
}

注意,api_key_env 不是 API key 本身。它只是告诉程序去 .env 里找哪个变量。

真实 API key 不应该写进 JSON、YAML、README、日志或截图里。这一点很重要。

九、本地 UI 的意义

项目里我加了一个本地 Streamlit UI。

它不是为了做一个漂亮的商业产品,而是为了让配置过程更直观。

在 UI 里可以做这些事:

  • 选择圆桌。
  • 设置每个 Agent 使用哪个 provider。
  • 设置每个 Agent 使用哪个模型。
  • 选择每个 Agent 使用 .env 里的哪个 API key。
  • 保存配置到 configs/agent_llms.json
  • 输入一个主题,直接运行真实 LLM。
  • 查看运行进度、当前阶段和最近事件。
  • 预览最终总结和对话记录。

这个 UI 对我很实用。

因为多 Agent 系统一旦开始扩展,手动改配置文件会越来越麻烦。UI 不需要复杂,但至少要能让我快速切换模型、切换圆桌、测试不同组合。

十、MCP 与 Tool Use:未来可以怎么接

agent_roundtable 当前重点是本地多 Agent 圆桌、RAG 和报告生成。MCP 还不是项目的核心实现,但它是很自然的下一步。

MCP 全称是 Model Context Protocol,可以理解为一种让 AI 应用连接外部工具和数据源的开放协议。它试图把模型与工具、数据库、文件系统、业务系统之间的连接方式标准化。

如果说 RAG 主要解决“先查资料再回答”,那么 MCP 更偏向解决“Agent 如何标准化地连接外部工具并执行动作”。

所以在这篇文章里,我不会把 agent_roundtable 包装成一个已经完整接入 MCP 的项目。更准确地说,它先把本地多 Agent 工作流跑通,再为后续接入 MCP 和 Tool Use 留出接口空间。

对我这个项目来说,未来可以考虑几类 MCP 能力:

  • 接入文件系统 MCP,让 Agent 更标准地读取本地资料。
  • 接入搜索 MCP,让某些 Agent 可以联网查证。
  • 接入数据库 MCP,让金融或宏观 Agent 查询结构化数据。
  • 接入 GitHub MCP,让技术 Agent 可以分析仓库、issue 和代码。
  • 接入日历、邮件或任务系统,让圆桌讨论结果变成后续行动。

不过我现在不会一上来就把 MCP 做复杂。

我更倾向于先把本地 RAG、角色配置、模型调用、报告生成这条主线跑稳。等这个主线稳定后,再把 MCP 作为工具层接入。

十一、和 ReAct、LangGraph 的关系

ReAct 是一个经典 Agent 思路:让语言模型在推理和行动之间交替进行。通俗说,就是模型不只是直接给答案,而是边想、边调用工具、边根据工具结果调整下一步。

LangGraph 则更偏向工作流编排。它把 Agent 流程建模成图:节点可以是 Agent、工具、判断逻辑或总结器,边表示流程如何流转。

多 Agent 圆桌非常适合用图来理解:

flowchart TD
    A["主持人提出问题"] --> B["专家轮流发言"]
    B --> C["主持人小结"]
    C --> D["下一轮追问"]
    D --> B
    C --> E["最终总结"]

这不是简单的链式调用,而是一个有状态、有顺序、有角色分工的工作流。

我的项目当前就是沿着这个方向设计:先有圆桌流程,再有 Agent 发言,再有总结和日志沉淀。以后如果继续增强,可以加入更复杂的条件分支,例如:

  • 某个 Agent 发现证据不足时,触发检索。
  • 两个 Agent 观点冲突时,主持人追问。
  • 某轮讨论质量不足时,自动加一轮反驳。
  • 最终报告生成前,增加事实检查 Agent。

这就是 Agent 工作流真正有意思的地方。

十二、开源时要注意什么

这个项目会涉及本地知识库、API key、运行日志,所以开源时要非常小心。

我在 .gitignore 里默认排除了几类内容:

  • .env:真实 API key。
  • knowledge/**/*.md:本地书籍、论文、长文。
  • logs/**:运行报告。
  • vector_db/chroma/**:本地向量索引。
  • __pycache__/.pytest_cache/ 等临时文件。

可以提交到 GitHub 的通常是:

  • 代码。
  • README。
  • agents/*.yaml
  • councils/*.yaml
  • configs/agent_llms.json
  • knowledge/README.md
  • .gitkeep 占位文件。

尤其是 knowledge/ 目录要谨慎。

如果里面放了版权书籍、论文全文、私人资料或付费内容,就不应该上传到公开仓库。开源项目可以展示目录结构和使用方式,但不应该把不适合公开的资料一起传上去。

十三、这个项目对我的意义

对我来说,agent_roundtable 不只是一个玩具项目。

它把几个我一直想练的方向连在了一起:

  • AI Agent。
  • 多智能体协作。
  • RAG 知识库。
  • Tool Use。
  • 本地工作流。
  • 模型配置管理。
  • Markdown 报告生成。
  • 面向真实使用的 UI。

它也很适合继续扩展。

以后我可以给宏观经济、投资、AI、历史、哲学、玄学、编程等不同主题分别建立专家系统。每个专家都有自己的资料库、角色卡和模型配置。用户只需要输入问题,就可以让不同专家围绕同一个主题讨论。

这比单纯写几个 prompt 更像一个系统。

这个项目目前完全用 Python 实现,更偏研究与实验阶段。如果未来要把它做成面向用户的产品,语言选择会变成另一个问题,我在 《AI Agent 用什么语言:Python、TypeScript 与下一代产品工程》 里展开过这个讨论。

我现在越来越觉得,未来很多 AI 应用不是“一个聊天框解决一切”,而是由多个角色、工具、知识库和工作流组合起来。

agent_roundtable 就是我对这个方向的一次实践。

常见问题

agent_roundtable 是什么?

它是一个本地运行的多 Agent 专家圆桌项目。你给定一个主题,系统会请几位不同方向的专家 Agent 轮流发言,主持人负责追问、串联和总结,最后把整场讨论保存成一份 Markdown 报告。它支持命令行和本地 Streamlit UI 两种方式,每个 Agent 可以单独配置 provider、模型和 API key 环境变量。

为什么用多 Agent,而不是一个超级 Agent?

现实中的复杂判断本来就不是一个声音完成的。多 Agent 的好处是每个 Agent 都有自己的角色卡、知识范围、说话风格和盲点,讨论时会从不同方向切入,再由主持人串联。这比写一个超长 prompt 更稳,也更容易扩展。

没有 API key 也能运行吗?

可以。项目支持 --mock 模式,在没有 API key 时先跑通完整流程;RAG 检索也默认优先支持 keyword 方式,不需要额外的 embedding API key,适合本地测试和入门。

这个项目接入 MCP 了吗?

目前还没有。agent_roundtable 当前重点是本地多 Agent 圆桌、RAG 和报告生成,MCPTool Use 是很自然的下一步,项目为后续接入预留了接口空间,但还不是核心实现。

开源时如何避免泄露 API key 和私有资料?

真实 API key 只放在 .env,配置文件里只写 api_key_env 变量名,不写 key 本身。.gitignore 默认排除 .envknowledge/ 下的本地资料、logs/ 运行报告和 vector_db/chroma/ 向量索引;公开仓库只提交代码、README、角色卡、configs/agent_llms.json 和占位文件。

参考来源

Share

分享这篇文章