diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..aac549d --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,2 @@ +# The project owner reviews repository-wide changes while the maintainer team is small. +* @aopays diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 7913c18..b4333fd 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,7 +1,7 @@ name: Bug report description: Report a reproducible defect without including secrets or private data. title: "[Bug]: " -labels: [bug] +labels: [bug, needs-triage] body: - type: markdown attributes: diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..1d9eb6f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Questions and design discussions + url: https://github.com/aopays/cloud-agent-platform/discussions + about: Ask usage questions or discuss ideas before opening an implementation issue. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..2eebcc5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,54 @@ +name: Feature request +description: Propose an FDE discovery improvement or a real-world agent workflow. +title: "[Feature]: " +labels: + - enhancement + - needs-triage +body: + - type: markdown + attributes: + value: | + Thanks for helping improve Cloud Agent Platform. Concrete workflows and measurable outcomes are especially useful. + - type: textarea + id: problem + attributes: + label: Problem or workflow + description: Who has this problem, and what are they trying to complete? + placeholder: As a platform engineer, I need... + validations: + required: true + - type: textarea + id: proposal + attributes: + label: Proposed behavior + description: Describe the smallest useful behavior, including inputs and outputs. + validations: + required: true + - type: textarea + id: acceptance + attributes: + label: Acceptance evidence + description: How could maintainers verify that the feature works? + placeholder: Given..., when..., then... + validations: + required: true + - type: dropdown + id: area + attributes: + label: Area + options: + - Agent runtime and tools + - Sandbox and security + - API and scheduling + - Requirement discovery + - Documentation and onboarding + - Other + validations: + required: true + - type: checkboxes + id: boundaries + attributes: + label: Safety check + options: + - label: This proposal does not require committing secrets or bypassing the sandbox boundary. + required: true diff --git a/README.md b/README.md index 71d0e6f..3702664 100644 --- a/README.md +++ b/README.md @@ -1,236 +1,227 @@ # Cloud Agent Platform -> **Turn fuzzy ideas and code repositories into bounded, auditable AI work.** -> 从一句模糊需求到软件设计报告,从一个 Git 仓库到可追踪的 Agent 执行结果。 +一个从场景面试题做起的 FDE 需求发现与 Agent 执行平台 -![Python](https://img.shields.io/badge/Python-3.10%2B-3776AB?logo=python&logoColor=white) -![FastAPI](https://img.shields.io/badge/FastAPI-0.115%2B-009688?logo=fastapi&logoColor=white) -![OpenAI](https://img.shields.io/badge/OpenAI-Responses_API-412991?logo=openai&logoColor=white) -![License](https://img.shields.io/badge/License-MIT-green) -![Status](https://img.shields.io/badge/Status-Alpha-orange) +**简体中文** · [English overview](#english-overview) -Cloud Agent Platform 是一个面向 **AI 应用工程师、平台工程团队和技术面试候选人** 的开源 MVP。 -它把“LLM 会调用工具”扩展成一条可以真正运行、取消、审计和演进的工程链路:API 接收任务,调度器投递, -Worker 准备仓库,Agent Runtime 循环推理与调用工具,Sandbox 控制执行边界,最终返回事件、用量与产物。 +![Cloud Agent Platform: FDE discovery, bounded agents, auditable delivery](docs/assets/cloud-agent-platform-hero.svg) -项目还提供独立的 **需求挖掘工作台**:用户只需要输入十几个字的模糊需求,系统通过多轮对话补齐用户、目标、 -流程、约束和验收条件,再生成可下载的软件设计报告。 +[![CI](https://github.com/aopays/cloud-agent-platform/actions/workflows/ci.yml/badge.svg)](https://github.com/aopays/cloud-agent-platform/actions/workflows/ci.yml) +[![Security](https://github.com/aopays/cloud-agent-platform/actions/workflows/security.yml/badge.svg)](https://github.com/aopays/cloud-agent-platform/actions/workflows/security.yml) +[![Python](https://img.shields.io/badge/Python-3.10%2B-3776AB?logo=python&logoColor=white)](https://www.python.org/) +[![OpenAI](https://img.shields.io/badge/OpenAI-Responses_API-412991?logo=openai&logoColor=white)](https://developers.openai.com/api/docs/quickstart) +[![License](https://img.shields.io/badge/License-MIT-22c55e)](LICENSE) +[![GitHub stars](https://img.shields.io/github/stars/aopays/cloud-agent-platform?style=social)](https://github.com/aopays/cloud-agent-platform/stargazers) -> 当前版本是可运行的本地开发与架构演示 MVP,不是生产级托管平台。运行时已经实现单 Agent 工具循环; -> 多 Agent DAG、持久化基础设施和强隔离属于清晰定义的演进路线,而非已经上线的能力。 +这个项目最初来自一道 AI 应用开发岗位的场景题:用户提交一句自然语言任务和一个代码仓库,平台在隔离环境中启动 Agent,让模型调用工具完成任务。我在拆题时发现,真正麻烦的地方不只在 Agent Loop。任务开始以前,FDE(Forward Deployed Engineer)往往还要先把客户十几个字的想法问清楚;任务开始以后,平台则要处理排队、超时、取消、权限和失败恢复。 -## 为什么值得关注 +所以仓库里有两个相互关联的功能: -- **不是一个聊天壳**:包含任务状态机、at-least-once 队列、执行租约、取消传播、预算和产物管理。 -- **不是一个无限循环脚本**:模型轮次、token、墙钟时间、命令时间和工具输出都有上限。 -- **不是把 Docker 当魔法**:明确 local 与 Docker 沙箱的信任边界,并提供路径穿越、符号链接、进程树和资源限制测试。 -- **不是只展示 Happy Path**:失败、超时、取消、重复投递、幂等冲突和清理失败都有显式语义。 -- **不是只画目标架构**:仓库同时保留 As-Is 可运行代码、Next 演进设计和完整 SDLC 文档,方便面试讲解和二次开发。 +- `/discovery` 用于前期需求访谈。它会继续追问业务目标、现状、规则、数据和验收方式,最后整理成技术方案草稿。 +- `/v1/tasks` 用于执行仓库任务。Worker 准备代码,Agent 调用受控工具,平台记录过程并保存结果。 -## 两条可运行产品链路 +当前版本是本地可运行的 MVP,适合用于面试展示、学习 Agent 工程或继续二次开发。它还不是托管服务:数据主要保存在进程内,产品运行时只有一个 Agent,多 Agent DAG 和生产级基础设施都还在设计阶段。 -### 1. 模糊需求 → 软件设计报告 +**文档导航**: [运行项目](#本地运行) · [需求发现](#需求发现会产出什么) · [仓库任务](#仓库任务会返回什么) · [演示建议](#面试时怎么演示) · [架构](#系统结构) · [源码入口](#从哪里开始读代码) · [已知限制](#当前限制) -适合产品经理、创业者、交付团队和 AI 应用工程师。输入例如: +## 需求发现会产出什么 + +例如客户只说: ```text -设计一个物流司机排班用的软件 +给物流公司设计一个司机排班软件,主要给货车司机使用。 ``` -系统通过三轮左右的澄清逐步收集角色、业务目标、关键流程、规则、数据、安全、性能和验收标准,最终生成 -Markdown 软件设计报告。入口:`http://127.0.0.1:8001/discovery`。 - -### 2. 自然语言任务 + Git 仓库 → Agent 产物 +系统不会立刻补出一份“完整 PRD”,因为这时大部分信息都没有依据。它会继续问: -适合研发团队、代码治理平台和 Agent Platform 学习者。输入包括自然语言指令、公开 HTTPS Git URL 或允许目录内 -的 `file://` 仓库 URI。平台返回: +- 要改善的业务指标、基线和决策人; +- 当前流程、异常证据、范围与非目标; +- 排班硬约束、软约束和人工兜底规则; +- 司机、车辆、订单、地图等数据与系统负责人; +- 权限、安全、合规、PoC/MVP 验收阈值。 -- Task ID 与完整状态; -- 单调递增的公开事件流; -- 工具调用摘要、持续时间和截断信息; -- Agent turns、token 与墙钟用量; -- 可下载的 Markdown/文本产物; -- 安全错误码、取消或超时结果。 +对话达到最低轮次后可以下载 `fde-technical-solution.md`。报告会把客户已经确认的事实、系统暂时采用的假设和仍待决定的问题分开,并整理范围、功能需求、数据接口、架构、安全要求、验收条件和研发移交事项。 -## 60 秒离线体验 +## 仓库任务会返回什么 -离线 Demo 不需要 OpenAI API Key,也不会产生模型费用: +输入自然语言任务和公开 Git URL: -```powershell -python -m venv .venv -.\.venv\Scripts\python.exe -m pip install -c requirements.lock -e ".[dev]" -Copy-Item .env.example .env -# 将 .env 中的 LLM_PROVIDER 改为 demo,SANDBOX_BACKEND 改为 local -.\scripts\start.ps1 +```json +{ + "instruction": "读取仓库,找出所有 TODO 和 FIXME,生成 Markdown 报告。", + "repository": { + "url": "https://github.com/example/project.git", + "ref": "main" + } +} ``` -启动后打开: - -- 首页: -- 需求挖掘: -- Swagger API: -- 就绪检查: - -也可以直接运行确定性示例: - -```powershell -.\.venv\Scripts\python.exe scripts\demo.py -``` +请求成功后会得到 Task ID。通过查询接口可以看到任务状态、执行事件、工具调用摘要、token/时间用量和最终产物。超时、取消、策略拒绝与普通执行失败使用不同的状态和错误码,方便调用方决定是否重试。 -该示例扫描 `examples/demo-repo` 中的 TODO/FIXME 并生成报告,用于验证完整任务生命周期。 +## 本地运行 -## 接入 OpenAI +第一次运行建议先使用 Demo Provider,不需要 OpenAI Key,也不会产生模型费用。 -复制配置文件: +### Windows PowerShell ```powershell +git clone https://github.com/aopays/cloud-agent-platform.git +cd cloud-agent-platform +python -m venv .venv +.\.venv\Scripts\python.exe -m pip install -c requirements.lock -e ".[dev]" Copy-Item .env.example .env +$env:LLM_PROVIDER = "demo" +$env:SANDBOX_BACKEND = "local" +.\scripts\start.ps1 ``` -只在本机 `.env` 中填写密钥,不要提交到 Git: +### Linux / macOS -```dotenv -LLM_PROVIDER=openai -OPENAI_API_KEY= -OPENAI_MODEL=gpt-5.4-mini -SANDBOX_BACKEND=local +```bash +git clone https://github.com/aopays/cloud-agent-platform.git +cd cloud-agent-platform +python3 -m venv .venv +./.venv/bin/python -m pip install -c requirements.lock -e ".[dev]" +cp .env.example .env +LLM_PROVIDER=demo SANDBOX_BACKEND=local bash scripts/start.sh ``` -然后启动: - -```powershell -.\scripts\start.ps1 -``` +启动后打开: -Linux/macOS 使用 `bash scripts/start.sh`。项目通过可替换的 `LLMProvider` 接口调用 OpenAI Responses API, -把本地工具转换成 function tools,并使用 `function_call_output` 继续模型—工具循环。实现与概念可参考 -[OpenAI Developer Quickstart](https://developers.openai.com/api/docs/quickstart) 和 -[Responses API Reference](https://developers.openai.com/api/reference/resources/responses/methods/create)。 +- **FDE 需求发现工作台**: +- **API 交互文档**: +- **运行就绪检查**: +- **产品首页**: -`/readyz` 只报告 Provider、模型、Sandbox 和目录状态,不返回 API Key。 +也可以不启动 Web 服务,直接验证任务生命周期: -## 提交仓库任务 +```powershell +.\.venv\Scripts\python.exe scripts\demo.py +``` -打开 Swagger 的 `POST /v1/tasks`,点击 **Authorize** 并在开发环境输入 `local-demo-token`。设置至少 8 个字符的 -`Idempotency-Key`,请求体示例: +这个 Demo 会扫描 `examples/demo-repo` 中的 TODO/FIXME。报告内容很简单,它的作用是提供一个稳定的端到端样例,用来检查队列、Worker、Runtime、事件和产物是否连通。 -```json -{ - "instruction": "读取仓库,找出所有 TODO 和 FIXME,生成 Markdown 报告。", - "repository": { - "url": "https://github.com/example/project.git", - "ref": "main" - } -} -``` +## 面试时怎么演示 -之后依次调用: +我通常按下面的顺序演示: -```text -GET /v1/tasks/{taskId} -GET /v1/tasks/{taskId}/events -GET /v1/tasks/{taskId}/artifacts -GET /v1/tasks/{taskId}/artifacts/{artifactId} -``` +1. 在 `/discovery` 输入“给物流公司设计司机排班软件”。 +2. 分三轮补充现在怎么排班、哪些规则不能违反、数据来自哪里,以及 PoC 怎样验收。 +3. 下载方案,重点看哪些内容是事实,哪些仍是假设。 +4. 打开 `/docs` 提交仓库扫描任务,查看事件和最终文件。 +5. 结合架构图解释为什么 API 不直接执行命令,以及取消如何传到正在运行的工具。 +6. 最后主动说明内存存储、单 Agent 和 Docker 隔离等限制。 -本地仓库必须位于 `REPOSITORY_IMPORT_ROOT` 下。当前版本只支持公开 HTTPS Git 仓库;私有仓库的任务级临时凭证 -注入属于下一阶段能力,请勿把 Token 拼进 URL。 +完整讲稿、常见追问、简历描述与诚实边界见 [FDE / AI Agent 面试展示包](docs/fde-interview-kit.md)。 -## 架构一览 +## 系统结构 ```mermaid flowchart LR - User[Web / API Client] --> API[FastAPI Control Plane] - API --> Repo[Task Repository] - API --> Queue[At-least-once Queue] + Customer[客户负责人] --> Discovery[FDE 多轮需求发现] + FDE[FDE / 方案架构师] --> Discovery + Discovery --> Plan[可执行技术方案] + + User[Web / API Client] --> API[FastAPI 控制面] + API --> Queue[任务仓储 + At-least-once Queue] Queue --> Worker[Worker + Lease + Heartbeat] Worker --> Prep[Repository Preparer] Worker --> Runtime[Bounded Agent Runtime] Runtime --> Provider[Demo / OpenAI Provider] - Runtime --> Registry[Tool Registry + Policy] - Registry --> Sandbox[Local trusted / Docker Sandbox] - Runtime --> Events[Monotonic Event Store] + Runtime --> Tools[Tool Registry + Policy] + Tools --> Sandbox[Local trusted / Docker Sandbox] + Runtime --> Events[Monotonic Events] Worker --> Artifacts[Content-addressed Artifacts] Events --> User Artifacts --> User ``` -核心设计是 **控制面与执行面分离**。API 不执行用户命令;Worker 负责租约、仓库、沙箱、Runtime、产物和终态; -Runtime 不直接调用宿主机 shell,而是通过结构化工具与 `SandboxSession` 交互。 +这里刻意把控制面和执行面分开。FastAPI 负责接收和查询任务,不直接执行用户命令;Worker 负责准备仓库、维护租约、启动沙箱和提交结果。Runtime 也不能直接调用宿主机 shell,只能使用注册过的工具,再由工具访问 `SandboxSession`。 + +## 从哪里开始读代码 + +- [`src/discovery.py`](src/discovery.py):FDE 访谈状态、就绪门禁、Provider Prompt 和技术方案生成。 +- [`src/agent_runtime/loop.py`](src/agent_runtime/loop.py):有界模型—工具循环,处理预算、取消、重试、重复调用和无进展终止。 +- [`src/agent_runtime/openai_provider.py`](src/agent_runtime/openai_provider.py):OpenAI Responses API 适配器,把注册工具映射为 function tools。 +- [`src/tools/`](src/tools/):工具注册、JSON Schema 校验、策略 Hook、超时、输出限额、脱敏与结果提交。 +- [`src/scheduler/`](src/scheduler/):任务状态机、幂等、队列投递、执行租约、心跳和取消传播。 +- [`src/worker.py`](src/worker.py):从领取任务到终态提交的纵向编排。 +- [`src/sandbox/`](src/sandbox/):本地可信与 Docker Session、路径和符号链接防护、进程树与资源策略。 +- [`src/storage.py`](src/storage.py):原子事件序列和内容寻址产物的 MVP 存储实现。 -完整图解见 [系统架构](docs/system-architecture.md),逐文件讲解见 [代码导览](docs/code-tour.md)。 +如果是第一次阅读,建议按 `src/main.py` → `src/platform.py` → `src/worker.py` → `src/agent_runtime/loop.py` 的顺序走一遍主流程。更细的说明放在 [代码导览](docs/code-tour.md) 和 [系统架构](docs/system-architecture.md) 中。 -## 技术栈 +## 实现时重点处理的问题 -- **API / Schema**:Python 3.10+、FastAPI、Pydantic v2、OpenAPI 3.1、SSE。 -- **Agent Runtime**:异步 Python、有界循环、Provider Adapter、结构化 function calling。 -- **调度与可靠性**:进程内队列/仓储/租约 MVP,at-least-once、幂等键、心跳与取消传播。 -- **工具系统**:JSON Schema 校验、权限策略、超时、输出限额、脱敏和结果提交。 -- **沙箱**:可信本地 Adapter、Docker Adapter、非 root、cap-drop、默认禁网和进程树清理。 -- **存储**:进程内事件/任务状态、本地内容寻址产物;接口预留 PostgreSQL、Redis、S3 替换点。 -- **工程质量**:Ruff、mypy strict、pytest、Windows/Linux CI、Docker smoke 与安全标记测试。 +- Agent 不能一直跑。模型轮次、输入 token、总时间、命令时间和工具输出都有上限。 +- 取消不是只改数据库状态。请求会传到 Runtime、工具协程,并触发进程树清理。 +- 队列按 at-least-once 设计,因此任务创建和终态提交必须考虑幂等与重复投递。 +- 日志不保存模型的私有思维链,只记录任务状态、行动摘要、工具、预算和错误。 +- Provider、队列、事件、产物与 Sandbox 使用接口隔开,后续可以替换实现。 +- Local Sandbox 只用于可信输入;Docker 配置了禁网、非 root、capabilities 和资源限制,但仍不是最终的强隔离方案。 -## 代码地图 +## 接入 OpenAI + +只在本机 `.env` 中填写 Key,永远不要提交到 Git: + +```dotenv +LLM_PROVIDER=openai +OPENAI_API_KEY= +OPENAI_MODEL=gpt-5.4-mini +SANDBOX_BACKEND=local +``` + +然后执行 `.\scripts\start.ps1`,Linux/macOS 执行 `bash scripts/start.sh`。`/readyz` 会显示 Provider、模型、Sandbox 和目录健康状态,但不会返回 API Key。 + +在 Swagger 的 `POST /v1/tasks` 中点击 **Authorize**,开发环境 Token 输入 `local-demo-token`;请求头 `Idempotency-Key` 至少 8 个字符。使用返回的 Task ID 查询: ```text -src/ -├── main.py # FastAPI composition root、SSE、下载与健康检查 -├── platform.py # Provider、Queue、Sandbox、Worker 的依赖装配 -├── worker.py # 从领取任务到终态提交的执行编排 -├── discovery.py # 多轮需求挖掘、结构化会话与报告生成 -├── agent_runtime/ # 模型—工具循环、预算、事件、OpenAI Adapter -├── api/ # Task/Discovery 路由与 Pydantic Schema -├── scheduler/ # 状态机、队列、租约、取消和幂等 -├── sandbox/ # 路径、进程、资源策略、本地与 Docker Session -├── tools/ # Tool Registry、Schema 校验和内置工具 -├── models/ # 任务与 Attempt 领域模型 -└── shared/ # 公共契约、接口与配置 +GET /v1/tasks/{taskId} +GET /v1/tasks/{taskId}/events +GET /v1/tasks/{taskId}/artifacts +GET /v1/tasks/{taskId}/artifacts/{artifactId} ``` -## 文档中心 +当前只支持公开 HTTPS 仓库。`file://` 仓库必须位于 `REPOSITORY_IMPORT_ROOT` 下;不要把仓库凭证写进 URL。 -- [文档导航](docs/README.md):按产品、开发、架构、安全、测试和发布查阅。 -- [产品定位与需求](docs/product-positioning.md):谁会用、解决什么问题、MVP 范围和成功指标。 -- [代码导览](docs/code-tour.md):像代码解释器一样按入口、调用链和模块阅读项目。 +## 相关文档 + +- [FDE / AI Agent 面试展示包](docs/fde-interview-kit.md):3 分钟讲稿、Demo、常见追问、STAR 和简历写法。 +- [FDE 客户需求发现手册](docs/fde-discovery-playbook.md):访谈阶段、证据模型、就绪门禁和研发移交。 +- [产品定位与需求](docs/product-positioning.md):目标用户、业务痛点、MVP 范围和成功指标。 - [系统架构](docs/system-architecture.md):上下文、容器、组件、时序、信任边界和演进架构图。 -- [完整软件开发生命周期](docs/sdlc/README.md):PRD、SRS、数据/API、开发、测试、安全、发布、SRE 与移交。 -- [多 Agent 目标架构](docs/multi-agent-platform-architecture.md):需求、设计与开发团队的 DAG 和角色边界。 -- [安全策略](SECURITY.md) 与 [沙箱安全边界](docs/security-boundary.md)。 -- [贡献指南](CONTRIBUTING.md) 与 [发布前检查清单](docs/release-checklist.md)。 +- [完整软件开发生命周期](docs/sdlc/README.md):PRD、SRS、数据/API、开发、测试、安全、发布和 SRE。 +- [多 Agent 目标架构](docs/multi-agent-platform-architecture.md):需求、架构、安全与 QA Agent 的 DAG 设计。 +- [安全边界](docs/security-boundary.md) 与 [安全策略](SECURITY.md):威胁模型、已实现控制和生产缺口。 +- [对标仓库增长分析](docs/open-source-growth-analysis.md):哪些传播方法值得学习,哪些夸大方式不应该复制。 -## 已实现、未实现与演进方向 +## 当前做到哪里 -### 已实现(As-Is) +现在已经可以跑通: +- FDE 多轮需求发现、就绪判断、技术方案生成和下载; - 任务创建、查询、取消、事件与产物 API; -- 模糊需求的多轮澄清页面与设计报告下载; -- Worker、可见性超时、租约、心跳、幂等与状态机; -- Demo/OpenAI Provider、Agent Loop、工具注册表与预算; -- 本地可信与 Docker 沙箱 Adapter; -- 路径逃逸防护、输出限制、超时、取消和秘密脱敏; -- 自动化单元、集成、端到端和安全测试; -- Docker、Compose、Windows/Linux 启动与 CI 基线。 +- Demo/OpenAI Provider、有界 Agent Loop、工具注册与预算; +- 本地可信和 Docker Sandbox Adapter; +- 路径逃逸、超时、取消、输出限额和秘密脱敏; +- 单元、集成、端到端、安全测试与跨平台 CI。 -### 下一阶段(Next) +下面这些还没有实现,是后续可能继续做的内容: - PostgreSQL、Redis、S3/MinIO 持久化 Adapter; -- 真实用户与租户、OIDC、RBAC、配额、限流和成本中心; -- 私有 Git 仓库的短期最小权限凭证注入; -- SSE 持续订阅、任务列表和更完整的 Web 控制台; -- 需求/架构/安全/QA 多 Agent DAG 与独立质量门; -- Temporal/Kubernetes、Worker 分池、强沙箱和灾备。 +- OIDC、租户、RBAC、配额、限流、成本中心和审计; +- 私有 Git 仓库的短期最小权限凭证; +- 任务列表、持续 SSE 和完整 Web Console; +- 需求、架构、安全、QA 多 Agent DAG 与独立质量门; +- Temporal/Kubernetes Worker 与 gVisor、Kata 或 Firecracker 强隔离。 -## 安全边界 +## 当前限制 -- `SANDBOX_BACKEND=local` 只允许可信开发输入,且在非 development/test 环境被拒绝。 -- Docker 是 MVP 隔离,不是运行任意恶意代码的最终边界;生产应评估 gVisor、Kata 或 Firecracker。 -- 默认不向沙箱开放网络,不挂载宿主 Docker socket,不把密钥放进模型上下文、事件、日志或产物。 -- 所有路径、命令参数和工具输出都必须经过策略与边界检查。 -- 生产环境必须替换默认 Bearer Token,并补齐身份、租户、持久化、限流、审计和密钥管理。 +任务、队列和事件目前主要保存在进程内,服务重启后不能恢复。`SANDBOX_BACKEND=local` 只适合自己控制的代码,并且在非 development/test 环境会被拒绝。Docker Adapter 增加了一层隔离,但不能据此运行任意恶意代码。若要用于生产环境,至少还需要补充真实身份、多租户隔离、持久化、限流、托管密钥和更强的沙箱。 -详细威胁模型见 [docs/security-boundary.md](docs/security-boundary.md)。 +详细威胁模型见 [docs/security-boundary.md](docs/security-boundary.md)。安全问题请通过 GitHub Security Advisories 私下报告。 -## 开发验证 +## 我用这些命令检查项目 ```powershell .\.venv\Scripts\python.exe -m ruff format --check . @@ -241,19 +232,16 @@ src/ .\.venv\Scripts\python.exe -m compileall -q src tests scripts ``` -离线端到端烟测: +## 参与项目 -```powershell -.\.venv\Scripts\python.exe scripts\smoke_test.py --base-url http://127.0.0.1:8001 -``` +如果你发现了可以复现的 Agent 失败、沙箱绕过方式,或者愿意补持久化 Adapter 和 Web 页面,可以先开 Issue 说明场景。提交代码前请阅读 [CONTRIBUTING.md](CONTRIBUTING.md)。项目使用 [MIT License](LICENSE)。 + +如果这个项目对你有用,可以点一个 Star 方便以后找到。也欢迎在 [Issues](https://github.com/aopays/cloud-agent-platform/issues) 留下真实需求;比起“再加一个 Agent”,我更希望后续功能来自可以复现的问题。 -## 开源协作 +## English overview -如果这个项目对你理解 Agent 编排、工具调用、沙箱或 AI 应用工程化有帮助,欢迎: +Cloud Agent Platform started as an AI application engineering interview project. It combines an FDE requirement-discovery workflow with a small, bounded runtime for repository tasks. -- ⭐ Star:让更多正在做 Agent Platform 的开发者看到它; -- 🐛 Issue:提交可复现的缺陷、威胁场景或真实业务需求; -- 🧪 Eval:贡献代表性任务、黄金答案和安全回归样例; -- 🔧 Pull Request:优先完善持久化 Adapter、Web Console、质量评测和强隔离。 +The current version runs locally and includes multi-turn discovery, task/event/artifact APIs, Demo and OpenAI providers, validated tools, cancellation, budgets, and local/Docker sandbox adapters. State is mostly in memory and the product runtime is still single-agent; the multi-agent DAG in the documentation is a future design. -提交前请阅读 [CONTRIBUTING.md](CONTRIBUTING.md)。本项目使用 [MIT License](LICENSE)。 +Start with the [local setup](#本地运行), read the [system architecture](docs/system-architecture.md), or use the [interview notes](docs/fde-interview-kit.md). diff --git a/README.zh-CN.md b/README.zh-CN.md new file mode 100644 index 0000000..7850142 --- /dev/null +++ b/README.zh-CN.md @@ -0,0 +1,7 @@ +# Cloud Agent Platform 中文文档 + +中文产品介绍已经移到仓库默认首页,避免两份长 README 在功能、命令和安全边界上发生漂移。 + +- [打开完整中文 README](README.md) +- [跳转到英文概览](README.md#english-overview) +- [打开文档中心](docs/README.md) diff --git a/docs/README.md b/docs/README.md index 61afdb8..d04ac5a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -5,13 +5,15 @@ ## 第一次了解项目 1. [项目首页](../README.md):价值、能力、启动和演示路径。 -2. [产品定位与需求](product-positioning.md):目标用户、核心场景、MVP 范围和指标。 -3. [系统架构](system-architecture.md):从系统上下文到组件、时序和部署。 -4. [代码导览](code-tour.md):从 `src/main.py` 开始逐层读懂代码。 +2. [FDE / AI Agent 面试展示包](fde-interview-kit.md):三分钟讲稿、现场 Demo、常见追问和简历写法。 +3. [产品定位与需求](product-positioning.md):目标用户、核心场景、MVP 范围和指标。 +4. [系统架构](system-architecture.md):从系统上下文到组件、时序和部署。 +5. [代码导览](code-tour.md):从 `src/main.py` 开始逐层读懂代码。 ## 想运行或二次开发 -- [需求挖掘功能](requirement-discovery.md) +- [FDE 客户需求发现工作手册](fde-discovery-playbook.md) +- [FDE 多轮需求发现功能](requirement-discovery.md) - [MVP 需求基线](requirements.md) - [MVP 架构基线](architecture.md) - [验收标准](acceptance-criteria.md) @@ -27,6 +29,11 @@ - [需求场景评测](reviews/discovery-scenario-evaluation.md) - [任务看板与决策记录](task-board.md) +## 想了解开源传播与项目包装 + +- [对标仓库增长分析](open-source-growth-analysis.md):用公开数据拆解搜索入口、首屏转化、面试资料和 Star 路径。 +- [FDE / AI Agent 面试展示包](fde-interview-kit.md):把可运行能力转成有证据的项目讲解,不虚构业务和性能指标。 + ## 想看真实软件生命周期 [SDLC 文档中心](sdlc/README.md)覆盖产品、SRS、数据/API、多 Agent 编排、开发、测试、安全、发布、SRE、 diff --git a/docs/assets/cloud-agent-platform-hero.svg b/docs/assets/cloud-agent-platform-hero.svg new file mode 100644 index 0000000..5abb9d5 --- /dev/null +++ b/docs/assets/cloud-agent-platform-hero.svg @@ -0,0 +1,70 @@ + + Cloud Agent Platform + FDE discovery and bounded, auditable AI agent workflows. + + + + + + + + + + + + + + + + + + + + + + + + + OPEN-SOURCE MVP + Cloud Agent Platform + Customer evidence → executable plan → bounded agents. + + + + + 01 / INPUT + Customer need + or Git repository + + + + + + 02 / DISCOVER + Probe + structure + facts, owners, constraints + + + + + + 03 / OUTPUT + Technical plan + executable and auditable + + + + OpenAI Responses API + + FastAPI + + Docker Sandbox + + Python + + + + + + + diff --git a/docs/code-tour.md b/docs/code-tour.md index 8a2fdba..618cfa8 100644 --- a/docs/code-tour.md +++ b/docs/code-tour.md @@ -203,13 +203,14 @@ no-new-privileges、CPU/内存/PID/临时盘限制。Docker 控制命令与用 `LocalArtifactStore` 使用 SHA-256 和逻辑名称实现内容校验与幂等,限制单产物大小,并把真实存储路径隐藏在 API 响应之后。当前元数据在内存中,重启后不恢复;生产 Adapter 应使用 PostgreSQL + S3/MinIO。 -## 11. 需求挖掘:`src/discovery.py` +## 11. FDE 客户需求发现:`src/discovery.py` -Discovery 是与仓库任务并列的产品模块: +Discovery 是与仓库任务并列的产品模块,也是 FDE 进入客户后的前置工作台: - `DiscoveryService` 管理会话、消息、状态和最终报告; -- `DemoDiscoveryAssistant` 提供可重复、无需费用的确定性流程; -- `ProviderDiscoveryAssistant` 使用同一 LLMProvider 做开放式澄清; +- `DemoDiscoveryAssistant` 提供可重复、无需费用的确定性 FDE 访谈流程; +- `ProviderDiscoveryAssistant` 使用同一 LLMProvider 按就绪门禁追问实施阻塞项; +- 报告严格区分事实、假设、决策、风险和开放问题,并形成研发与 QA 移交清单; - `src/discovery_ui.py` 是无构建步骤的单页演示 UI; - `src/api/discovery_routes.py` 提供创建、追加消息、完成和下载接口。 diff --git a/docs/contracts/openapi.yaml b/docs/contracts/openapi.yaml index 5a11b78..6ce77c7 100644 --- a/docs/contracts/openapi.yaml +++ b/docs/contracts/openapi.yaml @@ -2,7 +2,7 @@ openapi: 3.1.0 info: title: Cloud Agent Platform API version: 0.1.0 - description: P0 contract for task lifecycle, events, and artifacts. + description: P0 contract for FDE discovery, task lifecycle, events, and artifacts. servers: - url: http://localhost:8000 security: @@ -11,7 +11,7 @@ paths: /v1/discovery-sessions: post: operationId: createDiscoverySession - summary: Start a multi-turn requirement discovery conversation + summary: Start a multi-turn FDE customer discovery conversation requestBody: required: true content: @@ -45,7 +45,7 @@ paths: /v1/discovery-sessions/{sessionId}/messages: post: operationId: addDiscoveryMessage - summary: Answer questions and continue requirement discovery + summary: Record customer evidence and continue FDE discovery parameters: - $ref: '#/components/parameters/DiscoverySessionId' requestBody: @@ -68,7 +68,7 @@ paths: /v1/discovery-sessions/{sessionId}/finalize: post: operationId: finalizeDiscoverySession - summary: Generate the software design report + summary: Generate the FDE technical discovery and solution report parameters: - $ref: '#/components/parameters/DiscoverySessionId' responses: @@ -83,12 +83,12 @@ paths: /v1/discovery-sessions/{sessionId}/report: get: operationId: downloadDiscoveryReport - summary: Download the finalized Markdown software design report + summary: Download the finalized Markdown FDE technical solution parameters: - $ref: '#/components/parameters/DiscoverySessionId' responses: '200': - description: Software design report + description: FDE technical discovery and solution report content: text/markdown: schema: diff --git a/docs/fde-discovery-playbook.md b/docs/fde-discovery-playbook.md new file mode 100644 index 0000000..2b2dcab --- /dev/null +++ b/docs/fde-discovery-playbook.md @@ -0,0 +1,127 @@ +# FDE 客户需求发现工作手册 + +## 1. 产品使命 + +本项目把需求发现模块定位为 Forward Deployed Engineer(FDE)的前置工作台。它服务于 FDE、解决方案架构师、 +AI 应用工程师和技术交付负责人第一次进入客户现场的阶段:把企业负责人的业务语言、现状抱怨和零散想法,转成 +一份能够被架构、开发、QA、安全和客户共同评审的技术发现包。 + +它不追求“多聊几轮”,而追求每次沟通都减少一个实施风险,最终回答五个问题: + +1. 客户为什么现在必须解决这个问题? +2. 谁使用、谁提供数据、谁承担变更、谁最终决策? +3. 第一版具体做什么、不做什么? +4. 技术和组织前置条件是否真实存在? +5. 用什么证据决定 PoC/MVP 成功或停止? + +## 2. 需要解决的真实痛点 + +- 客户负责人描述的是方案名或症状,例如“做一个 AI 平台”,而不是可验证的问题。 +- 销售、业务、技术和一线用户使用不同语言,同一个词对应不同预期。 +- 会议反复讨论功能,却没有现状基线、数据样例、系统负责人和决策权限。 +- FDE 过早承诺技术方案,后续才发现数据拿不到、接口不存在、安全不允许或验收标准不一致。 +- 需求从 FDE 移交到研发时丢失上下文,最终变成范围蔓延、重复返工和责任争议。 + +## 3. 拒绝无效沟通的原则 + +### 3.1 从抽象词追到证据 + +客户说“系统要快”,继续追问哪个操作、现状耗时、目标耗时、测量口径和峰值规模。客户说“要智能”,继续追问 +由谁做决策、允许多大错误、错误成本、人工复核方式和可用训练或评测数据。 + +### 3.2 不重复已回答的问题 + +每轮先复用已有证据,只询问会阻塞范围、技术可行性、验收或交付承诺的缺口。问题数量控制在 3 到 5 个, +让客户可以在一次回复中给出高质量答案。 + +### 3.3 不把假设伪装成客户需求 + +所有内容按以下类型管理: + +- `FACT`:客户明确表达且最好有业务数据、文档或实例支撑。 +- `ASSUMPTION`:为了形成草案暂时采用,必须有责任人和确认日期。 +- `DECISION`:经过有权限的人确认的范围、规则或技术选择。 +- `RISK`:可能影响成本、进度、安全、质量或可行性的事项。 +- `OPEN`:尚未回答且会阻塞实施或验收的问题。 + +### 3.4 先确定问题,再选择技术 + +在业务结果、As-Is 流程、规模、边界和验收证据没有形成之前,不承诺微服务、模型、数据库或具体供应商。 +技术栈必须服务于已确认约束,而不是反过来创造需求。 + +## 4. FDE 访谈阶段 + +### 阶段 A:业务结果与决策机制 + +确认需求发起人、业务负责人、最终决策人、一线用户、预算和 Go/No-Go 机制。要求客户说明为什么现在做、 +不做的损失、希望改变的业务指标,以及谁有权确认这些指标。 + +### 阶段 B:As-Is 流程与痛点证据 + +使用一个最近发生的真实案例走查当前流程,记录每一步的负责人、输入、输出、等待时间、错误、返工和人工兜底。 +至少获得一种证据:样例数据、流程截图、工单、报表、会议纪要或系统日志。 + +### 阶段 C:范围、规则与异常 + +确定主流程、硬规则、常见例外、审批、人工覆盖和审计要求。明确 MVP 范围、非目标和变更流程,避免把未来愿景 +包装成当前承诺。 + +### 阶段 D:数据、集成与安全 + +为每个数据源和外部系统确认业务用途、负责人、接口、字段样例、规模、质量、更新频率、测试环境、权限、 +敏感等级、失败策略和预计可用日期。 + +### 阶段 E:PoC、MVP 与交付承诺 + +把成功写成可现场执行的 Given/When/Then,定义现状基线、目标阈值、测量窗口、数据来源和验收负责人。 +确认时间、预算、客户配合人、部署条件、运维责任和停止条件。 + +## 5. 技术方案就绪门禁 + +完成三轮只代表可以生成草案。以下九项没有阻塞缺口,才可以把方案标记为“可进入工程评审”: + +1. 业务结果、现状基线和成功指标; +2. 业务负责人、技术负责人、数据负责人和最终决策人; +3. 一线用户、场景、频率、规模和主流程; +4. MVP 范围、非目标、优先级和变更机制; +5. 业务规则、异常、人工兜底和审计要求; +6. 数据来源、样例、质量和责任人; +7. 外部系统、接口、测试环境和集成失败策略; +8. 安全、隐私、合规、部署和运维边界; +9. PoC/MVP 验收阈值、预算时间和 Go/No-Go 流程。 + +用户可以提前生成报告,但系统必须把缺口保留为开放问题,而不是自动补成客户承诺。单会话最多 12 个用户轮次, +用于避免无限对话;达到上限仍有阻塞项时,应升级为人工专题会议。 + +## 6. 最终交付物 + +FDE 技术发现报告至少包含: + +- 执行摘要和原始需求; +- 客户原话、事实、假设、决策、风险和开放项; +- Stakeholder/决策地图和责任边界; +- As-Is 流程、量化痛点和 To-Be 业务目标; +- MVP 范围、非目标、可追踪需求 ID、规则和异常; +- 数据与集成责任矩阵; +- 技术架构、接口、安全、可靠性和非功能要求; +- PoC 与 MVP 验收标准; +- 交付计划、依赖、风险和 Go/No-Go 条件; +- 给架构、开发、QA 和安全团队的移交清单。 + +## 7. 成功指标 + +- 首次客户访谈后关键维度覆盖率; +- 每个关键结论的证据关联率; +- 报告中未确认假设的数量和关闭周期; +- 进入开发后因需求误解产生的返工率; +- PoC 验收争议率和 Go/No-Go 决策周期; +- FDE 到研发移交后新增阻塞问题的数量; +- 客户会议时长不作为单独成功指标,减少无效轮次同时提高决策密度才是目标。 + +## 8. 产品边界 + +- 工具辅助 FDE 组织问题和证据,不替代客户业务负责人做决定。 +- 报告是技术方案草案,不是合同、法律意见、安全认证或自动交付承诺。 +- 对话质量取决于客户输入;关键事实必须由有权限的人确认。 +- 高风险行业仍需领域专家、法务、安全和合规团队参与。 +- 当前会话使用进程内存,不具备生产级 CRM、权限、长期留存和多人协作能力。 diff --git a/docs/fde-interview-kit.md b/docs/fde-interview-kit.md new file mode 100644 index 0000000..adf3754 --- /dev/null +++ b/docs/fde-interview-kit.md @@ -0,0 +1,169 @@ +# FDE / AI Agent 面试展示包 + +这份材料帮助候选人把项目讲成一个可验证的工程案例,而不是背诵 README。所有表述必须能在代码、测试、文档或现场演示中找到证据;没有测量过的性能、用户量和业务收益不要写进简历。 + +## 一句话版本 + +我实现了一个面向 FDE 前期客户沟通的需求发现工作台,并把技术方案后续可能需要的仓库任务接到一个有预算、可取消、可审计、通过沙箱执行工具的 Cloud Agent 运行平台。 + +## 三分钟项目讲稿 + +### 0:00~0:30:问题 + +FDE 面对企业客户时,经常只得到十几个字的模糊需求。直接生成 PRD 会把假设当事实,反复开会又会拖慢交付。另一方面,真正运行代码 Agent 不能只有 Prompt,还必须解决任务调度、工具权限、取消、资源上限、审计和失败恢复。 + +### 0:30~1:10:产品 + +系统有两条链路。第一条是多轮需求发现:围绕业务结果、现状证据、范围、规则、数据、集成、安全和验收继续追问,达到最低轮次后仍会检查实施阻塞,最后输出 FDE 技术方案。第二条是仓库任务:用户提交自然语言指令和 Git URL,平台排队后由 Worker 启动 Agent Runtime,通过受控工具完成任务并返回事件和产物。 + +### 1:10~2:10:架构决策 + +FastAPI 只承担控制面,不直接执行命令。调度层用状态机、幂等键、at-least-once 队列、租约和心跳描述任务语义。Worker 负责仓库、沙箱、Runtime、产物和终态。Runtime 是有界模型—工具循环,Provider 可替换,工具先经过 Schema 与策略校验,再调用 Sandbox Session。公开事件只记录行动摘要,不保存模型私有思维链。 + +### 2:10~2:40:安全与可靠性 + +模型轮次、token、墙钟、命令时间和输出都有上限;取消会传播到工具协程和进程树。路径穿越、符号链接逃逸、秘密脱敏、默认禁网、非 root 和最小 capabilities 都有实现或测试。Local Sandbox 只允许可信开发输入,Docker 也被明确标成 MVP 隔离而不是最终安全边界。 + +### 2:40~3:00:诚实边界 + +当前是单进程内存型 MVP,真实 OpenAI Provider 和离线 Demo 都已实现。PostgreSQL、Redis、S3、多租户认证、强沙箱、Temporal/Kubernetes 和运行时多 Agent DAG 是下一阶段设计,不会把它们宣称为已上线能力。 + +## 五分钟现场 Demo + +### 演示前检查 + +```powershell +Copy-Item .env.example .env +$env:LLM_PROVIDER = "demo" +$env:SANDBOX_BACKEND = "local" +.\scripts\start.ps1 +``` + +打开 `/readyz`,确认服务、Provider、Sandbox 和目录就绪。面试演示优先使用 Demo Provider,避免网络、余额和模型波动;OpenAI 连接作为补充能力展示。 + +### 第一分钟:模糊需求 + +打开 `/discovery`,输入: + +```text +给物流公司设计一个司机排班软件,主要给货车司机使用。 +``` + +解释为什么系统不马上生成“看起来完整”的方案:决策人、现状数据、约束和验收尚未形成证据。 + +### 第二至三分钟:三轮收敛 + +可以用以下信息模拟客户回答,但现场应保持自然语言: + +1. 当前由 3 名调度员用 Excel 为 180 名司机排班,每周约 12 次人工改班;目标是把排班时间从 4 小时降到 30 分钟,运营总监决策。 +2. 司机必须满足驾照、工时、休息、车型和区域限制;临时病假、车辆故障与急单允许调度员人工覆盖,并记录原因。 +3. 订单来自 TMS、司机信息来自 HR、车辆来自车队系统;PoC 用脱敏历史数据,要求硬约束零违规,计划可解释并支持人工确认。 + +强调:三轮只代表允许生成草案;关键实施阻塞未关闭时,系统仍会继续追问。 + +### 第四分钟:检查报告 + +下载 `fde-technical-solution.md`,快速定位: + +- 客户事实与默认假设是否分开; +- Scope / Non-goals 是否明确; +- FR、数据源、系统 Owner 和接口是否可落到研发; +- NFR、安全、PoC/MVP 验收是否可测试; +- Open Decisions、风险和 Go/No-Go 是否能支持评审。 + +### 第五分钟:Agent 执行闭环 + +打开 `/docs`,Authorize 使用开发 Token `local-demo-token`,调用 `POST /v1/tasks` 后依次查看任务、事件与产物。说明离线 TODO 扫描不是产品最终目标,而是一个确定性 Golden Path,用于稳定验证完整生命周期。 + +## 高频面试问题与回答框架 + +### 1. 为什么不是直接让大模型生成 PRD? + +直接生成会用语言流畅度掩盖证据不足。系统先要求业务指标、Owner、规则、数据和验收;报告把事实、假设、决策和风险分开。LLM 的职责是推进和整理,不是替客户决定未知信息。 + +### 2. 为什么控制面与执行面要分离? + +API 请求生命周期短且暴露给用户,命令执行长、危险且需要资源隔离。分离后可以独立扩缩、限制权限、恢复 Worker、管理租约,并避免 Web 进程直接运行不可信代码。 + +### 3. 为什么选择 FastAPI 和 Python? + +Python 与模型 SDK、异步工具生态契合,FastAPI 提供类型化 Schema、依赖注入和 OpenAPI,适合快速建立 API 契约。代价是 CPU 密集任务不应留在 API 进程,生产执行层需要独立 Worker 与持久化队列。 + +### 4. 为什么需要 at-least-once,而不是 exactly-once? + +分布式 exactly-once 通常最终依赖幂等。队列允许重复投递,业务层用幂等键、Attempt、租约和终态保护吸收重复,语义更可实现也更容易故障恢复。 + +### 5. Worker 崩溃后怎么办? + +当前内存 MVP 展示租约和心跳语义,但进程重启会丢状态。生产方案需要持久化任务/Attempt、可见性超时队列、租约到期回收、幂等终态提交和内容寻址产物。 + +### 6. 怎样阻止 Agent 无限循环和烧 Token? + +Runtime 同时限制轮次、输入 token 和墙钟时间,Provider 有有限重试;重复调用与无进展检测会提前终止。命令和工具还有独立超时与输出上限。 + +### 7. Prompt Injection 怎么处理? + +不能只靠系统 Prompt。仓库内容被视为不可信数据;工具白名单、结构化参数、策略 Hook、文件根目录、默认禁写/禁网、秘密隔离和 Sandbox 才是强制边界。模型即使被诱导,也不应获得越权能力。 + +### 8. Docker Sandbox 是否足够安全? + +不够。它是 MVP 隔离层,需要非 root、cap-drop、禁网、只读或受限挂载、资源/PID/时间限制,并且不能挂宿主 Docker socket。面对恶意多租户代码应评估 gVisor、Kata 或 Firecracker 和专用 Worker 节点。 + +### 9. 为什么不记录完整思维链? + +私有思维链不是可靠审计接口,还可能包含敏感数据。系统记录状态变化、行动摘要、工具名、参数摘要、输出截断、预算和错误,既支持运维审计,又控制隐私与存储风险。 + +### 10. 为什么事件 sequence 必须原子分配? + +Runtime 和任务生命周期可能并发写同一个 Attempt。若都先读最大序号再加一,就会发生冲突或丢事件。事件存储负责原子分配递增序号,生产环境可使用数据库序列、事务或分区日志。 + +### 11. 这是多 Agent 项目吗? + +要区分两个层面。开发过程可以由 backend、runtime、sandbox、QA 等多个专业 Agent 并行协作;当前产品运行时是一个有工具的 Agent。需求/架构/安全/QA 多 Agent DAG 已有目标设计,但没有伪装成已实现功能。 + +### 12. 你会怎样把它升级到生产? + +先做身份和租户边界,再替换 PostgreSQL/Redis/S3 Adapter,加入配额、限流、成本和审计;执行层使用独立 Worker 池、短期凭证和强沙箱;建立 Eval、SLO、追踪、告警和灾备。最后才在有质量门和状态持久化后扩展多 Agent DAG。 + +## STAR 表达模板 + +### Situation + +面试场景要求在七天内设计一个能接收自然语言任务、调用 LLM 和工具、在隔离环境执行并返回结果的 Cloud Agent Platform;同时,模糊需求需要先被结构化。 + +### Task + +我的目标不是只做一个聊天 Demo,而是交付一条可运行的纵向闭环,并能解释需求、架构、安全、测试、限制和生产演进。 + +### Action + +- 先冻结需求、OpenAPI、事件和安全边界,再拆分 API/调度、Runtime/工具和 Sandbox 三个领域; +- 建立控制面/执行面分离、任务状态机、幂等、租约、取消、预算和产物语义; +- 实现 Demo/OpenAI Provider、结构化工具调用与多轮 FDE 需求发现; +- 用单元、集成、E2E、安全测试和第二轮 QA/可靠性审查关闭并发事件、OpenAPI 与 Provider 等缺口; +- 用 As-Is / Next / Target 文档避免把规划能力当成已实现能力。 + +### Result + +最终形成了可离线运行、可接 OpenAI、可浏览 API、可生成需求方案与仓库报告的 MVP,并建立跨平台 CI、安全扫描、完整 SDLC 文档和可复现演示。结果部分只陈述仓库中可验证的产物;如需填写测试数量或耗时,应在提交简历当天重新运行并记录。 + +## 简历描述模板 + +可根据应聘方向选择 2~3 条,不要全部堆入一段: + +- 设计并实现 Cloud Agent Platform MVP,将 FastAPI 控制面、任务调度、Worker、Agent Runtime、工具注册、Sandbox、事件和产物串成可运行闭环。 +- 基于 OpenAI Responses API 实现可替换 Provider 与结构化 Function Calling,通过轮次、token、墙钟、重复调用和无进展检测约束 Agent 执行。 +- 面向 FDE 客户访谈设计多轮需求发现和就绪门禁,把模糊描述转换为包含事实、假设、范围、数据、架构、验收和 Go/No-Go 的技术方案。 +- 实现幂等键、at-least-once 投递、租约/心跳、取消传播、原子事件序列和内容寻址产物,覆盖重复投递与并发取消等失败路径。 +- 建立 Docker MVP 沙箱与路径、进程、网络、资源和秘密边界,并用自动化安全测试验证逃逸和清理场景。 + +## 面试时主动说明的限制 + +- 当前状态、队列、租约和事件主要为进程内实现,不具备重启持久性; +- Local Sandbox 只适合可信输入,Docker 也不是任意敌对代码的最终隔离; +- 私有仓库短期凭证、多租户认证、RBAC、限流和成本中心尚未实现; +- 当前产品运行时是单 Agent,多 Agent DAG 是设计路线; +- Demo Provider 的 TODO 报告用于确定性验收,不代表通用业务智能; +- 未经负载测试,不声称吞吐、并发或延迟达到某个数值。 + +主动说明这些限制通常比模糊地说“后续会优化”更能体现工程判断。 diff --git a/docs/open-source-growth-analysis.md b/docs/open-source-growth-analysis.md new file mode 100644 index 0000000..e8cd528 --- /dev/null +++ b/docs/open-source-growth-analysis.md @@ -0,0 +1,101 @@ +# 开源项目增长对标分析 + +## 目的与边界 + +本分析用于理解 GitHub 浏览者为什么会点击、继续阅读、运行并 Star 一个项目。参考样本是 +[`bcefghj/multi-agent-ecommerce-system`](https://github.com/bcefghj/multi-agent-ecommerce-system)。 + +这里复用的是信息组织和用户转化方法,不复制对方文案、代码、图片或未经验证的宣传结论。 + +## 公开数据快照 + +快照时间:2026-08-22,数据来自 GitHub 公开仓库元数据和默认分支。 + +- 518 Stars、77 Forks,Fork/Star 约为 14.9%; +- 2026-04-05 创建并完成最近一次推送; +- 默认分支共有 2 次提交、1 位公开贡献者; +- 2 个 Issues、1 个 Pull Request、0 个 Releases; +- 未设置仓库 Topics、未声明可识别 License、未配置自定义 Open Graph 图片; +- 默认分支目录中没有发现 GitHub Actions 工作流。 + +这些数据说明它获得关注的主要优势很可能不是长期提交活跃度、Release 运营或社区治理,而是选题、内容传播和首屏转化。Star 不等于生产成熟度,但 77 个 Fork 表明不少浏览者愿意复制后继续查看或修改。 + +## 它为什么容易获得 Star + +### 1. 一眼就能理解的搜索入口 + +仓库名同时覆盖 multi-agent、ecommerce 和 system 三个高意图关键词。描述直接说明多 Agent、电商、推荐/营销和多语言,没有要求读者先理解抽象平台概念。 + +### 2. 对目标人群的承诺非常具体 + +README 不只说“实现了多 Agent”,而是同时服务两类明确用户:想快速学会的初学者,以及需要面试项目材料的求职者。运行代码、代码讲解、面试问题和简历模板组合成了一个完整结果,而不是一堆孤立模块。 + +### 3. 首屏先讲价值,再讲实现 + +它先回答“是什么、解决什么、我能得到什么”,随后才进入架构和代码。浏览者不需要滚动到文件树或安装步骤才能判断相关性。 + +### 4. 具体业务降低认知成本 + +电商推荐、营销、库存和客服是容易想象的业务问题。每个 Agent 都有明确角色,使抽象编排概念变成可讲述的业务协作。 + +### 5. 大量可扫描的视觉锚点 + +徽章、目录、架构图、Agent 分解、代码片段、语言对比和编号步骤让长 README 仍然可以跳读。读者能在几十秒内找到自己关心的部分。 + +### 6. 把“学习”延伸到“求职结果” + +项目同时提供面试问题、简历写法、项目讲解和 STAR 表达。对求职者而言,Star 不只是收藏代码,也是收藏一套以后会再次使用的资料。 + +### 7. 启动阻力低,转化动作明确 + +复制命令即可启动,README 末尾明确邀请 Star 和 Issue。用户从看到项目到采取行动的路径很短。 + +## 不应该照搬的部分 + +- **不要用 Star 数替代工程证据**:提交少、无 Release、无 License、无 CI 并不妨碍传播,但会影响专业审查与真实采用。 +- **不要宣传没有实现的能力**:多语言、企业级、生产可用和性能指标都应有代码、测试或测量方法支持。 +- **不要无限拉长 README**:教程内容如果无法快速定位,会稀释核心产品叙事;深入材料应进入 docs。 +- **不要为了关键词扩张范围**:三个语言实现可能提高搜索覆盖,但也放大维护和一致性成本。 +- **不要隐藏限制**:面试官通常会追问持久化、租户、安全和容灾。主动说明 As-Is 与 Target 比假装完整更可信。 + +## Cloud Agent Platform 的复用策略 + +### 搜索层 + +使用 FDE、customer discovery、AI agents、Cloud Agent、requirements engineering、system design、sandbox、tool calling 等与真实实现匹配的关键词。 + +### 首屏层 + +先给出一个客户模糊需求,再说明两条可运行链路、目标人群和最终产物。浏览者不需要先理解“控制面/执行面”才能理解产品价值。 + +### 证据层 + +把架构、关键源码、CI、安全策略、测试命令和实现/规划边界放在同一条阅读路径上。每个能力都能找到代码或文档证据。 + +### 求职层 + +提供三分钟项目讲稿、五分钟 Demo、常见追问、STAR 表达和不虚构指标的简历模板,帮助面试者把工程决策讲清楚。 + +### 转化层 + +README 末尾只保留三个自然动作:运行项目、提出真实用例、Star 收藏。对贡献者则链接到明确的贡献边界和安全流程。 + +## 后续增长建议 + +1. 录制一个 60~90 秒 GIF:模糊需求输入、三轮追问、报告下载、事件流和产物。 +2. 发布 `v0.1.0`,同时提供变更说明、限制、校验值和升级路径。 +3. 维护 3~5 个 Golden Demo:物流排班、电商履约、客服工单、仓库治理和安全扫描。 +4. 为真实用例建立 Issue 模板,并把通过验收的案例转成 Eval 回归集。 +5. 每次发布展示可验证变化:测试数量、已关闭风险、兼容矩阵和已测资源上限;不展示没有测量方法的性能数字。 +6. 为 GitHub Social Preview 制作一张可读的 1280×640 产品图,突出 FDE Discovery、Agent Runtime、Sandbox 三个关键词。 + +## 成功指标 + +不只看 Star: + +- README → Quickstart 的点击和成功启动率; +- `/discovery` 完成三轮并下载报告的比例; +- Fork 后产生有效 Issue/PR 的数量; +- Golden Demo 的通过率和回归稳定性; +- Release 下载、复访和外部引用; +- 用户是否能准确说出“已实现”与“演进方向”的区别。 diff --git a/docs/product-positioning.md b/docs/product-positioning.md index ec9b7b4..e68da10 100644 --- a/docs/product-positioning.md +++ b/docs/product-positioning.md @@ -2,13 +2,20 @@ ## 1. 一句话定位 -Cloud Agent Platform 是一个面向 AI 应用开发与平台工程学习的开源执行底座:它把模糊需求和代码仓库转化为 -受预算、策略和沙箱约束的 Agent 工作,并把过程事件、错误、用量和产物完整返回。 +Cloud Agent Platform 是 FDE 的客户发现前置工作台和开源 Agent 执行底座:它把企业负责人的模糊表达转成 +有证据、可实施、可验收的技术方案,再把明确的仓库任务交给受预算、策略和沙箱约束的 Agent 执行。 ## 2. 给谁使用 ### 核心用户 +**Forward Deployed Engineer(FDE)与解决方案架构师** + +- 需要在客户交流早期识别真实业务结果、决策人、现状流程、规模和范围边界。 +- 需要拒绝没有证据的抽象讨论,把“快、智能、好用”追问成数字、样例和可观察行为。 +- 需要提前发现数据、接口、安全、预算、客户配合和验收条件等实施阻塞项。 +- 需要把访谈记录转成架构、开发、QA 和客户可以共同评审的技术发现包。 + **AI 应用工程师** - 需要学习或搭建 Agent Loop、function calling、工具注册表和 Provider Adapter。 @@ -29,13 +36,24 @@ Cloud Agent Platform 是一个面向 AI 应用开发与平台工程学习的开 ### 邻近用户 -**产品经理、创业者和交付顾问**可以使用需求挖掘页面,把“做一个物流司机排班软件”这类输入逐轮补全为可评审的 -软件设计报告。当前 Demo 对物流场景有确定性模板;使用 OpenAI Provider 时可处理更开放的需求,但输出仍需要 -业务与技术负责人确认。 +**产品经理、创业者、售前顾问和交付负责人**也可以使用 FDE 工作台,把“做一个物流司机排班软件”这类输入 +逐轮补全为可评审技术方案。当前 Demo 对物流场景有确定性模板;使用 OpenAI Provider 时可处理更开放的需求, +但输出仍需要客户业务负责人和技术负责人确认。 ## 3. 要解决的问题 -传统 LLM 工具 Demo 常见四个断点: +FDE 与企业负责人沟通时经常出现五个断点: + +1. 客户说的是方案名或症状,没有可量化的业务结果和现状证据; +2. 业务负责人、使用者、数据负责人、技术负责人和决策人没有明确区分; +3. 会议反复讨论功能,但范围、非目标、异常、人工兜底和验收标准始终模糊; +4. FDE 过早承诺技术方案,后续才发现数据拿不到、接口不存在或安全不允许; +5. 访谈内容移交研发时丢失上下文,产生范围蔓延、重复返工和验收争议。 + +需求发现模块通过分阶段访谈、证据分类和技术方案就绪门禁解决这些问题。详细方法见 +[FDE 客户需求发现工作手册](fde-discovery-playbook.md)。 + +作为执行底座,传统 LLM 工具 Demo 还常见四个断点: 1. 只展示一次模型调用,没有任务生命周期和失败语义; 2. 直接在宿主机执行命令,没有可信边界和资源上限; @@ -50,11 +68,11 @@ Cloud Agent Platform 是一个面向 AI 应用开发与平台工程学习的开 ## 4. 核心业务场景 -### 场景 A:需求发现 +### 场景 A:FDE 客户需求发现与技术移交 -输入:模糊的软件想法和可选前置条件。 -过程:创建会话 → 多轮澄清 → 用户补充 → 准备完成 → 生成报告。 -输出:需求摘要、用户与角色、范围、流程、非功能需求、风险、假设、未决问题和开发建议。 +输入:企业负责人的模糊需求、已知背景和前置条件。 +过程:业务结果与决策人 → As-Is 证据 → 范围/规则/异常 → 数据/集成/安全 → PoC 验收与交付条件。 +输出:事实/假设/决策/风险、角色责任、范围与非目标、技术架构、验收阈值、Go/No-Go 条件和研发移交清单。 ### 场景 B:仓库分析 @@ -79,7 +97,9 @@ Cloud Agent Platform 是一个面向 AI 应用开发与平台工程学习的开 - FR-07:排队和运行中的任务均可取消,取消传播到工具协程和进程树。 - FR-08:平台只记录公开行动摘要、工具事件、状态和用量,不保存私有思维链。 - FR-09:文本产物可列出、校验哈希并下载,重复提交保持幂等。 -- FR-10:用户可通过多轮对话把模糊需求整理为软件设计报告。 +- FR-10:FDE 可通过多轮对话把模糊客户需求整理为带证据和开放项的可执行技术方案。 +- FR-11:系统在达到最少轮次后仍按就绪门禁追问阻塞项,不把“可生成草案”误写为“需求完整”。 +- FR-12:报告必须区分事实、假设、决策、风险和开放问题,并包含研发与 QA 移交清单。 完整可追踪需求见 [软件需求规格说明书](sdlc/02-software-requirements-specification.md)。 @@ -101,6 +121,8 @@ Cloud Agent Platform 是一个面向 AI 应用开发与平台工程学习的开 - 每个成功任务的 token、模型费用和工具调用数; - 取消完成时间和孤儿进程/沙箱数量; - 需求报告的事实覆盖率、未确认假设率和人工返工率; +- 关键结论的证据关联率、开放项关闭周期和 FDE 到研发移交后的新增阻塞数; +- PoC 验收争议率、Go/No-Go 决策周期和因需求误解产生的开发返工率; - 路径逃逸、秘密泄露、越权工具和网络访问的阻断率; - Worker 崩溃后的恢复成功率与重复产物率。 diff --git a/docs/requirement-discovery.md b/docs/requirement-discovery.md index 8fb3765..7964cb7 100644 --- a/docs/requirement-discovery.md +++ b/docs/requirement-discovery.md @@ -1,13 +1,17 @@ -# 多轮需求发现与软件设计报告 +# FDE 多轮客户需求发现与可执行技术方案 ## 产品目标 -在仓库执行任务之前增加一个对话式控制面。用户可以只提交十几个字的模糊需求, -需求发现 Agent 通过多轮问题确认用户、场景、规模、规则、异常、数据、集成、成功指标和交付约束, -最后生成 Markdown 软件设计报告。 +在仓库执行任务之前增加一个面向 Forward Deployed Engineer 的对话式控制面。FDE 可以只提交客户十几个字的 +模糊需求,Discovery Agent 通过多轮问题确认业务结果、决策人、As-Is 证据、规模、范围与非目标、规则、异常、 +数据和系统负责人、安全边界、验收阈值和交付约束,最后生成 Markdown 技术发现与方案报告。 + +产品核心不是延长会议,而是拒绝无效沟通:已经回答的问题不重复问;抽象词继续追到数字、样例或可观察行为; +所有内容严格区分事实、假设、决策、风险和开放问题。完整方法见 +[FDE 客户需求发现工作手册](fde-discovery-playbook.md)。 需求发现不会直接执行用户代码,也不需要仓库地址。它与 `/v1/tasks` 的仓库执行流程相互独立; -未来可以把已确认的报告作为执行 Agent 的任务输入。 +未来可以把已确认的报告作为执行 Agent 和多 Agent 开发团队的任务输入。 ## 使用入口 @@ -20,22 +24,23 @@ 1. `POST /v1/discovery-sessions`:提交模糊需求和可选前置条件。 2. `POST /v1/discovery-sessions/{sessionId}/messages`:回答 Agent 的问题。 3. `GET /v1/discovery-sessions/{sessionId}`:获取完整对话和状态。 -4. `POST /v1/discovery-sessions/{sessionId}/finalize`:生成软件设计报告。 +4. `POST /v1/discovery-sessions/{sessionId}/finalize`:生成 FDE 技术方案草案。 5. `GET /v1/discovery-sessions/{sessionId}/report`:下载 Markdown 报告。 状态含义: - `DISCOVERY`:仍在进行需求澄清。 -- `READY`:已完成建议的三轮澄清,可以生成第一版报告。 +- `READY`:已完成建议的最少三轮,可以生成第一版草案;不代表需求已经完整。 - `FINALIZED`:报告已经生成,会话只读。 -用户可在三轮前提前生成报告。系统必须把未确认信息标记为默认假设或待确认项, -不得把模型推测伪装为用户确认。 +用户可在三轮前提前生成报告,也可以继续至最多 12 轮。达到三轮后,Agent 按九项就绪门禁检查业务结果、 +责任人、流程、范围、规则、数据、集成、安全和验收;存在实施阻塞时继续追问。系统必须把未确认信息标记为 +默认假设或待确认项,不得把模型推测伪装为用户确认。 ## Demo 与 OpenAI 模式 -Demo 模式使用确定性产品经理流程,能够离线演示物流司机排班等需求的三轮澄清, -并生成结构完整的软件设计报告。OpenAI 模式使用配置的 Responses Provider,根据已有对话动态追问和生成报告。 +Demo 模式使用确定性 FDE 发现流程,能够离线演示物流司机排班等需求的三轮澄清, +并生成结构完整的技术方案。OpenAI 模式使用配置的 Responses Provider,根据已有证据动态追问和生成报告。 OpenAI 模式采用手动重放最小消息历史的方式维持会话上下文,`store` 保持为 `false`。 生产环境可进一步评估 Responses API Conversations 或 `previous_response_id`,并结合数据保留要求选择状态管理方式。 @@ -44,12 +49,13 @@ OpenAI 模式采用手动重放最小消息历史的方式维持会话上下文 - 所有会话 API 使用与任务 API 相同的 Bearer 和租户隔离。 - 单条需求、前置条件和回答最多 20,000 字符;每个会话最多 12 个用户轮次。 -- 报告产物受认证下载,并限制为 Artifact Store 的安全文件名和大小。 +- 报告产物名为 `fde-technical-solution.md`,受认证下载,并限制为 Artifact Store 的安全文件名和大小。 - 模型错误只返回通用错误,不把 API Key、上游响应正文或内部异常写给用户。 - 对话中只保存用户可见的问答,不保存模型私有思维链。 ## 当前限制 - 会话状态使用进程内存,服务重启后丢失;报告文件仍在本地 `.artifacts`,但元数据不会自动恢复。 -- Demo 模式的问题模板对物流排班做了优化,其他领域使用通用问题和通用报告框架。 +- Demo 模式的问题模板对物流排班做了优化,其他领域使用通用 FDE 问题和技术方案框架。 - 尚未把最终报告自动转换成开发任务 DAG,也没有自动启动多 Agent 编码团队。 +- 当前 `READY` 是最少轮次门槛,不是模型给出的结构化完整度评分;生产版本应增加字段级证据模型和人工签字门禁。 diff --git a/docs/requirements.md b/docs/requirements.md index b39fb60..e48d73a 100644 --- a/docs/requirements.md +++ b/docs/requirements.md @@ -1,7 +1,8 @@ # Cloud Agent Platform 需求基线 > 扩展能力:在仓库执行任务之前,平台支持多轮需求发现会话。用户可以提交模糊需求和前置条件, -> 通过澄清问题形成已确认需求、默认假设和待确认项,再生成软件设计报告。 +> FDE 通过分阶段澄清形成客户需求证据、已确认事实、默认假设、决策、风险和待确认项, +> 再生成可供架构、开发、QA、安全和客户共同评审的技术方案。 > 详细契约见 `docs/requirement-discovery.md`。 ## 1. 产品定义 @@ -14,7 +15,7 @@ 以下信息尚未由真实业务方确认,实现前需要人工审阅: -- 假设目标用户是企业研发团队和内部开发者。 +- 假设核心目标用户是 FDE、解决方案架构师、AI 应用工程师、企业研发团队和内部开发者。 - 假设第一版是单区域、多租户 MVP,不承诺生产级 SLA。 - 假设输入以 Git 仓库 URL 和自然语言任务为主。 - 假设 P0 主要执行只读代码分析,但底层工具接口预留受控写文件能力。 @@ -25,6 +26,7 @@ ## 3. P0 范围 +- FDE 客户发现:围绕业务结果、现状证据、责任人、范围、数据集成、安全和验收进行多轮访谈,输出技术方案草案。 - 创建任务:自然语言目标、仓库 URL、可选分支或提交哈希。 - 查询任务:当前状态、开始/结束时间、失败原因和资源使用摘要。 - 取消任务:向运行中的 Worker 和沙箱传播取消信号。 diff --git a/docs/sdlc/01-product-and-business-requirements.md b/docs/sdlc/01-product-and-business-requirements.md index c78afdd..e0b5f0e 100644 --- a/docs/sdlc/01-product-and-business-requirements.md +++ b/docs/sdlc/01-product-and-business-requirements.md @@ -9,11 +9,12 @@ 企业研发人员经常需要把自然语言目标转换为一系列可审计的代码分析、文件修改、测试和报告操作。直接在开发者 电脑运行自治 Agent 会带来凭证泄漏、宿主机破坏、资源失控、过程不可追踪和多人协作困难。另一个上游问题是, -业务方通常只给出十几个字的模糊需求,团队在没有形成清晰范围和验收标准前就开始编码。 +企业负责人通常只给出十几个字的模糊需求,FDE 在没有确认决策人、现状证据、清晰范围、数据条件和验收标准前 +就被迫给出方案或承诺,后续造成重复沟通、范围蔓延和开发返工。 本产品提供两条连续价值链: -1. 从模糊需求出发,通过多轮会话和专业 Agent 形成结构化需求及软件设计报告。 +1. 从模糊客户需求出发,通过 FDE 多轮发现形成带证据、责任人、范围、验收和开放项的可执行技术方案。 2. 将批准的任务放入云端隔离环境,由受预算和策略约束的 Agent 执行,并返回事件、结果和产物。 ## 2. 产品愿景 @@ -23,7 +24,8 @@ ## 3. 目标用户 -- 业务产品经理:从模糊想法形成范围、流程、验收标准和未决问题。 +- Forward Deployed Engineer:在客户现场形成需求证据、范围边界、技术方案、验收门禁和研发移交。 +- 业务产品经理:与 FDE 共同确认业务目标、流程、验收标准和未决问题。 - 软件工程师:执行仓库分析、测试、文档、受控修改和技术调研。 - Tech Lead:拆分任务、控制并行开发、审核架构和集成结果。 - QA/安全人员:查看事件、工具调用、测试证据和策略拒绝。 @@ -34,7 +36,7 @@ ## 4. 核心价值指标 -- 需求澄清:80% 的内部需求在 3–5 轮后形成可评审的结构化快照。 +- FDE 发现:80% 的客户需求在 3–5 轮后形成可评审技术草案,关键结论具有证据或明确责任人。 - 任务成功:受支持的只读仓库任务成功率至少 95%。 - 开发效率:常规代码分析与报告任务的人工作业时间降低至少 50%。 - 可追踪性:100% 的模型调用、工具调用、状态变化和产物有公开事件或审计记录。 @@ -52,7 +54,7 @@ - Demo Provider 与 OpenAI Responses Provider。 - 文件列举、读取、搜索、受控写入、命令执行和结果提交工具。 - 本地可信 Sandbox 与 Docker Sandbox 策略。 -- 三轮需求发现和 Markdown 软件设计报告。 +- 至少三轮 FDE 客户发现和 Markdown 技术方案;三轮是草案门槛,不代表需求完整。 - 开发 Bearer Token、单进程存储和本地产物目录。 ### 5.2 Next:Internal Beta @@ -75,18 +77,18 @@ ## 6. 非目标 - v1 不允许 Agent 无审批部署生产、付款、删除业务数据或合并主分支。 -- v1 不承诺替代产品经理、架构师、安全专家或法律意见。 +- v1 不承诺替代 FDE、客户决策人、领域专家、架构师、安全专家或法律意见。 - 不持久化模型私有思维链,只记录面向用户的行动摘要和证据。 - 不支持任意互联网访问;网络必须通过声明式 allowlist 和出口代理。 - 不把 Docker 本身表述为可对抗任意内核级恶意代码的最终安全边界。 ## 7. 关键用户旅程 -### 旅程 A:模糊需求到设计报告 +### 旅程 A:客户模糊需求到 FDE 技术方案 -用户输入“设计一个物流司机排班软件”和前置条件。系统识别信息缺口,每轮询问最高价值的问题;用户回答规模、 -约束、集成和性能后,系统生成结构化需求快照。Domain、Product、Architecture、Data/API、Security 和 QA Agent -分别产出专业分析。若存在阻塞问题则回到用户;质量通过后生成报告和追踪矩阵。 +FDE 输入“客户想用 AI 提升物流司机排班效率”和前置条件。系统识别业务结果、决策人、As-Is 证据、范围、规则、 +数据、集成、安全和验收缺口,每轮只询问最阻塞实施的问题。若存在阻塞问题则继续访谈;达到草案条件后生成 +事实/假设/决策/风险、技术方案、PoC 验收、Go/No-Go 条件和研发移交清单。 ### 旅程 B:仓库分析 diff --git a/docs/sdlc/11-acceptance-handover-traceability.md b/docs/sdlc/11-acceptance-handover-traceability.md index 0af60d5..5c4fe35 100644 --- a/docs/sdlc/11-acceptance-handover-traceability.md +++ b/docs/sdlc/11-acceptance-handover-traceability.md @@ -30,10 +30,11 @@ ## 3. UAT 场景 -### UAT-01 需求发现 +### UAT-01 FDE 客户需求发现 -产品经理输入模糊需求,经过 3–5 轮形成快照;系统标记事实、假设和问题;生成报告包含领域实体、状态、API、NFR、 -安全和验收;用户能定位每条关键结论的来源。通过标准:业务方认为可估时、可拆任务,无 P0 未决项被隐藏。 +FDE 输入客户模糊需求,经过至少三轮形成草案;系统标记事实、假设、决策、风险和开放项;生成报告包含决策人、 +As-Is 证据、范围与非目标、数据集成、架构、API、NFR、PoC 验收和研发移交。通过标准:业务与技术负责人认为 +可估时、可拆任务、可现场验收,无 P0 阻塞项被隐藏。 ### UAT-02 只读仓库分析 diff --git a/docs/task-board.md b/docs/task-board.md index 12a99a7..96361a6 100644 --- a/docs/task-board.md +++ b/docs/task-board.md @@ -10,6 +10,30 @@ ## 当前扩展任务 +### CAP-GROWTH-001:面向面试官的开源产品包装与增长基线 + +- 状态:`DONE` +- 所有者:主 Agent +- 范围:README 首屏与信息架构、对标仓库客观分析、FDE 面试演示材料、文档导航、GitHub 搜索元数据 +- 验收:产品承诺与已实现能力一致;新用户可在首屏理解用户、痛点、输入、输出和演示路径;所有本地链接与质量门通过;不复制对标仓库原文,不使用虚构指标 +- 验证:Ruff format/lint、strict mypy、全量 pytest、安全标记测试、compileall 与全仓库 Markdown 本地链接检查全部通过 + +### CAP-FDE-001:FDE 客户需求发现前置工作流 + +- 状态:`DONE` +- 所有者:主 Agent +- 范围:Discovery Prompt、离线访谈流程、技术方案报告、Web UI、中英文产品定位、测试与 GitHub 元数据 +- 验收:访谈围绕证据和实施阻塞推进;三轮仅代表可生成草案;报告包含范围、责任人、数据集成、验收、 + Go/No-Go 与研发移交;本地及 GitHub 质量门通过 + +### CAP-OSS-001:GitHub 开源发现与仓库治理 + +- 状态:`DONE` +- 所有者:主 Agent +- 范围:GitHub 仓库设置、README 双语入口、项目视觉、社区模板、标签、发布与验证 +- 验收:搜索元数据准确;新用户可在首屏理解价值并离线启动;main、Actions 与安全策略回读通过; + 变更通过本地质量门并以独立 PR 交付 + ### CAP-DISC-001:多轮需求发现与软件设计报告 - 状态:`DONE` diff --git a/src/api/discovery_routes.py b/src/api/discovery_routes.py index 678a631..8fec847 100644 --- a/src/api/discovery_routes.py +++ b/src/api/discovery_routes.py @@ -23,7 +23,7 @@ def create_discovery_router( *, authenticate: AuthDependency, ) -> APIRouter: - router = APIRouter(prefix="/v1/discovery-sessions", tags=["requirement discovery"]) + router = APIRouter(prefix="/v1/discovery-sessions", tags=["FDE discovery"]) def response(session: object, request: Request) -> DiscoverySessionResponse: from src.discovery import DiscoverySession @@ -42,7 +42,7 @@ def response(session: object, request: Request) -> DiscoverySessionResponse: status_code=status.HTTP_201_CREATED, response_model=DiscoverySessionResponse, operation_id="createDiscoverySession", - summary="Start a multi-turn requirement discovery conversation", + summary="Start a multi-turn FDE customer discovery conversation", responses={503: {"model": ErrorResponse, "description": "Model unavailable"}}, ) async def create_session( @@ -86,7 +86,7 @@ async def get_session( "/{sessionId}/messages", response_model=DiscoverySessionResponse, operation_id="addDiscoveryMessage", - summary="Answer questions and continue requirement discovery", + summary="Record customer evidence and continue FDE discovery", responses={ 404: {"model": ErrorResponse, "description": "Session not found"}, 409: {"model": ErrorResponse, "description": "Conversation conflict"}, @@ -121,7 +121,7 @@ async def add_message( "/{sessionId}/finalize", response_model=DiscoverySessionResponse, operation_id="finalizeDiscoverySession", - summary="Generate the software design report from the conversation", + summary="Generate the FDE technical discovery and solution report", responses={ 404: {"model": ErrorResponse, "description": "Session not found"}, 503: {"model": ErrorResponse, "description": "Model unavailable"}, @@ -148,12 +148,12 @@ async def finalize_session( "/{sessionId}/report", operation_id="downloadDiscoveryReport", name="download_discovery_report", - summary="Download the finalized Markdown software design report", + summary="Download the finalized Markdown FDE technical solution", response_class=FileResponse, response_model=None, responses={ 200: { - "description": "Software design report", + "description": "FDE technical discovery and solution report", "content": {"text/markdown": {"schema": {"type": "string", "format": "binary"}}}, }, 404: {"model": ErrorResponse, "description": "Session not found"}, diff --git a/src/discovery.py b/src/discovery.py index f0993db..28cb89f 100644 --- a/src/discovery.py +++ b/src/discovery.py @@ -60,27 +60,27 @@ async def build_report(self, session: DiscoverySession) -> str: ... class DemoDiscoveryAssistant: - """Deterministic offline product-manager flow for a usable local demo.""" + """Deterministic offline FDE discovery flow for a usable local demo.""" async def initial_questions(self, requirement: str, context: str | None) -> str: del context if self._is_logistics_scheduling(requirement): return ( - "这个需求目前比较模糊,我先确认业务背景。请尽量回答下面 5 个问题;" + "我会按 FDE 客户发现流程先确认业务结果和需求证据。请回答下面 5 个问题;" "不知道的可以写‘按合理默认值’:\n\n" - "1. 主要使用者是谁:调度员、车队管理员、司机,还是都需要?\n" - "2. 业务属于城市配送、长途货运、快递末端,还是其他场景?\n" - "3. 大约有多少司机、车辆和配送区域?按天还是按周排班?\n" - "4. 排班最重要的目标是什么:准时率、最低成本、公平性还是司机满意度?\n" - "5. 第一版必须解决的三个问题是什么?" + "1. 谁是客户侧负责人和最终决策人?主要使用者是调度员、司机还是车队管理员?\n" + "2. 现在如何排班,哪个环节最浪费时间或最容易出错?请给一个最近发生的例子。\n" + "3. 属于城市配送、长途货运还是其他场景?司机、车辆、区域和日任务量是多少?\n" + "4. 客户最想改善哪个可量化指标:准时率、成本、排班耗时、公平性还是投诉率?\n" + "5. 第一版必须解决什么、明确不解决什么,谁负责验收?" ) return ( - "我会先做需求挖掘,再生成软件设计报告。请回答:\n\n" - "1. 谁会使用这个软件,他们现在最痛苦的问题是什么?\n" - "2. 软件在哪些业务场景下使用,频率和大致规模是多少?\n" - "3. 第一版必须完成哪些核心流程?\n" - "4. 用什么指标判断软件上线成功?\n" - "5. 有哪些明确不能做或必须遵守的前置条件?" + "我会按 FDE 客户发现流程,把这句话转成可执行技术方案。第一轮请回答:\n\n" + "1. 谁提出了需求、谁最终决策、谁实际使用?三者是否是同一个人?\n" + "2. 客户现在怎么完成这件事?最痛的步骤是什么?请提供一个最近的真实例子。\n" + "3. 问题发生频率、用户量、数据量和损失或耗时大约是多少?\n" + "4. 第一版必须改变哪个业务结果?用什么数字或现场行为证明成功?\n" + "5. 明确的范围外事项、交付时间、预算或合规红线是什么?" ) async def follow_up(self, session: DiscoverySession) -> str: @@ -96,12 +96,12 @@ async def follow_up(self, session: DiscoverySession) -> str: ) if session.user_rounds == 1: return ( - "收到。第二轮确认业务规则:\n\n" - "1. 核心流程有哪些必须满足的规则和例外?\n" - "2. 需要哪些角色、权限和审批节点?\n" - "3. 需要保存哪些数据,数据从哪里来?\n" - "4. 发生冲突或失败时应由系统还是人工处理?\n" - "5. 哪些操作必须保留审计记录?" + "收到。第二轮只追问会阻塞工程实施的业务规则和证据:\n\n" + "1. 请按顺序描述当前主流程,并指出每一步的输入、负责人和完成条件。\n" + "2. 哪些规则绝不能违反?最常见的三个例外和人工兜底方式是什么?\n" + "3. 需要哪些角色、权限和审批节点?谁有权覆盖系统建议?\n" + "4. 需要哪些数据,分别来自哪个系统,由客户侧谁负责提供和解释?\n" + "5. 哪些关键说法仍是猜测?需要访谈谁或查看什么数据才能确认?" ) if session.user_rounds == 2 and logistics: return ( @@ -114,16 +114,18 @@ async def follow_up(self, session: DiscoverySession) -> str: ) if session.user_rounds == 2: return ( - "最后一轮确认交付条件:\n\n" - "1. 使用网页、手机、桌面端,还是需要多端?\n" - "2. 需要连接哪些已有系统或第三方服务?\n" - "3. 对性能、可用性、安全和合规有什么要求?\n" - "4. 预计用户量、数据量和并发量是多少?\n" - "5. 上线时间、预算、团队和技术栈有哪些限制?" + "第三轮确认技术可行性、验收和决策边界:\n\n" + "1. 需要连接哪些现有系统?接口、样例数据、测试环境和系统负责人是否可获得?\n" + "2. 哪些数据敏感,涉及哪些权限、安全、审计、地域或行业合规要求?\n" + "3. 性能、可用性、并发、数据保留和故障恢复的最低可接受标准是什么?\n" + "4. 请给出 3 到 5 条可现场验收的 Given/When/Then 标准和 PoC 成功阈值。\n" + "5. 上线时间、预算、客户配合人、技术栈和最终 Go/No-Go 决策流程是什么?" ) return ( - "需求信息已经达到第一版设计所需的基本完整度。你可以继续补充," - "也可以点击“生成软件设计报告”。报告会区分已确认需求和默认假设。" + "已经达到生成技术方案草案的最少轮次,但这不等于需求完整。请检查业务结果与决策人、" + "现状证据、范围和非目标、规则与异常、数据和集成负责人、安全约束、验收阈值、预算与时间。" + "任何一项仍不明确,都可以继续补充;也可以生成 FDE 技术发现报告," + "并把缺口列为下一步行动。" ) async def build_report(self, session: DiscoverySession) -> str: @@ -150,7 +152,7 @@ def _confirmed_information(session: DiscoverySession) -> str: def _logistics_report(self, session: DiscoverySession) -> str: context = session.context or "未提供;采用下文默认假设。" confirmed = self._confirmed_information(session) - return f"""# 物流司机排班软件设计报告 + return f"""# FDE 客户需求发现与物流司机排班技术方案 ## 1. 文档信息 @@ -158,8 +160,9 @@ def _logistics_report(self, session: DiscoverySession) -> str: - 已知前置条件:{context} - 需求发现轮数:{session.user_rounds} - 会话编号:{session.session_id} +- 文档性质:客户访谈后的技术方案草案,待客户业务负责人和技术负责人共同确认 -## 2. 已确认需求 +## 2. 客户需求证据 {confirmed} @@ -323,61 +326,144 @@ def _logistics_report(self, session: DiscoverySession) -> str: - TMS、订单、GPS、考勤和通知系统的接口条件。 - 司机是否有拒绝、换班和偏好配置权,以及审批流程。 - 上线时间、预算、部署环境、数据地域和保留期限。 + +## 17. FDE 下一步行动与研发移交 + +1. 与客户负责人逐项确认默认假设、非目标、决策权限和验收指标,并形成会议决策记录。 +2. 获取脱敏样例数据、现有排班表、规则清单和 TMS/GPS 接口文档,验证技术可行性。 +3. 用一周完成规则建模与低保真原型评审;未通过的数据和接口前置条件不得进入开发承诺。 +4. 将已确认项转成需求 ID、验收测试和迭代任务;待确认项保留责任人和截止时间。 +5. 在 PoC 结束时依据准时率、排班耗时、硬约束违规数和人工调整量做 Go/No-Go 决策。 """ def _generic_report(self, session: DiscoverySession) -> str: context = session.context or "未提供;未确认部分按默认假设处理。" confirmed = self._confirmed_information(session) - return f"""# 软件设计报告 + return f"""# FDE 客户需求发现与可执行技术方案 -## 1. 原始需求 +## 1. 执行摘要 -{session.initial_requirement} +- 客户原始表达:{session.initial_requirement} +- 已知前置条件:{context} +- 访谈轮数:{session.user_rounds} +- 当前成熟度:技术方案草案;未被客户明确表达的信息不得视为承诺 -## 2. 已知前置条件 +## 2. 客户需求证据 -{context} +{confirmed} -## 3. 多轮需求发现记录 +## 3. 事实、假设和待确认决策 -{confirmed} +- **已确认事实**:仅包括上方客户原始表达和逐轮回答。 +- **默认假设**:第一版采用模块化单体、人工审批高风险动作、先覆盖一个可验证主流程。 +- **待确认决策**:决策人、现状基线、范围外事项、数据负责人、集成条件、验收阈值、预算和上线窗口。 +- **证据要求**:重要结论应关联会议纪要、样例数据、流程截图、接口文档或客户负责人确认。 + +## 4. 客户角色与决策地图 + +1. 业务负责人:确认业务目标、范围、优先级和成功指标。 +2. 一线用户:验证现状流程、异常场景和实际可用性。 +3. 客户技术负责人:确认数据、接口、环境、安全与运维责任。 +4. FDE:维护需求证据、技术方案、风险和跨团队移交。 +5. 最终决策人:依据 PoC 结果、成本和风险做 Go/No-Go 决策。 + +## 5. As-Is 问题与 To-Be 目标 + +- As-Is 必须补齐当前步骤、负责人、输入输出、等待时间、错误率和人工兜底。 +- To-Be 只承诺改变已确认的业务结果,不以“上线一个系统”代替价值目标。 +- 建议先建立现状基线,再定义目标值和测量周期,避免上线后无法判断是否成功。 + +## 6. MVP 范围与非目标 + +### 范围内 + +1. 身份认证、角色权限和一个端到端核心业务流程。 +2. 核心对象的状态流转、异常处理、人工审批和审计。 +3. 必要的数据导入、外部集成适配器、通知和基础指标。 + +### 范围外 -## 4. 产品目标与成功指标 +- 未确认的全量历史数据迁移、自动化高风险决策和一次性替换所有旧系统。 +- 没有接口、数据样例或客户责任人的外部系统集成。 +- 未形成验收标准的“智能化”“高性能”“体验好”等模糊目标。 -- 解决原始需求描述中的核心业务问题。 -- 先交付覆盖主流程的可验证 MVP,再基于真实使用数据扩展。 -- 上线前由业务负责人确认角色、规则、数据、集成和合规假设。 +## 7. 可追踪功能需求 -## 5. MVP 功能框架 +- `FR-001`:目标用户能够完成已确认的端到端主流程。 +- `FR-002`:关键业务对象具有合法、可审计且不可跳过的状态转换。 +- `FR-003`:规则冲突、外部系统失败和人工覆盖具有显式处理路径。 +- `FR-004`:关键写操作支持身份校验、幂等、防重复和操作审计。 +- `FR-005`:系统输出能够关联输入数据、规则版本和处理结果。 -1. 身份认证、用户角色和权限。 -2. 核心业务对象的创建、查询、修改和状态流转。 -3. 主业务流程、异常处理和人工审批。 -4. 操作审计、基础报表和通知。 -5. 可配置业务规则以及导入、导出能力。 +## 8. 数据与集成清单 -## 6. 建议架构 +每个数据源和外部系统必须记录业务用途、系统负责人、接口方式、字段样例、数据量、更新频率、 +敏感等级、测试环境、失败策略和交付日期。没有负责人或样例数据的集成标记为阻塞项。 + +## 9. 建议技术方案 + +### 9.1 技术架构 采用模块化单体作为第一版:Web/移动端调用 API 服务,业务模块使用 PostgreSQL, 耗时任务进入 Redis 队列和异步 Worker。外部集成通过适配器隔离,日志、指标和审计分开保存。 -## 7. 安全与质量 +只有在独立扩缩容、隔离或团队所有权有真实证据时才拆分微服务。所有 AI 推断必须与确定性业务规则、 +人工审批和可追踪证据分层。 + +### 9.2 核心数据模型 + +- `Actor`:用户、角色、组织、权限和决策责任。 +- `BusinessEntity`:客户领域中的核心业务对象及其生命周期。 +- `WorkflowState`:主流程状态、合法转换、完成条件和失败原因。 +- `DecisionRule`:业务规则、优先级、版本、适用范围和人工覆盖条件。 +- `IntegrationRecord`:外部系统、幂等键、同步状态和失败重试信息。 +- `AuditEvent`:操作者、输入、变更前后内容、原因、结果和时间。 + +### 9.3 API 基线 + +- `POST /v1/entities`:幂等创建核心业务对象。 +- `GET /v1/entities/{id}`:按权限查看对象、状态和处理证据。 +- `POST /v1/entities/{id}/actions`:执行经过校验的状态动作。 +- `GET /v1/entities/{id}/events`:查看公开业务与审计事件。 +- `POST /v1/integrations/{{system}}/sync`:触发可追踪的外部系统同步。 + +具体实体名、字段、状态和 API 必须在客户确认领域模型后替换,不能把通用占位符当成最终契约。 + +## 10. 安全、可靠性与非功能要求 - 最小权限、租户隔离、输入校验、敏感数据加密和审计。 - 核心状态机、幂等写入、超时、重试和故障恢复必须自动测试。 -- 先验证业务正确性,再根据实际数据决定是否拆分微服务。 +- 性能、并发、可用性、RTO/RPO、保留期限和合规要求在客户确认数值前均为开放项。 + +## 11. PoC 与 MVP 验收标准 + +1. `Given` 已确认角色、样例数据和测试环境,`When` 执行主流程,`Then` 可完成并生成可核验结果。 +2. 规则、异常、越权、重复提交和外部依赖失败都有客户认可的处理结果。 +3. 关键操作可追踪到用户、输入、规则版本、结果和时间。 +4. PoC 指标必须包含现状基线、目标阈值、测量窗口、数据来源和验收负责人。 +5. 未通过数据质量、安全或集成前置条件时,不得以功能演示替代正式验收。 + +## 12. 交付计划与工程门禁 + +1. Discovery:确认问题、证据、范围、负责人和决策机制。 +2. Feasibility:用样例数据和接口验证关键技术风险。 +3. PoC:只实现能证明核心价值的最小闭环。 +4. MVP:补齐安全、可靠性、运维、数据治理和验收自动化。 +5. Handoff:输出需求 ID、架构决策、接口契约、验收用例、风险和责任矩阵。 -## 8. MVP 验收标准 +## 13. 风险、依赖与仍需确认 -1. 目标用户可以完整完成主业务流程。 -2. 非法状态、越权访问和重复提交被明确拒绝。 -3. 关键操作可追踪,错误对用户可解释。 -4. 性能、安全和可恢复性满足已确认的前置条件。 +- 用户角色、决策人、业务规模、现状基线、规则、异常流程和成功指标。 +- 外部系统负责人、数据样例、接口权限、部署环境、安全合规、预算和时间限制。 +- 客户未按期提供数据、接口或评审人员时,交付时间和范围必须走变更控制。 -## 9. 仍需确认 +## 14. FDE 下一步访谈清单 -- 用户角色、业务规模、核心规则、异常流程和成功指标。 -- 外部系统、部署环境、安全合规、预算和时间限制。 +- 对每个开放项指定客户责任人和确认日期。 +- 用真实业务案例走查主流程和前三类异常,拒绝只讨论抽象功能名。 +- 获取样例数据、接口文档和安全要求,安排技术可行性验证。 +- 让业务负责人签字确认范围、非目标、验收指标与变更流程。 +- 将本报告转成开发任务前,由架构、开发、QA 和安全共同完成可实施性评审。 """ @@ -412,8 +498,12 @@ async def follow_up(self, session: DiscoverySession) -> str: Message( role="user", content=( - "判断信息是否足够形成 MVP 设计。简要总结已确认内容和关键假设," - "然后提示用户可以生成软件设计报告;不要直接输出报告。" + "按 FDE 技术发现就绪清单判断信息是否足够:业务结果和决策人、" + "现状流程与量化证据、" + "用户和规模、MVP 范围与非目标、规则与异常、数据和集成负责人、安全约束、" + "验收阈值、预算时间与 Go/No-Go 流程。若有阻塞缺口," + "继续追问最关键的 3 到 5 个;" + "全部覆盖后才说明可以生成技术方案。不要直接输出报告。" ), ) ) @@ -432,24 +522,31 @@ async def build_report(self, session: DiscoverySession) -> str: Message( role="system", content=( - "你是资深产品经理和软件架构师。根据完整对话输出中文 Markdown 软件设计报告。" - "必须区分已确认需求、默认假设和待确认问题,并包含角色、流程、功能范围、" - "数据模型、架构、API、安全、非功能要求、MVP 验收标准、风险和迭代计划。" - "不要声称用户确认了对话中没有出现的信息。" + "你是资深 Forward Deployed Engineer、解决方案架构师和交付负责人。" + "根据完整对话输出中文 Markdown《FDE 客户需求发现与可执行技术方案》。" + "必须区分已确认事实、客户原话证据、默认假设、开放问题和已做决策。" + "报告必须包含执行摘要、决策人与用户、As-Is 流程和量化痛点、To-Be 目标、" + "MVP 范围与非目标、可追踪需求 ID、规则与异常、数据和集成责任矩阵、" + "技术架构与 API、安全和非功能要求、PoC/MVP 验收阈值、交付计划、风险依赖、" + "Go/No-Go 条件以及给开发与 QA 的移交清单。不要把模型推测写成客户承诺。" ), ) ] messages.extend(Message(role=item.role, content=item.content) for item in session.messages) - messages.append(Message(role="user", content="现在生成完整的软件设计报告。")) + messages.append(Message(role="user", content="现在生成完整的 FDE 技术发现与方案报告。")) response = await self._provider.complete(messages, []) return self._answer(response.final_answer) @staticmethod def _discovery_prompt() -> str: return ( - "你是需求发现 Agent。目标是通过多轮对话把模糊的软件需求变为可验收的 MVP。" - "优先询问用户角色、业务场景、规模、规则、异常、数据、集成、成功指标和交付约束。" - "每轮只问 3 到 5 个问题,问题要具体、容易回答;不要泄露内部推理。" + "你是资深 Forward Deployed Engineer 的客户需求发现助手。目标不是陪聊或急于给方案," + "而是把企业负责人的模糊表达变成有证据、可实施、可验收的技术方案。" + "优先确认业务结果与决策人、As-Is 流程和真实案例、量化规模与痛点、用户与权限、" + "MVP 范围和非目标、规则与异常、数据来源和系统负责人、集成条件、安全合规、" + "PoC 验收阈值、预算时间和决策流程。严格区分事实、假设、决策、风险和开放问题。" + "不得重复已经回答的问题;遇到‘快、智能、好用’等模糊词必须追问数字、样例或可观察行为。" + "每轮只问 3 到 5 个最阻塞工程实施的问题,并说明问题所处的访谈阶段;不要泄露内部推理。" ) @staticmethod @@ -556,7 +653,7 @@ async def finalize(self, session_id: str, *, tenant_id: str) -> DiscoverySession report = await self._assistant.build_report(session) artifact = await self._artifact_store.put_text( session.session_id, - "software-design-report.md", + "fde-technical-solution.md", report, "text/markdown", ) diff --git a/src/discovery_ui.py b/src/discovery_ui.py index 12f5f0c..b39b470 100644 --- a/src/discovery_ui.py +++ b/src/discovery_ui.py @@ -5,7 +5,7 @@ - 需求发现 Agent + FDE 客户需求发现工作台