产品上下文层

PCL是一个为AI编程代理提供持久化、结构化产品知识的工具,通过混合搜索和实时索引帮助代理按需获取产品文档。

  • by MichaelGorski
  • TypeScript
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 MichaelGorski/pcl-mcp

使用说明

PCL——产品上下文层

为AI编码代理提供关于您产品的持久、结构化的知识。

npx pcl-mcp init

PCL不会在每次会议上重新解释你的角色、旅程和架构决策,而是通过MCP按需提供服务。任何代理(Claude Code、Cursor、Windsurf)在需要时都会准确地查询它需要什么。


为什么是PCL?

没有PCL,每个编码会话都从头开始:

  • 除非您将产品文档粘贴到提示中,否则代理商无法找到您的产品文档
  • 上下文窗口因无关信息而变得臃肿
  • 你每次都要重新解释角色、业务规则和规范
  • 没有护栏——代理人做出的假设违反了你的商业规则

使用PCL,代理商按需加载产品知识:

  • 渐进式披露——会话开始成本约600个代币(产品摘要+关键规则)
  • 混合搜索(BM25+语义)无需您引导即可找到正确的上下文
  • 在文件保存时实时重新索引——编辑规范,代理会立即看到它
  • 结构化Zod模式——代理每次都能获得可预测、可解析的前端内容

具体用例

你问你的经纪人: “构建结账流程”

没有PCL: 您将您的计费规则文档、角色文件、行程图和规范粘贴到聊天中。在代理编写一行代码之前,需要4000个令牌。下一节课,你再做一次。

使用PCL: 代理在会话开始时自动加载关键计费规则(约200个令牌)。当它启动结账功能时,它会拉取相关角色,获取旅程步骤,并检查规范的验收标准——所有这些都是按需的,只有需要的。每次会话,自动。


快速开始

npm install pcl-mcp
npx pcl init            # prompts before adding example files, sets up CLAUDE.md
# add MCP config (see Agent Configuration below), then start a new agent session

堆栈

层 技术 为什么
协议 MCP(stdio) 通用——适用于所有主要代理
存储 SQLite+FTS5 零基础设施,git友好,离线
关键字搜索 BM25通过FTS5(标题加权10×) 精确术语、ID、专有名词在同类中最好
语义搜索 all-mpnet-base-v2 (本地,768d) 质量高于MiniLM,API成本为零,约3ms/doc
嵌入策略 拆分正文+标题嵌入 分离正文和标题匹配的语义通道
混合融合 自适应RRF(语料库大小感知k) 在小型和大型语料库上都有更好的召回率
分数过滤 15%的差距阈值 防止低质量的尾部结果浮出水面
交叉引用 自动前端链接解析 将相关文件自动拉入结果
验证 Zod模式 代理获得可预测、可解析的前端内容
文件查看 Chokidar v4 保存时实时重新索引

先决条件

Node.js>=22 (必填——PCL使用现代节点API)


安装

npm install pcl-mcp
npx pcl init            # creates ./product with templates

也可以在GitHub软件包上找到 @michaelgorski/pcl-mcp.


导入现有文档

如果您的仓库中已经有markdown文档,PCL可以自动扫描、分类和导入它:

npx pcl init --scan         # scan + import existing docs, then scaffold remaining templates
npx pcl init --scan-only    # scan + import only, skip template scaffolding

扫描仪:

  • 步行至您的仓库 .md 文件(跳过 node_modules, dist, .git等等)
  • 按目录名、文件名、frontmatter键和内容模式对每个文件进行分类
  • 使用适当的frontmatter将匹配的文件转换为PCL格式
  • 将它们复制到 product/ 正确类别下的文件夹
  • 跳过已导入文件的类别(无重复模板)

支持的分类: 人格面具, 旅程, 规格, 决定, 领域, 产品


代理配置

可与任何MCP兼容的代理配合使用。配置示例如下。

克劳德代码-- .claude/mcp.json

{
  "mcpServers": {
    "pcl": {
      "command": "node",
      "args": ["./node_modules/pcl-mcp/dist/src/server.js"]
    }
  }
}

光标-- settings.json

"mcp.servers": {
  "pcl": {
    "command": "npx",
    "args": ["pcl-mcp", "serve"]
  }
}

Windsurf——MCP配置

{
  "mcpServers": {
    "pcl": {
      "command": "npx",
      "args": ["pcl-mcp", "serve"]
    }
  }
}

文件结构

/product
  product.md              ← north star doc (required)
  personas/
    001-max.md            ← one persona per file
  journeys/
    001-onboarding.md     ← one user journey per file
  specs/
    001-auth-flow.md      ← feature specs with acceptance criteria
  decisions/
    001-use-nextjs.md     ← architecture decision records (ADRs)
  domain/
    core-rules.md         ← business rules agents must never violate
  .pcl.db                 ← SQLite index (auto-generated, gitignore this)

代理可用的工具

工具 参数 描述
pcl_product_summary -- 加载产品北极星文档。会话开始时呼叫。
pcl_get_persona id 按ID获取用户角色。在任何面向用户的功能之前调用。
pcl_get_journey id 按ID获取用户旅程,包括详细步骤。
pcl_get_spec id 按ID获取功能规格,包括验收标准
pcl_get_decision id 按ID获取架构决策记录(ADR)
pcl_get_domain id 或 "*critical" 按ID获取域规则。Pass "*critical" 加载所有关键规则。
pcl_list type: "personas" "journeys"
pcl_search query, mode? ("hybrid" "semantic"
pcl_related id, top_k? 查找与给定文件ID语义相关的文件

提示和资源

除了工具,PCL还公开了MCP提示和资源:

提示: session-start --返回产品摘要+所有关键域规则。代理可以在每个编码会话开始时调用此函数,以便在不加载每个文件的情况下定位自己。

资源: pcl://files/{type}/{id} --每个索引文件都可以作为MCP资源使用。代理可以直接通过资源URI浏览和读取单个文件(例如。, pcl://files/persona/example-user).


混合搜索的工作原理

PCL运行三个并行检索信号,并将其与往复式秩融合融合:

query: "what does Max find frustrating about onboarding"

BM25 (FTS5, title-weighted 10×):
  → persona-max, journey-onboarding, spec-magic-link
  ↓ ranked by bm25(title=10×, body=1×) — exact terms, IDs, proper nouns

Semantic — body embedding (all-mpnet-base-v2, 768d):
  → journey-onboarding, persona-max, domain-core-rules
  ↓ cosine similarity on full-text embedding

Semantic — title embedding (all-mpnet-base-v2, 768d):
  → persona-max, journey-onboarding, spec-onboarding-ux
  ↓ cosine similarity on title + summary embedding

Adaptive RRF (k = corpus_size / 10):
  score(d) = Σ 1 / (k + rank(d))   fused across all three lists

Score gap filter (15% threshold):
  Drops results below 0.15 × top_score — removes noise

Cross-reference resolution:
  journey-onboarding.frontmatter.persona = "max"
  → auto-includes persona-max even if it ranked outside top-k

Result:  1. journey-onboarding  (0.94)
         2. persona-max         (0.87)
         3. spec-onboarding-ux  (0.71)

为什么要拆分嵌入? 正文和标题具有不同的语义信号。一个类似的查询 “结账角色” 即使其正文内容主要是人口统计数据,也应按标题匹配人物角色文件。分别对它们进行索引,为融合步骤提供了两个不同的语义通道,而不是一个稀释的通道。

为什么选择自适应RRF k? 修复了k=60的小语料库(10-20个文件)的平滑排名问题。语料库感知k对小集合进行缩减,使强匹配与弱匹配分开。


测试和基准

PCL附带了完整的测试套件和多维基准框架。

测试

npm test            # run all tests (vitest)
npm run test:watch  # watch mode

六个测试套件覆盖了整个堆栈:

套房 保险范围
db.test.ts SQLite操作、FTS5查询、嵌入存储
embeddings.test.ts 嵌入生成、缓存命中、维度检查
indexer.test.ts 文件发现、模式提取、更改检测
schemas.test.ts 所有文件类型的Zod frontmatter验证
search.test.ts 混合搜索、RRF、多跳分解、交叉引用
tools.test.ts MCP工具处理程序、响应格式、错误路径

基准测试

npm run bench           # all benchmarks
npm run bench:perf      # latency benchmarks (search + embedding speed)
npm run bench:quality   # search quality: Precision@k, Recall@k, NDCG, MRR
npm run bench:tokens    # token efficiency across search modes
npm run bench:ablation  # hybrid vs keyword-only vs semantic-only comparison
npm run bench:ai        # Claude-judged result quality (requires ANTHROPIC_API_KEY)
npm run bench:report    # generate markdown report from results
套房 措施
性能 搜索+嵌入延迟(p50/p95)
搜索质量 Precision@k, Recall@k标记语料库上的NDCG、MRR
令牌效率 跨搜索模式每次查询消耗的令牌
消融 质量增量:混合vs仅关键字vs仅语义
人工智能质量 克劳德对top-k结果的相关性评分进行了判断

人工工作流

这个系统的好坏取决于你投入的东西。纪律:

  • 产品决策? → 写a decisions/ ADR(5分钟)
  • 正在计划新功能? → 写a specs/ 先文件,再编码
  • 用户研究或反馈? → 更新角色 anti_patterns 或 jobs_to_be_done
  • 业务规则更改? → 更新 domain/ 先编码
  • 发现新用户旅程? → 添加 journeys/

代理人做剩下的事。


微笑

product/.pcl.db      # SQLite index — auto-regenerated

许可证

麻省理工学院