你正在帮助用户将一个 AI Agent 客户端(Claude Code / CodeBuddy / Codex / WorkBuddy / dsh / Hermes / OpenClaw)接入 Memory Proxy。
Memory Proxy 是一个 LLM 请求代理,在请求转发到上游 LLM 之前注入团队记忆/技能/知识。每个 agent 客户端有不同的配置文件格式和协议:
| Agent | 配置文件 | 协议 | 特殊要求 |
|---|---|---|---|
| claude-code | ~/.claude/settings.json |
Anthropic Messages | env 字段里写 5 个模型变量 |
| codebuddy | ~/.codebuddy/models.json |
OpenAI Chat | models 数组追加条目 |
| codex | ~/.codex/config.toml |
OpenAI Responses | TOML 格式,必须 wire_api = "responses" |
| workbuddy | ~/.workbuddy/models.json |
OpenAI Chat / Responses | 顶层数组 |
| dsh | ~/.dsh/settings.yaml + ~/.dsh/.credentials.yaml |
OpenAI Chat (无 /v1) | 两个文件 + chmod 700/600 |
| hermes | ~/.hermes/config.yaml |
OpenAI Chat | 需 header 预选 (x-team-id/agent-id/task-id) |
| openclaw | ~/.openclaw/openclaw.json |
OpenAI Chat | 需 header 预选 + allowPrivateNetwork |
配置写入脚本:agents/skills/setup-proxy/setup-proxy.sh(相对于仓库根目录)
严格按以下顺序,每一步必须验证通过后再进入下一步。
先检查用户是否已有 proxy 配置,避免重复填写:
# 检查 Claude Code
cat ~/.claude/settings.json 2>/dev/null | jq -r '.env.ANTHROPIC_BASE_URL // empty'
# 检查 CodeBuddy
cat ~/.codebuddy/models.json 2>/dev/null | jq -r '.models[]? | select(.url | contains("/codebuddy/")) | .url' 2>/dev/null | head -1
# 检查其他 agent 类似...
如果扫描到含 proxy 路径的 URL(包含 /claude-code/、/codebuddy/、/codex/ 等片段),提取并展示:
/<agent>/ 之前的部分)/<agent>/ 之后的那段)询问用户:"检测到现有配置,是否复用?"
依次向用户获取:
http://127.0.0.1:8096)default,本地部署一般不用改)每个信息获取后确认,不要一次问三个。
展示 7 个可选 agent 让用户选择一个:
告诉用户:
claude-sonnet-4-20250514、claude-opus-4.7、gpt-5.5、deepseek-r1
根据选中 agent 的协议,构造对应的 curl 探测请求:
# Claude Code → Anthropic Messages
curl -s -w "\n%{http_code}" -X POST "${PROXY_HOST}/claude-code/${INSTANCE_ID}/v1/messages" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${USER_KEY}" \
-d '{"model":"'${MODEL_ID}'","messages":[{"role":"user","content":"ping"}],"max_tokens":1,"stream":false}'
# CodeBuddy / Hermes / OpenClaw → OpenAI Chat
curl -s -w "\n%{http_code}" -X POST "${PROXY_HOST}/${AGENT}/${INSTANCE_ID}/v1/chat/completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${USER_KEY}" \
-d '{"model":"'${MODEL_ID}'","messages":[{"role":"user","content":"ping"}],"max_tokens":1,"stream":false}'
# dsh → OpenAI Chat 但不带 /v1
curl -s -w "\n%{http_code}" -X POST "${PROXY_HOST}/dsh/${INSTANCE_ID}/chat/completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${USER_KEY}" \
-d '{"model":"'${MODEL_ID}'","messages":[{"role":"user","content":"ping"}],"max_tokens":1,"stream":false}'
# Codex → Responses API
curl -s -w "\n%{http_code}" -X POST "${PROXY_HOST}/codex/${INSTANCE_ID}/v1/responses" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${USER_KEY}" \
-d '{"model":"'${MODEL_ID}'","input":[{"type":"message","role":"user","content":[{"type":"input_text","text":"ping"}]}],"stream":false}'
# WorkBuddy → OpenAI Chat (更通用)
curl -s -w "\n%{http_code}" -X POST "${PROXY_HOST}/workbuddy/${INSTANCE_ID}/v1/chat/completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${USER_KEY}" \
-d '{"model":"'${MODEL_ID}'","messages":[{"role":"user","content":"ping"}],"max_tokens":1,"stream":false}'
判断结果:
如果选的是 hermes 或 openclaw,需要额外收集 header 预选信息。这些 agent 不支持交互式 form,必须在配置中预填 team/agent/task ID。
优先方案:通过面板 API 拉取列表让用户选择
询问用户是否提供面板后端地址(默认 http://127.0.0.1:8125)。如果提供了:
# 1. 先通过 auth/verify 拿 user_id
curl -s -X POST "${PANEL_URL}/api/v1/meta/auth/verify" \
-H "Content-Type: application/json" \
-H "x-tdai-service-id: ${INSTANCE_ID}" \
-d '{"user_key":"'${USER_KEY}'"}'
# 从 .data.user.user_id 提取
# 2. 拉 Team 列表
curl -s -X POST "${PANEL_URL}/api/v1/meta/team/list" \
-H "Content-Type: application/json" \
-H "x-tdai-user-key: ${USER_KEY}" \
-H "x-tdai-service-id: ${INSTANCE_ID}" \
-d '{"user_key":"'${USER_KEY}'"}'
# 从 .data.items 展示让用户选
# 3. 拉 Agent 列表(带 owner_user_id 过滤)
curl -s -X POST "${PANEL_URL}/api/v1/meta/agent/list" \
-H "Content-Type: application/json" \
-H "x-tdai-user-key: ${USER_KEY}" \
-H "x-tdai-service-id: ${INSTANCE_ID}" \
-d '{"team_id":"'${TEAM_ID}'","user_key":"'${USER_KEY}'","owner_user_id":"'${USER_ID}'"}'
# 从 .data.items 展示让用户选
# 4. 拉 Task 列表
curl -s -X POST "${PANEL_URL}/api/v1/meta/task/list" \
-H "Content-Type: application/json" \
-H "x-tdai-user-key: ${USER_KEY}" \
-H "x-tdai-service-id: ${INSTANCE_ID}" \
-d '{"team_id":"'${TEAM_ID}'","user_key":"'${USER_KEY}'"}'
# 第一个选项始终是"本次不关联任务 (no-task)"
如果面板不可达或用户不想提供,让用户手动填写 team_id / agent_id / task_id。
另外还需要一个 x-conversation-id(可自动生成一个如 conv-20260820-xxxx)。
告诉用户默认路径(见上方表格),询问是否使用默认路径。如果不是让用户填。
所有信息收集完毕且验证通过后,调用脚本的非交互模式写入配置:
bash agents/skills/setup-proxy/setup-proxy.sh --non-interactive \
--proxy-host "${PROXY_HOST}" \
--instance-id "${INSTANCE_ID}" \
--user-key "${USER_KEY}" \
--agent "${CHOSEN_AGENT}" \
--model "${MODEL_ID}" \
--config-path "${CONFIG_PATH}"
如果是 Hermes/OpenClaw,追加:
--team-id "${TEAM_ID}" \
--agent-id "${AGENT_ID}" \
--task-id "${TASK_ID}" \
--conv-id "${CONVERSATION_ID}"
检查脚本退出码:0 = 成功,非 0 = 失败(展示输出给用户)。
写入后读取配置文件确认内容正确:
cat <config_path>
展示关键字段给用户确认。
配置写入不等于生效,必须提醒用户在客户端中切换到 Proxy 模型才会走 Proxy 链路:
| Agent | 如何切换 |
|---|---|
| Claude Code | 无需操作,settings.json 的 env 启动时自动加载 |
| CodeBuddy | 对话框中切换模型为 proxy-memory-agent(即配置的模型 ID) |
| Codex | 无需操作,config.toml 已指定 model |
| WorkBuddy | 模型选择器中切换到自定义模型列表里的对应模型 |
| dsh | 无需操作,settings.yaml 已指定模型 |
| Hermes / OpenClaw | 确保客户端选择的 provider/模型指向 Proxy 配置 |
务必告知用户:如果不切换模型,请求不会经过 Proxy,记忆/技能注入不会生效。
配置完成后询问用户:是否要导入该 Agent 的本地资产(skill + 对话历史)到团队记忆?
如果用户选择导入:
然后调用:
PANEL_URL="${PANEL_URL}" TDAI_SERVICE_ID="${INSTANCE_ID}" TDAI_USER_KEY="${USER_KEY}" \
tsx agents/asset-import.ts --source "${CHOSEN_AGENT}" --team-id "${TEAM_ID}" --agent-id "${AGENT_ID}"
如果 tsx 不可用,提示用户手动运行命令。
.bak.<timestamp>
/v1,这是客户端硬编码的