TencentDB Agent Memory 端口对不上:模块写 8421,部署写 8424
翻 TencentDB-Agent-Memory 这个仓库时,最容易让人对着屏幕愣一下的不是架构,是端口。
同一个知识服务,你在 MemoryKnowledge/README.md 里读到的是 8421,翻到仓库根的 INSTALL.md 端口表,写的是 8424。两处都言之凿凿,都不带「或」。如果你是先照模块 README 起服务、再照根目录文档去访问 Swagger,或者反过来,就会撞上这个数字。
先说清楚采集口径:本文的全部依据是该仓库 feat/server_team 分支(这就是它的默认分支,不是 main 也不是 master)在 2026-08-16 的快照 97f9465,我们只做了静态阅读,没有部署、没有起容器、没有调用过任何接口。下面出现的所有端口都是文件里写着的值,不是我们观察到的运行结果。
一、两个数字各自出现在哪些文件里
这件事之所以值得单写一篇,是因为它不是「某一行写错了」那么简单——两个数字各自都有一整组文件在支撑。把它们摊开列出来,问题就从「哪个是对的」变成了「你手上是哪条路径」。
写 8421 的一组,全在 MemoryKnowledge/ 这个模块目录内部:
| 文件 | 写的内容 |
|---|---|
MemoryKnowledge/README.md:6 | 默认端口 8421,API 前缀 /v3 |
MemoryKnowledge/src/config.ts:150 | port: envInt("PORT", 8421) |
MemoryKnowledge/Dockerfile:78、83 | ENV PORT=8421、EXPOSE 8421 |
MemoryKnowledge/docker-compose.yml:19 | 端口映射 ${TEAM_KNOWLEDGE_HOST_PORT:-8421}:8421 |
MemoryKnowledge/openapi.yaml 头部 | servers[0].url: http://localhost:8421/v3 |
MemoryKnowledge/src/mcp/server.ts:94-95 | KNOWLEDGE_API_URL 默认 http://localhost:8421 |
写 8424 的一组,全在模块目录之外:
| 文件 | 写的内容 |
|---|---|
INSTALL.md:58 | 端口表一行:Knowledge | 8424 | wiki / code-graph service |
INSTALL.md:91 | Swagger 地址 http://localhost:8424/docs |
deploy/global-images/.env.example:50 | KNOWLEDGE_PORT=8424 |
deploy/panel-knowledge-combined/Dockerfile:49、85 | 环境变量默认 KNOWLEDGE_PORT=8424,EXPOSE 8125 8424 |
这里只陈述差异、标明位置,不推断原因,也不由此评价什么。以我们实读的仓库状态为准:模块目录内的四处配置加规格与 MCP 默认值写 8421,仓库根安装文档与 deploy/ 下的两条部署路径写 8424。
二、变量名也不是同一个
再往下挖一层,会看到一个比数字更值得记住的细节:这两组文件读的根本不是同一个环境变量。
MemoryKnowledge/src/config.ts:150 读的是 PORT。而 KNOWLEDGE_PORT 这个名字,我们在整个 MemoryKnowledge/ 目录里 grep 不到——该模块只认 PORT。
那 KNOWLEDGE_PORT=8424 是怎么生效的?在合并镜像那条路径上,deploy/panel-knowledge-combined/start-combined.sh:100 做了一次转译,写法是 PORT="${KNOWLEDGE_PORT}"。也就是说,外层配置用 KNOWLEDGE_PORT,进到进程之前被换成模块认识的 PORT。
这条链路的意义在于:如果你直接给 MemoryKnowledge 的独立容器塞一个 KNOWLEDGE_PORT,模块侧的 config.ts 是不看这个名字的,取到的仍然是 envInt("PORT", 8421) 的默认值。反过来,走 deploy/global-images 三件套时,.env 里改的那个变量叫 KNOWLEDGE_PORT,.env.example:47-51 也明确说端口冲突时改这四个变量。
三、先判定你手上是哪条部署路径
排查这类问题,最有用的不是背下数字,而是有一个能立刻执行的判定动作。仓库里的知识服务至少有两条独立的启动路径,看你手边打开的是哪个文件就能分辨:
判定动作一:看你用的是哪份编排文件。
- 如果你起服务用的是
MemoryKnowledge/docker-compose.yml这份编排,那就是模块独立服务这条路径。它只声明一个knowledge服务,build: .,镜像名${TEAM_KNOWLEDGE_IMAGE:-team-knowledge:latest},宿主端口默认8421,卷knowledge-data:/app/data。这份文件里没有任何数据库、缓存、消息队列容器——整份只有这一个服务。此时端口看 8421 这一组。 - 如果你在
deploy/global-images/下cp .env.example .env再./start-all.sh,那是三件套路径,起的是agentmemory/memory-core、agentmemory/memory-hub、agentmemory/memory-proxy三个容器,知识服务被装在 memory-hub 这个合并镜像里。此时端口看 8424 这一组。 - 如果你走的是「已有 Memory Core、只补 Memory Hub」那条(
INSTALL_CN.md:213-234),docker run命令里写的是-p 8125:8125 -p 8424:8424,同样属于 8424 这一组。
**判定动作二:比对两处配置。**打开 MemoryKnowledge/src/config.ts:150,再打开 deploy/panel-knowledge-combined/start-combined.sh:100,前者是模块的默认值,后者是外层变量到模块变量的转译点。你的配置从哪一头进来,就以哪一头的文件为准。
判定动作三:查一个不会随端口变的地方。MemoryKnowledge/src/routes/health.ts:10 注册的 GET /health 挂在无前缀位置(src/server.ts:56-96 的挂载顺序里,/health 在 /v3 前缀之外),返回 { status: "ok", timestamp }。业务路由才走 app.route(config.apiPrefix, api) 加上 /v3。所以确认「服务在不在这个端口上」和「API 前缀对不对」是两件事,别混在一次判断里。
四、端口一改,还有两处必须跟着改
这是本篇最实际的一段。文档里写明了端口不是一个孤立的数字。
第一处是 KNOWLEDGE_PUBLIC_BASE_URL。deploy/global-images/.env.example:54-56 的默认值是 http://host.docker.internal:8424/v3,注释强调必须含 /v3 前缀;deploy/global-images/README.md:162-171 明写改 KNOWLEDGE_PORT 时这个变量要跟着改。它还是必填项之一——start-all.sh:21-27 的 require_vars 一共校验 15 项(三个镜像、四个端口、两个卷名、三个 MEMORY_LLM_*、KNOWLEDGE_PUBLIC_BASE_URL、三个 PROXY_UPSTREAM_*),判定规则是「空 或 等于字面量 REPLACE_ME」即算缺失(_lib.sh:34-49)。
第二处是模块自己的入口校验。MemoryKnowledge/docker/entrypoint.sh:177-183 会校验 --public-url 必须以 /v3 结尾。docker-compose.yml 的 command: 里 --public-url 用的是 ${PUBLIC_URL:?...} 写法,未设直接报错退出。
另外有三个地方写着 8421 但不受端口变量影响,改端口时容易漏:openapi.yaml 的 servers[0].url 是规格里的静态字符串;MCP 进程读的是另一个变量 KNOWLEDGE_API_URL(默认 http://localhost:8421,可选 KNOWLEDGE_API_TOKEN);而 src/mcp/http-client.ts:36 拼 URL 的写法是 ${baseUrl}/v3${endpoint},这里的 /v3 是写死的字符串,哪怕你改了 API_PREFIX 它也不跟。
五、改完怎么验证
仓库自带了验证入口,不用自己现编:MemoryKnowledge/docker/smoke-test.sh(236 行)会依次 curl /health、/docs、/wiki/list、/code-graph/list,再跑一遍 wiki 的 create → get → delete。注意它所有 API 调用都带 -H "x-tdai-service-id: $SERVICE_ID"(120、147 行)。同目录还有 run.sh(48 行)是宿主机一键 docker run。
容器内的健康检查是另一回事:MemoryKnowledge/Dockerfile:85-86 的 HEALTHCHECK 用 node -e "fetch('http://127.0.0.1:8421/health')...",interval 30s / timeout 5s / start-period 15s / retries 3;这打的是容器内地址,和你在宿主机上敲哪个端口不是同一件事。docker-compose.yml:42-47 另有一份同款 healthcheck,参数是 interval 15s / timeout 5s / retries 3 / start_period 15s。
Swagger 那边:src/server.ts:100-111 把 UI 挂在 /docs,同时暴露 /openapi.json——顺带记一句,这个 handler 返回的 Content-Type 写的是 application/yaml。
六、什么情况说明不是端口的问题
排查文章最不该省的就是这一步。以下几种情况,换端口不解决:
- 返回 400 且提到 service_id:这是缺请求头。
MemoryKnowledge/src/api-helpers.ts:12定义SERVICE_ID_HEADER = "x-tdai-service-id",白名单是^[A-Za-z0-9_-]+$、最长 200(20-21 行),注释说明这是为了防路径穿越(id 会被拼进data/{service_id}/{team_id}/{resource_id}/)。每个 handler 各自读这个头并在缺失时 400(例如src/routes/wiki.ts:470)。本地部署下spaceId固定为default。 - 路径 404 但服务确实在:先看
/v3前缀有没有带。业务路由全在config.apiPrefix之下(默认/v3),/health、/docs、/openapi.json在前缀之外。 - 规格里查不到你要调的端点:
openapi.yaml:6自称提供 28 个端点,我们数出 paths 下确实是 28 条;而代码在/v3前缀下注册了 37 条。规格里查不到的包括POST /wiki/update-meta、POST /code-graph/update-meta、POST /tools/list、POST /tools/call、三条/internal/llm-binding/*,以及GET /auto-sync/status、POST /auto-sync/trigger。这属于规格与代码的差异,不是端口。 - MCP 那一侧连不上:MCP 客户端走的是
KNOWLEDGE_API_URL,且src/mcp/http-client.ts:36-38的请求头只设Content-Type、有 token 时加Authorization——我们在该文件里没有找到设置x-tdai-service-id的代码,而被它调用的那些路由缺该头会返回 400。 - 回调没动静:
TMC_CALLBACK_URL为空时整个回调是 no-op(src/callback.ts:56-58),跟端口无关。
七、顺带一提:Panel 也有一对
同一个模式在 Panel 上又出现了一次,形状完全一样:MemoryKnowledge/README.md:61、69、77 里 TMC_CALLBACK_URL 写的是 http://127.0.0.1:8123,而 INSTALL.md:57、71、deploy/global-images/.env.example:49、deploy/panel-knowledge-combined/Dockerfile:48 写的是 8125。模块侧的 MemoryPanel/docker/local/Dockerfile.local:72 是 EXPOSE 8123、ENV HOST=0.0.0.0 PORT=8123。
所以你在这个仓库里核端口时,把「模块独立镜像」和「合并镜像 / 三件套」这两栏分开记,比记具体数字更省事。
最后要说的限定:这个项目仍在快速变动。CHANGELOG.md:12 最新条目是 2.0.1-beta.1,MemoryCore/package.json 里是 2.0.0-beta.1,而 MemoryKnowledge/package.json 的版本还是 0.1.0;ROADMAP 开头自己声明「路线图列出的是团队正在推进的工作,不是承诺,范围与时间可能调整」。本文列的每一个行号都对应 97f9465 这个快照,端口、变量名、默认值都可能随版本变化,动手前请以你手上那份仓库的文件为准。
延伸阅读
- 从头读起:TencentDB Agent Memory 是什么:团队级 Agent 记忆中枢怎么读
- 本专题共 40 篇,完整分组目录见专题页
- TencentDB Agent Memory 有几种装法:单机、Docker 与合并镜像
- TencentDB Agent Memory 的镜像用户:Dockerfile 里没有 USER 指令
本文依据 TencentDB Agent Memory 官方仓库(github.com/TencentCloud/TencentDB-Agent-Memory)
feat/server_team 分支上的 README、INSTALL、CHANGELOG、ROADMAP 与四个模块的源码整理,
核对日 2026-08-16,对应仓库快照 97f9465。该仓库的默认分支即为 feat/server_team。
本文内容为仓库源码与文档口径,我们没有部署、也没有运行过该项目的任何一个模块,
因此不涉及运行效果、检索质量与性能的任何描述。
该项目主模块处于 beta 阶段、其余模块版本号仍为 0.1.0,参数与接口随版本变动,请以仓库最新内容为准。
该项目会采集并存储团队的对话、文档与代码,属于敏感数据,是否使用请结合自身合规要求评估。
安全与合规相关做法请结合自身环境评估,本文不构成安全方案建议。