当我把 Claude Code 从终端“搬“到服务器上之后...

张开发
2026/5/18 10:00:11 15 分钟阅读
当我把 Claude Code 从终端“搬“到服务器上之后...
一个折腾的周末上个月有个需求让我头疼了很久。我们团队用 Claude Code 做内部工具开发效率确实高——写 prompt、配几个 MCP 工具一个功能半天就搭出来了。但问题也随之而来这东西只能在终端用。产品经理想把它集成到内部平台让非技术的同事也能用我想把几个常用的 Agent 封装成 API供其他服务调用。但 Claude Code 是个 CLI 工具强依赖终端交互这要怎么搞那个周末我翻了好多资料甚至考虑过用 expect 脚本模拟终端输入输出别笑真的试过最后干脆心一横要不自己研究一下它的内部机制看能不能把核心能力抽出来摸索的过程说干就干。我找了个开源项目 learn-claude-code它通过拦截 Claude Code 发往 Anthropic API 的请求分析出了 system prompt、工具定义、消息结构等参数。顺着这个思路我搭了个简单的代理开始观察 Claude Code 到底在干什么。结果发现Claude Code 的核心其实就是一个标准的 tool_use 循环没有想象中那么神秘用户输入 → 构建消息 → 调 Anthropic API ↑___________________| (循环直到结束)几个关键发现System Prompt 是分块的—— 不是一个大字符串而是content块数组分身份声明、工具说明、工作流、环境注入几段。环境注入那部分当前时间、工作目录、CLAUDE.md 内容是每轮动态追加的。上下文压缩是三层策略—— 日常对话微压缩截断旧工具结果超过阈值时触发 LLM 摘要完整对话会存档到 transcripts 目录。这个机制保证了长对话不会爆 token。子代理是独立实例—— 通过特殊工具信号派生有自己独立的 messages 列表和工具集运行完把结果返回给父代理。嵌套深度有限制默认 5 层。搞明白这些之后我意识到理论上完全可以复现这套机制然后把 CLI 外壳换掉。动手实现接下来就是码代码的过程了。我给自己定了几个目标保持核心行为一致—— 复现 Agent 循环、工具调用、子代理递归支持多种接口—— HTTP、SSE 流式、WebSocket 都要保留 Claude Code 的项目级配置—— .claude/ 那套东西很好用支持多 Agent 编排—— 复杂场景需要把多个 Agent 串起来大概花了一周多时间一个能跑通的版本出来了。给它起了个名字叫CCServerClaude Code Server 的缩写虽然有点随意但好记。用起来怎么样现在我的部署方式是服务器上跑 CCServer前端用 Gradio 做个简单界面内部平台的其他服务直接调 HTTP 接口。API 调用很简单# 创建会话curl-XPOST http://localhost:8000/sessions# 直接对话阻塞式curl-XPOST http://localhost:8000/chat\-HX-Session-Id: xxx\-d{message: 分析这个目录的代码结构}# 或者 SSE 流式curl-XGEThttp://localhost:8000/chat/stream?message你好\-HX-Session-Id: xxx配置管理还是熟悉的 .ccserver/ 目录.ccserver/ ├── agents/ # 自定义 subagent ├── skills/ # 技能文档 ├── hooks/ # 生命周期钩子 └── settings.json # 权限配置格式和 Claude Code 的.claude/保持一致可以直接拷贝复用。多 Agent 编排是我觉得最有意思的部分。比如我做了个角色扮演对话系统流程是这样的[用户输入] → [意图识别/搜索] → [话题建议] → [生成回复] → [质量检查] ↓___________| (不通过则重试)每个节点都是一个完整的 Claude Agent节点间按 DAG 执行支持条件回边做重试。这种显式编排比单 Agent 自主调度更可控适合业务流程固定的场景。一些踩坑记录Prompt 兼容性—— Claude Code 的 system prompt 结构在不同版本有变化我实现了一个PromptLib系统来管理不同版本的拼接逻辑可以通过环境变量切换。工具调用格式—— 要严格按照 Anthropic API 的 tool_use / tool_result 格式来参数类型也要对齐否则模型行为会不一致。会话隔离—— 每个会话要有独立的工作目录沙箱否则文件操作会互相干扰。我用sessions/{session_id}/workdir/的方式来管理。上下文压缩阈值—— 默认 50000 字符触发 LLM 压缩这个值要根据实际 token 消耗调整不同模型的换算比例不一样。写在最后把 CCServer 部署到服务器之后最大的感受是Agent 能力终于可以用起来了。以前写好的 prompt 和 MCP 配置只能在终端里自己用。现在可以封装成接口分享给团队集成到各种流程里。对于一些复杂的多步骤场景Graph 编排也让流程更清晰可控。如果你也有类似需求——想把 Claude Code 的能力服务化、或者需要多 Agent 协作编排——可以试试看。项目已经开源链接在文末还在持续迭代中。当然这只是个学习研究性质的实现不是官方项目部分高级特性比如 Claude Code 内置的那些专用 subagent还没有完全对齐。但核心的 Agent 循环和工具系统已经挺稳定了日常用下来没什么问题。相关链接项目地址https://github.com/kazeMace/ccserver

更多文章