Skip to content

Repository files navigation

ResearchOS

ResearchOS 是一个把“问题”研究成“观点”的个人深度研究工作台。

当前实现为 R1 持久化研究核心的首个可用迭代:

登录 → 工作台 → 选题池 → 创建研究项目 → 问题定义 → 研究假设 → 研究地图 → 资料搜集

本地运行

  1. 复制 .env.example.env,按需修改 POSTGRES_DBPOSTGRES_USERPOSTGRES_PASSWORD;同时保持 DATABASE_URLDIRECT_DATABASE_URL 中的连接信息一致。
  2. 启动 PostgreSQL 并初始化数据库:
npm install
npm run db:up
npm run db:deploy
npm run db:seed
npm run dev

打开 http://localhost:3000

混合 Agent 配置

研究假设、研究地图和资料搜集支持“AI 生成初稿 + 用户审核确认 + 手动编辑”的混合交互。资料搜集 Agent 只生成检索计划,不会静默执行外部搜索;搜索结果默认是待审核资料,不会自动成为事实或证据。未配置 Provider 或 Connector 时,页面保留完整的手动新增、编辑、删除和保存路径。

.env 中配置任意 OpenAI-compatible 服务:

AI_BASE_URL="https://api.openai.com/v1"
AI_API_KEY="your-api-key"
AI_MODEL="gpt-4o-mini"
# 可选;默认 60000,模型响应较慢时可提高到 90000
AI_TIMEOUT_MS="60000"

更新 Prisma Schema 后执行 npx prisma generate,数据库执行 npm run db:deploy;如果正在运行 Next.js 开发服务,重启 npm run dev 以加载新的 Prisma Client 和环境变量。

Agent 执行日志与调试

在“研究假设”“研究地图”或“资料搜集”页面底部点击 查看执行日志,可以查看当前阶段最近 20 次运行;点击某次运行的详情,可以看到 RUN_STARTEDPROVIDER_REQUESTRUN_COMPLETEDPROVIDER_FAILED 等事件、错误信息、耗时和脱敏元数据。

页面会持续轮询 GENERATING 运行,直到 Agent 完成或失败;连续 2 分钟没有收敛会自动回到手动模式。服务端会将超过 5 分钟仍为 GENERATING 的孤立运行标记为失败,下一次生成请求会创建新运行。

也可以直接通过接口查询,projectId 替换为当前研究项目 ID:

curl -b "<登录 Cookie>" "http://localhost:3000/api/projects/<projectId>/agent-runs?stage=MAP&limit=20"
curl -b "<登录 Cookie>" "http://localhost:3000/api/projects/<projectId>/agent-runs/<runId>"

开发服务终端会同步输出不含 API Key 的结构化日志,前缀为 [agent-run]。常见故障码:

  • AGENT_NOT_CONFIGURED:检查 AI_BASE_URLAI_API_KEYAI_MODEL,修改 .env 后重启 npm run dev
  • AGENT_TIMEOUT:检查上游网络、代理和模型响应时间。
  • AGENT_RATE_LIMITED:检查模型配额、调用频率或切换模型。
  • AGENT_INVALID_OUTPUT:上游没有返回合法 JSON,检查 OpenAI-compatible 服务是否支持 response_format: { type: "json_object" }
  • AGENT_UPSTREAM_ERROR:查看运行详情中的 HTTP 错误和终端日志,确认 AI_BASE_URL 是否应包含 /v1
  • P2021agent_run_logs / agent_runs 表不存在:先执行 npm run db:deploy,再重启开发服务。

AI 配置快速验证

不要在终端命令或日志中打印 AI_API_KEY。项目提供了一个复用真实 Provider 请求格式的验证教本:

# 验证研究假设请求
npm run verify:ai

# 验证研究地图请求
npm run verify:ai -- map

输出含义:

  • PASS:网络、鉴权、模型名和 JSON 结构均可用。
  • HTTP 401/403:API Key 或上游权限不对。
  • HTTP 404AI_BASE_URL 路径不对,通常检查是否应包含 /v1
  • HTTP 400:模型或 response_format: { type: "json_object" } 不被上游兼容接口支持。
  • TIMEOUT:请求超过 AI_TIMEOUT_MS;先看实际耗时,再检查上游网络、代理、模型负载或提高超时。
  • UPSTREAM_ERROR 且没有 HTTP 状态:通常是 DNS、TLS、代理或网络不可达。

日志迁移文件为 prisma/migrations/20260824100000_add_agent_run_logs/migration.sql。日志只保存运行状态、错误、事件和脱敏元数据,不保存 API Key。

网页搜索与正文抓取 MCP

如果 .env 已经配置了 OpenAI 官方 API,资料搜集会优先自动使用模型内置网页搜索,不需要填写 SOURCE_WEB_SEARCH_MCP_ENDPOINTSOURCE_WEB_SEARCH_MCP_TOKEN。当前默认规则是:

  • AI_BASE_URLhttps://api.openai.com/v1:自动启用内置网页搜索。
  • 其他 OpenAI-compatible 服务:默认不假设支持网页搜索;如果该服务确实兼容 Responses Web Search,可以设置 SOURCE_BUILTIN_WEB_SEARCH="true"
  • 如果配置了 SOURCE_WEB_SEARCH_MCP_ENDPOINT:优先使用 MCP,MCP 优先级高于内置搜索。
  • SOURCE_PAGE_FETCH_MCP_ENDPOINT 仍然只负责网页正文抓取;没有抓取 MCP 时,可以手工粘贴正文。

因此,最简单的配置只需要已有的 AI 配置:

AI_BASE_URL="https://api.openai.com/v1"
AI_API_KEY="your-openai-api-key"
AI_MODEL="gpt-4.1-mini"
SOURCE_BUILTIN_WEB_SEARCH="auto"

如果你使用的是兼容 OpenAI 的其他服务,并确认它提供 Responses API 网页搜索,再显式打开:

AI_BASE_URL="https://your-provider.example.com/v1"
AI_API_KEY="your-provider-key"
AI_MODEL="your-search-capable-model"
SOURCE_BUILTIN_WEB_SEARCH="true"

资料搜集阶段也支持通过标准 Connector 接口调用远程 Streamable HTTP MCP。搜索和抓取独立配置,后续可以分别替换为学术搜索、新闻搜索或内部知识库 Connector:

SOURCE_WEB_SEARCH_CONNECTOR_ID="web-search"
SOURCE_WEB_SEARCH_MCP_ENDPOINT="https://your-mcp.example.com/mcp"
SOURCE_WEB_SEARCH_MCP_TOOL="web_search"
SOURCE_WEB_SEARCH_MCP_TOKEN=""

SOURCE_PAGE_FETCH_CONNECTOR_ID="page-fetch"
SOURCE_PAGE_FETCH_MCP_ENDPOINT="https://your-fetch-mcp.example.com/mcp"
SOURCE_PAGE_FETCH_MCP_TOOL="fetch_page"
SOURCE_PAGE_FETCH_MCP_TOKEN=""

SOURCE_CONNECTOR_TIMEOUT_MS="30000"
SOURCE_SEARCH_RESULT_LIMIT="4"
SOURCE_FETCH_MAX_BYTES="1000000"

修改 .env 后重启开发服务。Connector 只接受远程 HTTP MCP,不会在 Web 服务器内启动任意本地 stdio 进程。网页抓取会拒绝 localhost、内网地址、链路本地地址和非 HTTP(S) URL。

验证配置:

npm run verify:sources
npm run verify:sources -- "自定义安全测试搜索词"

脚本会打印 Connector ID、搜索模式、工具名、能力、健康状态和最多 3 条结果标题/URL,不会打印 Token 或网页正文。未配置 MCP 但配置了 OpenAI 官方 AI 时,应看到 search mode=OPENAI_WEB_SEARCH;完全没有搜索能力时才会返回 SOURCE_CONNECTOR_NOT_CONFIGURED

常见资料 Connector 错误:

  • SOURCE_CONNECTOR_NOT_CONFIGURED:缺少对应 endpoint,或检索任务引用了未注册的 Connector ID。
  • SOURCE_CONNECTOR_RATE_LIMITED:内置网页搜索达到调用限制,请稍后重试或切换 MCP。
  • SOURCE_CONNECTOR_UNAUTHORIZED:Bearer Token 无效或 MCP 服务拒绝访问。
  • SOURCE_CONNECTOR_TIMEOUT:远程 MCP 超过 SOURCE_CONNECTOR_TIMEOUT_MS
  • SOURCE_INVALID_RESULT:MCP 工具没有返回标准 resultscontentText JSON。
  • SOURCE_URL_BLOCKED:抓取 URL 指向 localhost、内网或云元数据地址。

搜索或抓取失败不会阻塞研究流程。用户可以直接添加 URL、创建无 URL 的手工笔记,或在资料卡片中粘贴正文。

本地容器运行依赖 Podman 与 podman compose。项目使用 .podman-compose/config.json 隔离 Compose 凭据配置,避免读取已卸载 Docker Desktop 遗留的 credsStore;启动脚本设置 PODMAN_COMPOSE_WARNING_LOGS=false,不再输出外部 Compose provider 提示;PostgreSQL 镜像通过 mirror.gcr.io 获取,避免部分网络环境访问 Docker Hub 时出现 EOF。若本机没有 Podman,也可以使用 npx prisma dev --name researchos --detach。该命令返回代理连接串时,应用侧 DATABASE_URL 需要追加 &pgbouncer=true,迁移使用的 DIRECT_DATABASE_URL 保持原连接串。

校验命令

npm run typecheck
npm test
npm run test:e2e
npm run build

当前工程结构

  • src/app/:Next.js 页面和 API Route Handlers。
  • src/app/(app)/:受会话保护的工作台、选题池和研究项目真实路由。
  • src/server/modules/:按工作空间过滤的 Prisma 仓储。
  • src/lib/domain.ts:研究领域类型和状态。
  • src/server/auth/:数据库会话和当前工作空间边界。
  • prisma/schema.prisma:PostgreSQL 核心对象模型。
  • docs/20260812-researchos-prd.md:产品需求文档。
  • docs/20260812-researchos-tech-design.md:技术方案文档。

下一阶段

按照技术方案继续实现:

  1. 证据核验与事实提取。
  2. 学术搜索、新闻搜索和内部知识库 Connector。
  3. 研究地图父子关系、拖拽排序和画布视图。
  4. Red Team、结论版本和 Markdown 文章生成。

About

ResearchOS 是一个把“问题”研究成“观点”的个人深度研究工作台。

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages