# AgentServer 自托管的 Agent 服务:在服务端接入 Claude Code(Codex 在 M2 接入),通过统一的 REST + SSE API 为内部业务平台提供数据分析、资料查找、文档生成等能力,并附带一个 VS Code 风格的管理后台(含 Playground)。 设计文档见 [docs/](docs/README.md)。 ## 目录结构 ``` apps/server Fastify + SQLite 服务端(API、Run 调度、引擎适配、安全策略) apps/admin 管理后台(Vue 3 + UnoCSS),生产环境由服务端托管在 /admin/ packages/shared 事件与 API 类型(前后端共享) packages/client TS 客户端 SDK(会话、SSE 断线续传、交互回复、上传) packages/chat-ui Vue 对话组件(时间线、工具卡片、审批/提问卡片、输入框),业务平台可直接复用 packages/ui-tokens 设计令牌(tokens.css)与 UnoCSS preset skills/ 本地技能(部署到 /srv/agent-server/skills;官方技能通过后台"技能与插件"安装,不放在这里) deploy/ 安装、运行环境、发布脚本与 systemd unit docs/ 设计文档、ADR、调研 ``` ## 前置条件 - Node.js 22+、pnpm 8+ - 正式服务:用 `agent-claude` 以服务账号 agentsvc 登录 Claude(一次即可);开发环境:本人终端已登录 `claude` - bubblewrap、socat(Claude 沙箱);LibreOffice、poppler-utils、pandoc、ripgrep、fonts-noto-cjk - 数据目录与运行环境由 `deploy/install.sh`、`deploy/setup-runtime.sh` 创建,见 [docs/design/10-deployment.md](docs/design/10-deployment.md) ## 部署(正式服务) 服务以专用用户 `agentsvc` 运行(systemd),详见 [docs/design/10-deployment.md](docs/design/10-deployment.md): ```bash sudo deploy/install.sh # 首次:创建 agentsvc、目录权限、systemd 服务、agent-claude 命令 sudo deploy/setup-runtime.sh # 首次 / 依赖变化:Python、Node、系统工具 deploy/deploy.sh # 每次发布:构建、发布到 /srv/agent-server/app、重启 # 然后在后台"概览"页点"登录"完成 Claude 登录(也可以在终端执行 agent-claude auth login) ``` 后台:http://127.0.0.1:8787/admin/ ;日志:`journalctl -u agent-server -f` ## 开发 ```bash pnpm install pnpm dev:server # 服务端:http://127.0.0.1:8788(tsx watch,数据在 .dev-data/,使用你自己的 claude 登录态) pnpm dev:admin # 后台:http://127.0.0.1:5173/admin/(代理到 8788) ``` 首次启动时,如果没有设置 `AGENT_SERVER_ADMIN_PASSWORD`,会生成随机的后台密码并打印在日志里(只打印一次),登录后请在"设置"中修改。 | 环境变量 | 默认值 | 说明 | |---|---|---| | `AGENT_SERVER_HOST` / `AGENT_SERVER_PORT` | `127.0.0.1` / `8787`(开发脚本为 8788;systemd 部署为 `0.0.0.0`) | 监听地址 | | `AGENT_SERVER_TRUST_PROXY` | `false` | 反向代理的 IP / CIDR(逗号分隔,推荐),或 `true`(信任所有来源) | | `AGENT_SERVER_DATA_DIR` | 生产 `/srv/agent-server`,开发 `.dev-data/` | 数据目录 | | `AGENT_SERVER_SHARED_DIR` | `/srv/agent-server` | 共享只读资源(runtime、skills) | | `AGENT_SERVER_ADMIN_PASSWORD` | (随机生成) | 仅首次启动时使用 | | `AGENT_SERVER_ADMIN_DIST` | `apps/admin/dist` | 后台静态资源目录 | 其余运行配置(路径、资料库、禁止项、网络白名单、并发等)都在后台"设置"和"资料库"页面管理。 ## 构建与运行 ```bash pnpm build # 构建全部包(后台产物在 apps/admin/dist) NODE_ENV=production node apps/server/dist/main.js ``` ## 测试 ```bash pnpm test # 服务端单元与集成测试(文件访问策略、API 全流程、LibreOffice 转换) pnpm typecheck # 全部包类型检查 ``` `apps/server/scripts/` 下有两个手动验证脚本(会消耗真实额度):`smoke-claude.ts` 用来验证 SDK 和登录态,`try-claude-adapter.ts` 用来验证审批流和越权拦截。 ## 调用示例 ```bash KEY=ask_xxx # 在后台 API Keys 页面签发 SID=$(curl -s -X POST localhost:8787/v1/sessions -H "authorization: Bearer $KEY" -H 'content-type: application/json' -d '{}' | jq -r .id) curl -s -X POST localhost:8787/v1/sessions/$SID/files -H "authorization: Bearer $KEY" -F file=@sales.xlsx curl -s -X POST localhost:8787/v1/sessions/$SID/messages -H "authorization: Bearer $KEY" -H 'content-type: application/json' \ -d '{"text":"分析 uploads/sales.xlsx,生成一份 Word 报告"}' curl -N localhost:8787/v1/sessions/$SID/stream -H "authorization: Bearer $KEY" # SSE 事件流 ``` 前端推荐直接使用 `@agent-server/client` 和 `@agent-server/chat-ui`: ```ts import { AgentClient } from '@agent-server/client' import { AgentChat, useChatSession } from '@agent-server/chat-ui' import '@agent-server/ui-tokens/tokens.css' const client = new AgentClient({ baseUrl: 'https://agent.example.com', apiKey: KEY }) const session = useChatSession(client, sessionId) // ```