ReviewOps MCP–通过MCP+LLM(Self-Hosted MVP)提供反馈分析的平台
审查运营MCP -分析组织文本反馈的微服务平台。项目帮助获得 结构化的负面原因与确认(引用)进行全文搜索,并按标题和地区形成比较分析。这些工具可以通过REST API或 MCP(模型上下文协议) 与LLM代理集成
______________________________________________________________________
机会
工具(REST API+MCP)
- 手册:顶级类别和过滤区域。
- 评论全文搜索俄罗斯
tsvector相关片段。 - 负面见解:按类别/地区+引用示例+改进建议列出的负面原因。
- 领导者:按标题(和地区)分类的组织中的领导者和反领导者,评论次数阈值。
- 组织钻取:审查特定组织的底片
org_key. - 比较:两个区域的交叉点和负原因的差异比较。
LLM层(本地或通过代理)
- 局部:
llama.cpp serverGGUF模型(OpenAI Compatible)/v1/chat/completions). - 远程:LLM Gateway代理OpenAI Compatible Endpoint(例如Proxyapi)中的查询。
- Orchestrator使用LLM 点 (Summary/Compare),原因计算和证据选择在数据库中以确定性的方式进行(以降低幻觉的风险)。
工程性能
- MCP优先:工具可用于MCP客户端/代理。
- 后备方案:Orchestrator通过MCP调用工具,并在必要时切换到直接REST API。
- 可观测性:活动/跟踪C
trace_idв波斯特格雷斯。 - Security(可选):JWT发行和Bearer令牌验证。
- Moderation(可选):防爆注射和秘密编辑。
______________________________________________________________________
建筑
请求/数据流(Request/Data Flow)
flowchart LR
U["User / Client"] -->|"POST /chat"| ORCH["orch: Orchestrator (LLM gateway)"]
ORCH -->|"SSE /mcp tools"| MCP["mcp: FastMCP server"]
MCP -->|"HTTP"| API["api: Analytics API (FastAPI)"]
API -->|"SQL"| DB[(db: Postgres)]
ORCH -->|"OpenAI-compatible /v1/chat/completions"| LLM["llm: llama.cpp server"]
ORCH --> LOG["logsvc: events"]
MCP --> LOG
API --> LOG
SEC["security: JWT (opt)"] -.-> ORCH
MOD["moderator: input/output (opt)"] -.-> ORCH互动逻辑:
- Orchestrator接受用户请求(
POST /chat). - 如果需要上下文/统计,Orchestrator通过MCP调用工具(
/mcp上海证券交易所 - MCP在Analytics API上代理对Tools的调用。
- Analytics API执行Postgres查询并返回结构化结果。
- Orchestrator使用工具和(必要时)LLM的结果来生成响应。
- 关键事件和查询关联记录在
logsvc/log_event沿着trace_id.
Docker Compose(Docker Compose)
┌─────────────────────────────────────┐
Client / User → │ Orchestrator (FastAPI) :9000 │
│ - routing (auto/search/...) │
│ - tool calls (MCP → fallback REST) │
│ - optional JWT auth │
│ - optional moderation │
└───────────────┬─────────────────────┘
│
│ tool calls
▼
┌───────────────────────────┐
│ MCP server (FastMCP) :8787 │
│ tools → wraps Data API │
└─────────────┬─────────────┘
│
▼
┌───────────────────────────┐
│ Data+Analytics API :8000 │
│ - search │
│ - leaders │
│ - insights │
└─────────────┬─────────────┘
│ SQL
▼
┌───────────────────────────┐
│ Postgres 16 :5432 │
│ org / rev / log_event │
└───────────────────────────┘
LLM side:
┌───────────────────────────┐ ┌───────────────────────────┐
│ LLM Gateway :8080 │ → │ llama.cpp server :8081 │
│ /v1/chat/completions │ │ (local GGUF) │
│ backend=local|proxyapi │ └───────────────────────────┘
└───────────────────────────┘
Optional:
- logsvc :9100 (event log API -> log_event)
- security :9200 (JWT mint/verify)
- moderator :9300 (input/output moderation)
- loader (one-shot) (HF parquet -> DB)______________________________________________________________________
合同和接口
编排器API
GET /health
用途:Liveness/Readiness(验证服务是否可用)。
POST /chat
用户请求的主入口点。
请求
{
"message": "string",
"mode": "auto"
}Response(目标合同)
{
"trace_id": "string",
"answer": "string",
"evidence": [
{
"source": "db",
"snippet": "string",
"meta": {
"org": "string",
"rubric": "string",
"region": "string",
"rating": 0
}
}
]
}保证:
trace_id必须关联所有关键步骤(ORCH→MCP→API→DB)并与事件匹配logsvc/log_event.answer总是字符串。evidence可能是空的;在mode="insights"如果找到数据,则最好提供证据。
合同扩展计划:
- 制度
search(相关片段的选择)和summary(简短摘要,无建议); - 噪声控制参数:
max_evidence,min_rating/a0在请求的顶层。
______________________________________________________________________
数据和电路
数据源(默认)
Loader从HuggingFace Dataset下载Parquet文件并将数据导入Postgres。
默认情况下(见下文)。 .env / docker-compose.yml):
HF_REPO=d0rj/geo-reviews-dataset-2023HF_FILE=data/train-00000-of-00001-49261e4e5a35a5a0.parquet
表格
org:组织(密钥、名称、地址、区域)a0/a1, рубрикиrub[])rev:отзыв(id,组织密钥,评级,文本,tsvector俄语)log_event:跟踪事件(traceu id、service、event、payload jsonb)
数据模型(TL;DR)
表格 rev
一行=一条评论。用于:
- 按标题/地区分列的排名,
- 全文/子字符串搜索,
- 从标题+评级阈值中提取负片。
索引:
rev_org_rating_idx-加速组织/对象和评级的过滤(见下文)。db/init.sql是真理的源泉。
注:
- 关于各栏的确切名称和类型,请参见附件一。在
db/init.sql(规范方案); - 建议在缩放时添加
created_at代用id和(可选)tsvector/FTS基础设施,如果尚未启用。
______________________________________________________________________
快速启动(Docker Compose)
要求
- Docker+Docker组合
- 为GGUF模型和数据集缓存提供足够的磁盘空间
1.克隆和环境保护
git clone https://github.com/Lin-Lini/reviewops-mcp
cd reviewops-mcp
cp .env.example .env2)LLM模式的选择
选项A:本地模型(默认)
将GGUF文件放置在路径上:
models/qwen2.5-1.5b/qwen2.5-1.5b-instruct-q4_k_m.gguf检查(或离开) .env:
LLM_BACKEND=local
LLM_MODEL=qwen2.5-1.5b选项B:通过代理远程LLM(网关)
请输入 .env:
LLM_BACKEND=proxyapi
PROXYAPI_OPENAI_BASE=https://openai.api.proxyapi.ru/v1
PROXYAPI_KEY=***secret***
PROXYAPI_MODEL=gemini/gemini-2.5-flash-lite3)提升数据库并加载数据
docker compose up -d db
docker compose run --rm loader4)服务启动
最低要求:
docker compose up -d api mcp llm orch全套(包括LogSVC、Security、Moderator):
docker compose up -d______________________________________________________________________
性能检查
- API文件:http://localhost:8000/docs
- 编排器运行状况:http://localhost:9000/health
- 日志:http://localhost:9100/events
- LLM网关运行状况:http://localhost:8080/health
______________________________________________________________________
使用
Orchestrator(主入口点)
端点:
POST http://localhost:9000/chat
身体:
{
"message": "Разбери негатив по кафе в Москве: причины, примеры, что улучшить",
"mode": "auto"
}mode:
auto(默认)search-搜索/选择相关片段insights-负面原因+引用+建议leaders领导人/反领导人compare两个区域比较
Insights(Insights):
curl -s http://localhost:9000/chat -H "Content-Type: application/json" -d '{"message":"негатив по ресторанам в Санкт-Петербурге: причины и цитаты","mode":"insights"}'Leaders(Leaders):
curl -s http://localhost:9000/chat -H "Content-Type: application/json" -d '{"message":"худшие кафе в Москве","mode":"leaders"}'比较(Compare):
curl -s http://localhost:9000/chat -H "Content-Type: application/json" -d '{"message":"сравни кафе Москва vs Санкт-Петербург","mode":"compare"}'______________________________________________________________________
MCP工具
MCP端点:
http://localhost:8787/mcp
可用的工具:
top_rubrics(n=50)top_regions(n=50)text_search(qs, n=20)negative_insights(rubric, a0=None, n_terms=20, n_samples=5, max_docs=3000)leaders_worst(rubric, a0=None, min_reviews=20, n=10)leaders_best(rubric, a0=None, min_reviews=20, n=10)org_negative_insights(org_key, n_terms=20, n_samples=5, max_docs=3000)
注意:MCP传输使用SSE。正确运行MCP客户端需要标题 Accept: text/event-stream.工具合同(专用)
top_rubrics(n: int)
返回顶部n类别的评论数。
[
{ "rubric": "string", "count": 123 }
]top_regions(n: int)
返回顶部n个区域的评论数。
[
{ "region": "string", "count": 123 }
]text_search(qs: string, n: int)
搜索文本反馈(子字符串或FTS取决于API的实现)。
[
{ "org": "string", "rubric": "string", "region": "string", "rating": 0, "text": "string" }
]negative_insights(rubric: string, a0: float, n_terms: int, n_samples: int, max_docs: int)
收集负面的原因。
参数:
a0评级阈值(例如, `
### 获取令牌
1. 指定参数 `.env`:
ROOT_API_KEY=change-me JWT_SECRET=dev-secret
2. 请求令牌:
curl -s http://localhost:9200/token -H "X-API-Key: change-me"
3. 使用令牌:
curl -s http://localhost:9000/chat -H "Content-Type: application/json" -H "Authorization: Bearer " -d '{"message":"найди отзывы про парковку","mode":"search"}'
______________________________________________________________________
## 故障排除
**LLM不在本地启动**
- 检查路径中是否存在模型文件 `models/qwen2.5-1.5b/...gguf`.
- 检查环境变量 `LLM_BACKEND=local` 和 `LOCAL_LLM_CHAT_URL`.
**`/mcp` 返回406**
- 使用MCP客户端 `Accept: text/event-stream` 上海证券交易所
**Insights/Compare运行缓慢**
- 确保加载程序已完成 `ANALYZE` (默认情况下,在init/loader中启用)。
- 检查是否有索引(见下文)。 `db/init.sql`).
**`/chat` 返回401**
- 启用 `AUTH_ENABLED=1`,但请求没有令牌发送。要么关闭AUTH,要么通过JWT `security`.
______________________________________________________________________
## 简历亮点
- 带Docker Compose环境的微服务体系结构(Fastapi+Postgres)
- MCP集成:LLM代理可通过Model Context Protocol获得分析工具
- LLM作为可替换后端:本地GGUF模型 `llama.cpp` OpenAI Compatible Endpoint(Compatible Endpoint)
- 确定性分析和数据库的证据,LLM用于摘要
- 可选子系统:AUTH(JWT)、MODERATION、Event Logging/Tracing
______________________________________________________________________
## 许可证
麻省理工学院