这是一份针对 周末挑战:慷慨版 的提交
别只问 AI,把答案分享出来。
AI 是软件开发的真正倍增器,也是快速解决技术问题的理想伙伴。但所有这些知识 — — 我们自己留着,或者说,我们失去了它们。
故事总是止步于此。
提问 → 回答 → 问题解决 — — 对话沉入聊天记录,消失不见。
然后另一个人遇到了完全相同的难题。同样的循环:提问 → 回答 → 问题解决 — — 对话沉入聊天记录,消失不见。
这就是问题所在。不是 AI 不能两次解决同一问题 — — 而是一个可行的解决方案已经存在某处:有人已经调查、测试、找到了修复方法,并进行了足够详细的对话以便正确解释。
为什么那份知识会在会话结束时蒸发?为什么反复问同样的问题 — — 浪费已经花费的电力、水和时间 — — 而不是循环利用这些原始材料?
这就是 Shared Knowledge MCP 的核心思想。
我构建的
Shared Knowledge 是一个 MCP 服务器,它将 AI 对话中的解决方案转化为一篇建议的 Markdown 文章,然后转化为提交给人工审查的 GitHub Pull Request。合并后,该贡献会被发布到文档站点,并生成一个由 ElevenLabs 制作的音频版本。
该项目将已解决的问题转化为可重复使用的社区知识 — — 但前提是用户必须明确决定分享它。
对话本身保持严格私密。MCP 服务器仅提取相关解决方案,将其结构化为独立的英文 Markdown 文章,进行验证,并在 GitHub 上打开 Pull Request。
没有任何内容会自动发布。人工审查该贡献,并决定它是否属于共享知识库。只有在 PR 被合并后,文章才会发布到公开文档站点,进而触发其音频版本的生成。
流程被刻意设计得极其简洁:
AI 对话 → 明确分享 → MCP → Markdown → Pull Request → 人工审查 → 合并 → 文档 + 音频
唯一重要的边界是人工审查。MCP 可以结构化知识并准备贡献 — — 但它不能代表任何人决定什么值得成为公共知识。
演示
公开的文档站点已经上线:
站点目前收录了四篇已发布的文章,每篇都配有自动生成的音频版本。
为了证明这套系统确实能在不同客户端上跑通——不走捷径,没有任何硬编码——我通过两条截然不同的路径测试了 publish_knowledge。
直接执行脚本
第一篇通过 Shared Knowledge 发布的贡献,是以一个真实 Pull Request 的形式提交的:可选依赖在导入本身并非可选时,导致导入链崩溃。
这个 PR 端到端地走通了整个流程:
- 用 AI 助手解决了一个真实的技术问题(
pyproject.toml中的一个可选依赖导致导入链崩溃); - 明确地把它转化为一篇结构化的 Markdown 文章(包含章节、元数据和标签);
- 由 MCP 服务器自动校验,并创建 PR;
- GitHub Copilot 自动审查,指出了 YAML 格式和标题层面的问题;
- 修复之后合并进
main分支; - 合并完成后,再用 ElevenLabs 生成音频版本,发布到文档站点。
第一个 PR 同时也是一份实实在在的善意:有人愿意花时间,把自己的修复沉淀成一份资源,让日后每一个撞上同一堵墙的开发者都能直接复用。
对话式 Agent 模式
接下来,我换用一个真实的 AI 客户端——在 Codespace 中以 Agent 模式运行的 GitHub Copilot Chat。
这一次,助手自发地先通过 search_knowledge 查询现有知识库、确认没有重复内容,然后才决定发布:PR #2。
该行为在 MCP 服务器中任何地方都没有硬编码:服务器仅提供工具,而调用的助手决定如何使用它们。共享知识不是绑定到单一模型的封闭式 AI 应用——它是一个用于共享知识的开放 MCP 接口。
代码
完整项目在 GitHub 上开源:
共享知识 MCP
将已解决的问题转化为共享知识。 不要只求答案。把答案贡献出来。
共享知识 MCP 是一个围绕 AI 辅助问题解决构建的社区驱动知识库。它是一个 MCP (Model Context Protocol) 服务器,允许任何 MCP 兼容的 AI 助手(Claude、ChatGPT/Codex、Cursor 等)在从头解决问题之前先 搜索 共享知识库,并将新解决的问题以社区知识文章的形式 发布 —— 作为 GitHub Pull Request 提交供人工审核,然后作为静态文档网站发布。
核心原则:
对话保持私密。从中提取的知识可以被共享。 共享始终是明确且自愿的 —— 未经用户请求,绝不会发布任何内容。
Private conversation
↓
AI-assisted solution
↓
User chooses to share
↓
Caller structures the article (guidelines prompt)
↓
GitHub Pull Request
↓
Human review
↓
Shared knowledge base
↓
Available该仓库包含 MCP 服务器、知识文章、Astro/Starlight 静态站点、GitHub Actions 工作流、测试套件以及文档。
我是如何构建它的
周末 MVP 的务实做法
在周末独立完成一个概念验证(PoC)会带来严格的限制。
我本来可以设计一个 PostgreSQL 数据库,加入带嵌入的向量搜索,构建一个完整的身份验证系统,并交付一个管理后台。
我没有这样做。
就此 MVP 而言:
- GitHub 是唯一的事实来源。 知识库采用纯 Markdown。Git 已经处理版本控制、历史、分支、差异和代码审查——没有必要重新实现这些功能。
- Astro + Starlight 负责渲染。 无需全天候运行应用服务器仅为了提供已经由人工审批通过的静态内容。
- 搜索保持故意简单。 基于字段权重的关键词搜索在此规模下已经足够。对于只有四篇文章的情况,添加向量数据库不会让系统变得更智能——它只会为原型增加不必要的重量。
三个范围狭窄的 MCP 工具
服务器公开三个故意简单的工具:
-
search_knowledge— 使用基于字段权重的排名搜索知识库。 -
get_knowledge— 安全地获取特定文章(防止路径遍历)。 -
publish_knowledge— 验证结构并打开一个 GitHub Pull Request。
今日使用方法
任何符合 stdio 兼容的 MCP 客户端都可以连接到服务器——Claude Desktop、带有 GitHub Copilot Chat(Agent 模式)的 VS Code 以及其他客户端。一个最小的 .vscode/mcp.json 就足够了:
{
"servers": {
"shared-knowledge": {
"type": "stdio",
"command": "${workspaceFolder}/.venv/bin/python3",
"args": ["${workspaceFolder}/server.py"],
"env": {
"GITHUB_TOKEN": "${env:GITHUB_TOKEN}",
"GITHUB_REPO": "pcescato/shared-knowledge",
"KNOWLEDGE_DIR": "${workspaceFolder}/knowledge"
}
}
}
}
克隆仓库,pip install -e .,设置你自己的 GITHUB_TOKEN,指向你自己的知识仓库——任何支持 MCP 的助手都可以开始读取并向基础仓库贡献,并在你自己的 GitHub 身份下打开拉取请求。
架构转折:互操作性胜过奖项类别
在我的第一个实现中,MCP 服务器直接内部调用 Gemini,将对话摘要转化为结构化文章。虽然有效——但这违背了 MCP 的核心理念:服务器正在变成一个与特定 AI 厂商绑定的单体应用。
于是我在构建过程中重新设计了架构。
服务器现在公开一个 MCP 提示词(knowledge_article_guidelines),其中列出了结构化规则——英文输出,强制要求 ## Problem / ## Solution 节,以及受控的类别和标签词汇表。调用的助手使用 其自身的模型 来构建内容,而 publish_knowledge 仅负责验证和发布。
客户端是运行在 Claude、GPT、Gemini 还是本地模型上都无关紧要。
这一选择为挑战带来了实际成本:我有意识地将 Gemini 从关键路径中移除,因而放弃了获得 最佳使用 Google AI 奖项的资格。但我宁愿提交一个架构忠于互操作性理念的项目,也不愿为了勾选奖项类别而强行引入依赖。
多智能体协作:践行所宣扬的
这个项目有一个很好的闭环:它正是按照它所主张的范式来构建的。
与其依赖单一助手,不如在人类监督下让多个 AI 环境协作,各自承担特定角色来开发该仓库:
- FreeBuff + GLM 5.3 —— 通过七个顺序的、封闭的批次推动开发,每个批次都有明确的守则(“不要实现...”、“仅执行...”),以防止范围漂移,并避免一个组件的更改破坏另一个组件。
- GitHub Copilot CLI + Haiku 4.5 —— 作为独立的代码审查者,检查 PR 并运行关键检查。
- OpenCode + Big Pickle —— 负责本地代码迭代、重构、快速边缘情况修复以及错误消除。
真实世界中的真实错误
周末的 PoC 快速提醒我们:架构图并不等同于现实。
那个根本不存在的 AI 生成 bug
Copilot CLI 的一次自动审查报告了一个极具说服力的 GitHub 身份验证 bug——连代码片段和行号都一应俱全。动手改动之前我先核实了一下:那一行,以及它所描述的那段代码,在仓库里压根就不存在。这倒是个有益的提醒:AI 审查确实有价值,但仍需要人来替它核对作业。
ElevenLabs Voice Library 的陷阱
音频生成屡屡失败,报出的 invalid_uid 错误极具误导性。我在网页界面上挑选的那个声音属于共享的 Voice Library(语音库),而免费账户无法通过 API 访问它。把声音添加到“My Voices”之后,第二个问题又浮出水面:GitHub Actions 里一个值为空的 ELEVENLABS_MODEL_ID 变量悄悄覆盖了代码中的默认值——因为 os.environ.get() 只有在键不存在时才会回退到默认值,如果键存在但被设成了空字符串,它并不会这么做。
手动改坏状态的问题
本地测试时,我删掉了一个 MP3 文件,却没有相应更新 .audio_manifest.json。下一次 CI 运行时,工作流读取清单文件,据此认定音频已是最新版本。代码本身没有毛病——是我手动改动文件,把系统状态弄得不一致了。
接下来要做的事
改进音频生成
通过 ElevenLabs 进行的音频生成严格安排在人工审查与合并之后。未经审查的 Pull Request 绝不会生成任何音频。
话虽如此,回听生成的 MP3 时,一个有趣的工程现实浮出了水面:对人眼阅读和 Git diff 都极为友好的格式,未必适合文字转语音引擎。Markdown 是为 Git 而生的,不是为语音而生的。
TTS 引擎朗读原始 Markdown 时,章节标题(## Problem、## Context)会与后面的正文直接连在一起,中间没有真正的韵律停顿。最终生成的音频既缺少换气间隙,也缺少叙事结构。
音频流水线需要一个中间的脚本处理环节:
Validated Markdown article
↓
Structure parser
↓
Narration script (pauses & transition cues)
↓
ElevenLabs API
↓
Final MP3 file
与其直接把原始 Markdown 语法发送到 ElevenLabs,不如让流程把编辑结构转化为实际的旁白脚本。Markdown 文章仍是唯一的事实来源——音频成为专门构建的派生格式。
明显的诱惑是把这变成一个完整的社区平台——投票、评论、向量搜索、仪表盘。
我认为这不是正确的优先级。首要的是验证循环本身的简洁性:有人解决问题 → 决定把答案贡献回去 → 其他人得以重复使用。
朝着真正可用的产品迈进的自然下一步是通过 Streamable HTTP 远程托管 MCP 服务器——无需本地安装,只需在你已使用的任何助手中添加一个 URL。
但循环的运作不需要投票、仪表盘或更大的模型。它需要有人愿意把答案贡献回去,以及另有人愿意足够信任它去阅读。
奖项类别
最佳 ElevenLabs 使用
Shared Knowledge 使用 ElevenLabs 将经过验证的技术方案以音频形式提供。音频生成与 MCP 服务器解耦,仅在 Pull Request 合并后在 GitHub Actions 中独占运行——这确保只有经过审查、批准的内容才会被合成语音。
未参加 Best Use of Google AI 评选:上述架构转变有意将 Gemini 从关键路径中移除,以支持模型无关的结构。这是一次有意的权衡,而非疏忽。

