loading…
Search for a command to run...
loading…
Enables personalized discovery of crypto news, trending topics, and project insights from the Followin platform with intelligent search, content normalization,
Enables personalized discovery of crypto news, trending topics, and project insights from the Followin platform with intelligent search, content normalization, and recommendation explanations.
这个项目可以理解成一条面向 crypto 资讯场景的事件级推荐原型:
Followin API + adapters.py 拉取原始内容normalizer.py 把原始内容标准化成结构化 ContentItemservice.py 在 get_personal_feed 里先做显式多路召回,再做 semantic supplementclustering.py 把多条内容并成同一事件的 EventClusterranking.py 用多信号 heuristic ranker + MMR rerank 生成个性化 feed一句话总结:
一个面向 crypto 资讯场景的 Followin MCP 原型:将原始内容标准化成结构化 item,再通过多路召回、语义补召回、事件聚类和个性化排序,产出面向用户的事件级 feed。
followin_mcp/
Python 包入口followin_mcp/core/
核心业务逻辑:adapter、model、normalizer、ranking、servicefollowin_mcp/mcp/
MCP server 入口followin_mcp/demo/
测试 agent 和 Web demoscripts/start_dev.sh
本地一键启动脚本web/
前端静态资源followin_mcp/core/adapters.py
Followin API 适配层followin_mcp/core/models.py
数据模型followin_mcp/core/taxonomy_rules.py
taxonomy / 规则配置followin_mcp/core/normalizer.py
原始内容标准化、实体抽取、事件类型识别followin_mcp/core/clustering.py
事件聚类followin_mcp/core/ranking.py
用户推荐排序与解释followin_mcp/core/semantic_recall.py
embedding 建索引、语义召回、item 相似度followin_mcp/core/service.py
面向 MCP / 应用层的服务入口sequenceDiagram
participant U as MCP client / agent
participant M as mcp/server.py
participant S as service.py
participant A as adapters.py
participant F as Followin API
participant N as normalizer.py
participant SR as semantic_recall.py
participant C as clustering.py
participant R as ranking.py
U->>M: call tool
M->>S: get_latest / search / get_personal_feed ...
S->>A: fetch raw content
A->>F: HTTP request
F-->>A: raw payload
A-->>S: raw items
loop per raw item
S->>N: normalize(raw)
N-->>S: ContentItem\nentities / event_type / scores
end
S->>SR: enqueue normalized items
SR-->>S: background indexing
opt personal feed / semantic supplement
S->>SR: recall(query, candidate pool)
SR-->>S: semantic candidates / similarity
end
opt personal feed
S->>C: cluster_same_event(items)
Note over C: uses item embedding similarity
C-->>S: EventCluster list
S->>R: rank_for_user(user, clusters)
Note over R: uses semantic_match_score
R-->>S: ranked clusters
end
S-->>M: tool payload
M-->>U: MCP response
mcp/server.pyservice.py 调用ContentItem / EventCluster 序列化成 MCP 返回结构service.py -> adapters.pyget_latest_headlines / get_project_feed / get_project_opinions / get_trending_topics
直接透传上游分页能力get_trending_feeds / search_content
直接返回当前快照结果get_personal_feed
会先做显式多路召回和 semantic supplement,再走事件聚类和个性化排序normalizer.pynormalize(raw) 把单条原始内容转成 ContentItemprojects / tokens / chains / topicsentity_sourcesentity_confidence(命中方式强度)event_typecredibility_score(来源可信程度)importance_score(预定规则计算)ContentItemservice.py 在 personal feed 里会先做显式多路召回:latesttrendingprojectsearchitem.id 去重clustering.pyContentItem 列表EventCluster 列表ranking.pyEventClusterimportance_scorefreshness_scorefollow_affinity_scoreinterest_match_scoresemantic_match_scoresource_quality_scorerisk_boost_scoremute_penaltysemantic_recall.pyenqueue 到异步 embedding workersemantic_index.dbservice.py 在 personal feed 里基于当前 query 和候选池做 query-aware semantic recall / semantic supplementclustering.py 把 item embedding similarity 作为聚类信号之一ranking.py 通过 semantic_match_score 把语义匹配信号带入最终排序get_personal_feed 是当前唯一会话化的 feed toolservice.py 内部维护 FeedSessionState,主要保存:pending_clustersdelivered_event_idsdelivered_item_idssource_cursorsranked_clustersitemsnext_cursorhas_morepending_clusterspending_clusters 头部取前 max_items 个 clusterpending_clusters当前这套 MCP tools 可以分成两类:
get_latest_headlinesget_trending_feedsget_project_feedget_project_opinionsget_trending_topicssearch_contentget_personal_feed内容查询工具默认保持无状态:
get_latest_headlines / get_project_feed / get_project_opinions / get_trending_topicsget_trending_feeds / search_contentget_personal_feed 是当前唯一的状态化 tool:
service.py 会维护短生命周期的 FeedSessionStatefeed session cursorpending_clustersdelivered_event_idsdelivered_item_idssource_cursorspending_clusters职责边界大致是:
当前分页语义:
get_latest_headlines / get_project_feed / get_project_opinions / get_trending_topicsget_personal_feednext_cursor 和 has_morecursor 的语义是 feed session continuation,而不是普通列表翻页FastMCP)strong / medium / weakcredibility_score 主要依赖上游提供的 source type / metadata;受数据边界限制,还没有更细的 source-level reliability 和 multi-source verificationsemantic_match_score,但主体仍是人工特征加权的 heuristic linear ranker,而不是 learned-to-rankget_latest_headlinesget_trending_feedsget_project_feedget_project_opinionsget_trending_topicssearch_contentget_personal_feed如果你想更直观地测试“随机用户画像 + 多轮对话”,可以启动一个 Web demo:
python3 -m followin_mcp.demo.webapp
或者安装后:
followin-mcp-web
然后打开:
http://127.0.0.1:8000
这个 demo 支持:
next_cursor 上下文运行前请确保 .env 中已经配置:
FOLLOWIN_API_KEY=your_api_key
OPENAI_API_KEY=your_openai_api_key
当前已经把以下能力暴露成 MCP tools:
get_latest_headlinesget_trending_feedsget_project_feedget_project_opinionsget_trending_topicssearch_contentget_personal_feed启动方式:
python3 -m followin_mcp.mcp.server
或者安装后使用:
followin-mcp-server
如果你想把当前对话 agent 作为 ACP stdio agent 暴露给支持 ACP 的客户端,可以启动:
python3 -m followin_mcp.acp.server
或者安装后使用:
followin-acp-agent
当前 ACP wrapper 直接复用 FollowinChatAgent:
FollowinChatAgent 会话prompt() 内部调用现有的 chat_stream()FOLLOWIN_ACP_PROFILE_JSON,未配置时使用一个内置默认画像如果你要接到本地 acpx / OpenClaw,~/.acpx/config.json 可以先用最小配置:
{
"agents": {
"followin": {
"command": "/path/to/python",
"args": ["-m", "followin_mcp.acp.server"],
"cwd": "/path/to/followin-mcp"
}
}
}
这里不需要额外写 env:
followin_mcp.acp.server 启动时已经会 load_dotenv()cwd 指到项目根目录,就会读取仓库里的 .envДобавь это в claude_desktop_config.json и перезапусти Claude Desktop.
{
"mcpServers": {
"followin-mcp": {
"command": "npx",
"args": []
}
}
}