Show HN:Era——为你的 Agent 提供完整模拟公司
英文标题:🔶 Show HN: Era – Complete Simulated Companies for Your Agents
Era 是一个用于生成完整模拟公司的平台,旨在为 AI Agent 提供可交互、可读写的真实感企业数据环境。它按照员工时区、组织变动、业务事件、客户工单、文件、通话和聊天记录等规则生成跨系统一致的数据,并刻意加入可声明的数据脏乱样本。单个最高规模租户可包含数万条联系人、文件、通话、工单和问题记录,覆盖 Salesforce、Zendesk、Slack、Jira、云盘及多种文档格式。开发者可通过 MCP 或厂商原生 REST API 连接同一实时租户状态,使 Agent 测试不再局限于静态快照数据。
104.7 KB
15.2 KB
中文
01 / 时钟
时间戳落在员工工作的时段
每条记录的时间都会依据其所属人员在其本地时区内的工作周生成。
06:00 11 月 24 日,周一 一周时间,按小时划分 __
78% 位于工作时间内,6% 位于周末。节假日按国家设定。
02 / 一个人,完整闭环
一个人有职级、历史与遗留痕迹
一个人,只生成一次:一个职位、一个职级、一串变动记录、一年中包含休假的安排,以及其离开后留下的痕迹。
人员变动
- 入职:周一入职,占 54%
- 晋升:在当前职级任职 26 至 40 个月后
- 调岗:每年 5%,最多两次
- 重组:每年 19%,更换直属经理
在上一次变动后的 180 天内,不会发生新的变动。
Wei Ashwell 高级软件工程师 IC4 · 新加坡
离职之后
11% 的员工名册成员已离开。其中一些人仍会:
- 保留付费许可证
- 继续运行自动化任务
- 仍属于某个群组
- 离开一个没有负责人的团队
职级阶梯
IC1 IC2 IC3 IC4 IC5 M3 M4 M5 E1 E2
IC4 和 M3 为同一职级:这是职业路径分叉,而不是降职。
一年
按区块分布,并向 8 月倾斜(2.1 倍)。3.5% 的员工休育儿假,时长为 8 至 16 周。
她在各系统中的身份
- Slack URYK9RBHQIS
- Jira 712020:dcf192af-a814-4822-80e3-64e49c3da98c
- Zendesk 34283961120
- PagerDuty P7H3Y0UHIDCQKG
- Asana 5259982783324276
- Salesforce 0035g06l6zxBXAvAAO
六个系统背后对应同一个身份:96401ffc2a5dc4d26d1d185e82b4c824。
03 / 分布形状
数值来自已公开的分布形状,而非均匀噪声
每个目标值都附带其来源;生成器所抽取的表格,也是用于评分的表格。
交易金额:对数正态分布,中位数 1.7 万美元,sigma 为 0.85
$0 $70k $140k+
行业:Amplitude 的 S-1 文件显示,1,039 家客户的平均值为 9.86 万美元,1.7% 的客户超过 100 万美元。
客户员工规模:对数正态分布,中位数 180,sigma 为 1.1
0 1,200 2,400+
行业:在所有已测量经济体中,企业规模都接近对数正态分布。
每个账户的工单数:重尾分布,alpha 为 1.45
1 13 26+
结构性事实:前 10% 的账户提交了 38% 的工单队列,且没有账户超过 7%。
柱状条表示抽样结果,曲线表示其依据的概率密度。每种分布形状都附带来源,评分卡会公布其中有多少内容属于估计值。
再次抽样
04 / 爆发事件
一次故障、五位客户、五种不同表述
互不相关的账户报告大致相同的故障;每个账户都从自己的时区、以自己的措辞提交问题。
高峰日:一个写入副本饱和,五位报告者,按到达顺序排列
- Nine Rivers 22:19 JST · 13:19Z 升级处理:我们的沙盒环境中,报表仪表板显示为空(请求 8f21c4)紧急
- Marlow Health 09:12 EST · 14:12Z 我们整个团队的报表仪表板均显示为空紧急
- Kestrel Freight 14:31 GMT · 14:31Z 自 14:05 起,我们的欧盟用户仪表板显示为空高
- Bower & Vale 15:48 CET · 14:48Z 是否发生了事故?生产环境中的仪表板显示为空高
- Alto Systems 07:03 PST · 15:03Z 自 06:40 起,我们的报表仪表板在夜间批处理期间不可用普通
19% 的工单队列属于共享事故;每 30 天发生一天,并且它们会在工作日中段出现,因为部署通常如此。
05 / 有意制造的杂乱
杂乱是刻意加入的,并且已声明
一个租户可以被注入真实公司常见的数据维护问题:粘贴进去的占位符、电子表格式大小写、2023 年遗留的测试账户。
- 占位符Berlin, DEN/A
- 大小写Marlow HealthMARLOW HEALTH
- 空白字符Renewal - EMEARenewal - EMEA
- 垃圾行-ZZZ test (delete me)
- 重复项AcmeAcme (old)
__ 占该列的 0% 注入比例 · 上限 30%
清单
每个缺陷都会被提供而非隐藏:类型、集合、字段、记录以及其替换掉的值。清单中声明的重复项属于数据维护问题;未声明的重复项则是 Bug。
- 任意单列的硬性上限为 30%
- 根据行自身的 ID 进行键控哈希,因此新增字段不会改变杂乱数据的位置
- 0 个 ID、键、域名或登录邮箱会被修改——绝不产生断裂的关联
这些问题采用可选择加入且已声明的方式,因此可用于评测去重、DLP 和访问审查,而不是制造噪声。
06 / 数据资产版图
多种数据类型,规模与真实企业资产相当
同一家公司会被投射到表格系统、文件存储、通话转录、聊天记录和渲染文档中;处于最高规模层级的单个租户,在每一种系统中都拥有数万条记录。
数据资产的构成
- 表格数据:salesforce · hubspot · zendesk · jira
- 转录内容:gong 通话,逐轮转录,并附带录音
- 聊天:slack 频道和线程,包括事故发生期间使用的频道
- 文件存储:aws · google-drive · box · dropbox · sharepoint
- 内容:docx · xlsx · pdf · txt/md · csv/json · png/jpeg · mp4 · parquet
一个最高规模层级的租户
- 联系人 18,766
- 文件 15,801
- 通话 13,758
- 工单 12,000
- 问题 12,000
- 事故聊天消息 4,354
包含 6,086 小时通话音频、1,752 位不同的聊天作者,以及他们共同所属的 750 个账户。
- 11 个系统承载同一图谱的投射:六个表格层和五个文件存储,均对员工身份及发生事项保持一致
- 通过 Drive、Box、Dropbox 和 AWS 自有 SDK,从一个拥有 20,000 份文档的数据资产中读取回 79,000 个条目——涵盖所有系统中的每一份文档
- 该租户中有 12,050 份文件为渲染文档,750 份为通话转录,而不是只有文件名的行记录
数据量来自某个超大规模细分市场公开的标准答案文件,该文件也是其评分器进行评测时使用的同一份文件;四个文件存储系统的数据则来自一次文件与数据湖审计,该审计通过各供应商的 SDK 扫描同一份数据资产,并将结果重新关联回图谱。
07 / 检测器
九种识别伪造数据的方法,我们一种也不会触发
每个数值都与以朴素方式生成的同一家公司进行对照。
每项检测:我们的结果与朴素生成结果的对比
每家公司、每项检测以及检测器发现的所有内容,都完整发布于 数据保真度。
08 / 通过 MCP 实时连接
连接实时运行的技术栈,而不是静态快照
公司中的每个系统都是一个正在运行的实例。Agent 通过 MCP 连接,客户端则通过供应商自己的 API 连接;二者对同一租户进行读写。
请求
_POST /mcp_ _zendesk_
{"jsonrpc": "2.0", "id": 7,
"method": "tools/call",
"params": {
"name": "**get_ticket** ",
"arguments": {"ticket_id": 4182}}}
同一张工单的 REST 请求:GET /api/v2/tickets/4182.json
- Slack 实时
slack_get_channel_history{"ok": true, "messages": […]} - Zendesk 实时
get_ticket{"id": 4182, "status": "open", …} - Salesforce 实时
run_soql_query{"totalSize": 750, "done": true, …} - Jira 实时
getJiraIssue{"key": "OPS-311", "fields": {…}}
每个连接器都在同一个端口上提供其厂商 REST API 和 MCP 端点,并针对同一租户状态运行;因此,通过 MCP 执行的写入操作,会在 REST 客户端读取时立即可见。
English / 原文
01 / THE CLOCK
Timestamps land when people are at work
Every record's time is drawn against its owner's working week, in their own timezone.
06:00 Mon 24 Nov one week, an hour at a time __
78% inside business hours, 6% at a weekend. Holidays are per country.
02 / ONE PERSON, ROUND
A person has a level, a history and a residue
One human, derived once: a seat, a rung, a string of moves, a year with leave in it, and what is left behind when they go.
the moves
- hire a Monday, 54%
- promotion 26-40 months in level
- transfer 5% a year, max twice
- reorg 19% a year, new manager
Nothing moves inside 180 days of the last move.
Wei Ashwell Senior Software Engineer IC4 · Singapore
after they leave
11% of the roster has already gone. Of those:
- keep a paid licence
- still run automations
- still in a group
- leave a team with no lead
the ladder
IC1 IC2 IC3 IC4 IC5 M3 M4 M5 E1 E2
IC4 and M3 are the same rank : the fork, not a demotion.
the year
In blocks, weighted into August (2.1x). 3.5% take parental leave, 8-16 weeks.
where she exists
- Slack URYK9RBHQIS
- Jira 712020:dcf192af-a814-4822-80e3-64e49c3da98c
- Zendesk 34283961120
- PagerDuty P7H3Y0UHIDCQKG
- Asana 5259982783324276
- Salesforce 0035g06l6zxBXAvAAO
One identity behind all six: 96401ffc2a5dc4d26d1d185e82b4c824.
03 / THE SHAPES
Numbers come from published shapes, not uniform noise
Each target carries where it came from, and the table the generator draws from is the table it is scored against.
deal size lognormal, median $17k, sigma 0.85
$0 $70k $140k+
industry Amplitude's S-1: 1,039 customers, $98.6K average, 1.7% above $1M.
customer headcount lognormal, median 180, sigma 1.1
0 1,200 2,400+
industry firm size is close to lognormal in every economy measured.
tickets per account heavy-tailed, alpha 1.45
1 13 26+
structural the top tenth of accounts files 38% of the queue, and none past 7%.
The bars are draws, the line is the density they are drawn against. Each shape carries where it came from, and the scorecard publishes how much of itself is an estimate.
draw again
04 / THE BURST
One outage, five customers, five different sentences
Unrelated accounts file about the same failure, each from their own timezone and in their own words.
the tall day: one saturated write replica, five reporters, in arrival order
- Nine Rivers 22:19 JST · 13:19Z Escalating: reporting dashboard renders empty on our sandbox (req 8f21c4)urgent
- Marlow Health 09:12 EST · 14:12Z Reporting dashboard renders empty for our whole teamurgent
- Kestrel Freight 14:31 GMT · 14:31Z Dashboards render empty since 14:05 for our EU usershigh
- Bower & Vale 15:48 CET · 14:48Z Is there an incident? dashboards render empty on productionhigh
- Alto Systems 07:03 PST · 15:03Z Reporting dashboard down for our overnight batch since 06:40normal
19% of the queue belongs to a shared incident, one day in 30, and they land midweek because deploys do.
05 / DELIBERATE MESS
The mess is on purpose, and declared
A tenant can be dosed with the housekeeping a real company has: a pasted placeholder, a spreadsheet's casing, the test account from 2023.
- placeholderBerlin, DEN/A
- casingMarlow HealthMARLOW HEALTH
- whitespaceRenewal - EMEARenewal - EMEA
- junk row-ZZZ test (delete me)
- duplicateAcmeAcme (old)
__ dose 0% of the column · cap 30%
the manifest
Every defect is served, not hidden: kind, collection, field, record, and the value it replaced. A duplicate the manifest claims is housekeeping; an undeclared one is a bug.
- 30% hard cap on any one column
- keyed hashed off the row's own id, so adding a field never moves the mess
- 0 ids, keys, domains or login emails touched - never a broken join
Opt-in and declared, so it benchmarks deduplication, DLP and access review instead of being noise.
06 / THE ESTATE
Many kinds of data, at the volume a real estate carries
The same company is projected into tabular systems, file stores, call transcripts, chat and rendered documents - and one tenant at the top size tier carries tens of thousands of records in each of them.
what the estate is made of
- tabular salesforce · hubspot · zendesk · jira
- transcripts gong calls, turn by turn, with their recordings
- chat slack channels and threads, including the ones an incident runs in
- file stores aws · google-drive · box · dropbox · sharepoint
- content docx · xlsx · pdf · txt/md · csv/json · png/jpeg · mp4 · parquet
one tenant, the top size tier
- contacts 18,766
- files 15,801
- calls 13,758
- tickets 12,000
- issues 12,000
- incident chat 4,354
6,086 hours of call audio, 1,752 distinct chat authors, 750 accounts they all belong to.
- 11 systems carry a projection of the same graph: six tabular overlays and five file stores, all agreeing on who works there and what happened
- 79,000 entries read back off one 20,000-document estate through Drive's, Box's, Dropbox's and AWS's own SDKs - every document in all of them
- 12,050 of the tenant's files are rendered documents and 750 are call transcripts, not rows with a filename
Volumes are one hyperscale segment's published answer key, the same file its graders are scored against; the four-store figures are the files-and-lake audit that drove each vendor's SDK across one estate and joined the results back to the graph.
07 / THE DETECTOR
Nine ways to spot fake data. Ours trips none of them.
Every number stands beside the same company generated the naive way.
each thing it checks, ours against naive
Every company, every check and everything the detector found is published in full on Data fidelity.
08 / LIVE OVER MCP
Connect to the live stack, not a snapshot
Every system in the company is a running instance. An agent connects over MCP, a client over the vendor's own API, and both read and write the same tenant.
the request
_POST /mcp_ _zendesk_
{"jsonrpc": "2.0", "id": 7,
"method": "tools/call",
"params": {
"name": "**get_ticket** ",
"arguments": {"ticket_id": 4182}}}
The same ticket over REST: GET /api/v2/tickets/4182.json
- Slack live
slack_get_channel_history{"ok": true, "messages": […]} - Zendesk live
get_ticket{"id": 4182, "status": "open", …} - Salesforce live
run_soql_query{"totalSize": 750, "done": true, …} - Jira live
getJiraIssue{"key": "OPS-311", "fields": {…}}
Every connector serves its vendor's REST API and an MCP endpoint off one port, against one tenant's state, so a write over MCP is there when the REST client reads it back.