第 7 篇
工程技术
管理 API 与 MCP 如何共用应用层
结合实际开发项目,讨论管理 API 与 MCP 如何共用应用层,说明设计理由、关键源码、验证方法及适用边界。
本文目录 · 7 节
本文属于 Memory Center:AI 编程上下文与记忆系统工程实践,第 07 篇,位于“服务架构与项目边界”模块。案例背景统一采用实际开发项目;复现步骤使用脱敏教学样例,不代表特定生产事故。
从实际问题出发
同一个检索能力同时供管理页和 AI 工具使用。如果两边各写一套查询、权限和来源拼装,界面显示的结果很快会与模型拿到的结果不同。共享应用层用于约束这种语义分叉。
入口只处理自己的协议
HTTP 参数、MCP schema 和页面交互不同,但应传入同一类受控请求。身份校验不能仅靠界面隐藏按钮;查询模式、来源引用和错误边界应该由共享用例统一定义。

图中展示的是本篇关注的职责和顺序。正常流程之外,还要结合下面的源码与实验检查失败分支;它不是对某次线上调用的运行时追踪。
共享不等于一个巨型服务类
应用层组合存储、检索和授权,不应把所有 SQL、解析算法和显示文案塞在一起。可选模型失败时,应由对应领域返回诊断,再由用例决定如何表达部分结果。共享的重点是业务语义,不是强迫所有返回格式完全相同。
关键源码与阅读方法
源码基线为 Memory Center 6e90553(文档标注 5.0.0b24)。定位:memory_center/platform/application.py,函数 lookup,起始行 45。
以下为源码节选,省略后续分支;不能作为独立脚本执行。
def lookup(self, actor, workspace_id, query, mode='hybrid', limit=10, session_id=''):
workspace = self.access.scope(actor, workspace_id)
if session_id:
session = self.access.owned(actor, 'session', session_id, workspace_id)
if session['status'] != 'active':
raise CatalogError('SESSION_CLOSED', '会话已关闭')
if mode in {'symbol', 'callers', 'callees', 'context'}:
from memory_center.core.orchestrator.query import (
memory_callees,
memory_callers,
memory_context,
memory_symbol,
)
_, index = self.indexed(actor, workspace_id)
methods = {'symbol': memory_symbol, 'callers': memory_callers, 'callees': memory_callees, 'context': memory_context}
generic = query_code_graph(index['workspace_file'], query, mode, limit)
if mode == 'context' and generic and any(s['language'] == 'java' for s in generic['symbols']):
generic = None
if generic is not None:
result = generic
for symbol in [*result.get('symbols', []), *[e['symbol'] for e in result.get('chain', [])]]:
symbol['freshness'] = 'CURRENT' if symbol_fresh(workspace['root'], symbol) else 'STALE'
elif mode in {'symbol', 'callers', 'callees'}:
result = methods[mode](index['workspace_file'], query, limit=min(limit, 50), view='minimal')
else:
result = memory_context(index['workspace_file'], query, view='minimal')
result['workspace_id'] = workspace_id
result['generation'] = index['generation']
else:
result = self.retrieval.search(workspace, actor, query, mode, limit)
# 源码命中实时核对哈希,只核对有界候选,不重建索引。
for item in result.get('items', []):
source = item['source']
if source['kind'] == 'code':
path = Path(workspace['root']) / source['path']
try:
阅读时先找输入由谁提供,再区分纯计算、读取和写入;遇到异常或提前返回,追问调用方会得到什么,以及已有状态是否仍然有效。上面的代码只证明展示范围内的实现,跨模块行为应继续查看调用处和相应测试。
用一个小实验核对设计
建议在独立临时目录和隔离数据中操作,使用虚构的接口、文档与项目名称。
- 用相同凭据从两个入口提出相同查询。
- 对比项目范围、命中来源和错误码。
- 撤销权限后重试。
**要核对的结果:**入口格式允许不同,但授权结果和来源边界应保持一致。
可把观察记录为下表;没有执行的项写“未执行”,不能用设计预期冒充实测结果。
| 核对项 | 应保留的证据 |
|---|---|
| 使用条件 | 源码版本、配置、输入与项目范围 |
| 正常行为 | 实际返回、来源位置或状态变化 |
| 关键失败分支 | 错误码、可见结果与原状态是否保留 |
| 结论范围 | 已覆盖、未覆盖和需要进一步验证的条件 |
适用边界与继续阅读
本篇以静态源码与项目设计为依据,给出可执行的核对方法,未据此宣称已经完成新的性能或生产环境测试。不同版本的入口、默认值和底层实现可能变化,应先核对当前合同,再把方法用于自己的实际开发项目。
理解这一节后,可以回到专题总导航,沿同一模块继续阅读;顺序学习时使用专栏内的上一篇和下一篇。涉及具体技术选择,应连同本篇的代价与限制一起采用。