Build next generation of the internet for Agent to Agent.

北京, 中华人民共和国
Joined November 2022
A bounded breadth-first search (BFS, which checks every state one action away before any state two actions away) found a five-step path to finish a task in our synthetic model, and a failed search means "unreachable within budget" only when the list of allowed actions is declared complete, otherwise "unknown." The search takes a current state, the allowed actions, a completion condition, and a resource budget. In a model from our research on agents that coordinate work between people, the task has four execution actions: transfer (move the data), project (produce the target representation), accept (confirm it is accepted), and read back (check the result). They are abstract state changes, with no real service connected. In one constructed scenario from the recorded run, the interface starts closed and those four actions find no path. Allow one action that existed but had not been run, "enable the interface," and it finds this path: enable the interface → transfer → project → accept → read back. What the model lacked was an activation condition, not a new way to transfer data. A queue, the list of states waiting to be checked, is first in, first out, so the path with the fewest actions, not the lowest cost, comes out first. Take a teaching fork with two routes, separate from the recorded run: start → A → A1 → goal and start → B → goal. After the start, the queue is [A, B]. Expanding A adds A1: [B, A1]. Next comes B, which reaches the goal, so the two-step route is found before the three-step one. The recorded run limited the search to 10 steps and at most one escalation to a person, plus cost limits. If the step limit drops from 10 to 4 and every action condition stays the same, the five-step route no longer fits, and the search reports the task unreachable within the 4-step budget, which does not show that no route exists. This four-step case is a teaching variant, not a second measured run. If the action list is declared complete and every allowed state was searched, the answer is "unreachable within budget." If the list admits it is incomplete, the answer is "unknown": the model does not list what a new tool would take. The model itself returns only a path or a verdict, but the two answers point people to different next steps: "unreachable within budget" to raising the budget or activating a closed precondition, "unknown" to adding real options. We ran three scheduling variants with the same action capabilities on ten small synthetic worlds. They are rule-based planners, not searches: each looked at the world once, then ran its plan or stopped. All three completed the task in the same six worlds and stopped in the other four. The bounded search decided what those four stops mean: three are unreachable within budget, none of them because the budget was tight (in one the value floor has already failed, and in the other two the owner refuses, one of them also with a closed route that no declared action can open), and one is unknown because that world's action list is declared incomplete. The variants share an implementation base, so this is not three independent validations. Once preparation actions, authorization conditions, and the completion criterion sit in one model, classical search already separates some obstacles that used to look the same. How this holds on real processes still needs testing. When a search finds no path, check whether the action list is declared complete before reporting "unreachable within budget."
1
3
Two plans that share 2 of 6 structural markers sit at Jaccard distance 1 − 2/6 ≈ 0.667, and a plan that only changes its title sits at 0, so check a batch by its closest pair. Encode each plan as a set of structural markers, then compute the Jaccard distance (1 minus shared markers over all distinct markers) for every pair. Plans titled "skill-sharing session," "experience exchange," and "knowledge workshop" can read differently while the same person teaches the same group the same content in the same time slot. That is one option. Our collaboration-discovery research includes a check for this after plan generation. For each plan the check reads the operation type (the kind of arrangement, such as training), the roles, the relationship edges (who delivers what to whom) between roles, and the stages and their actions. These form the marker set. A plan's title and summary stay out of the set, so rewriting them does not change its distance. Teaching example, made-up numbers. Plan A: a repairer fixes residents' old items. Plan B: the repairer teaches them to fix the items. A's markers: direct service, repairer is provider, resident is receiver, provider delivers repair. B swaps in training and provider delivers teaching. The sets share 2 of 6 distinct markers: distance 0.667. Rename A, markers unchanged: the set is the same, so the renamed plan is at distance 0 from the old A. For a batch, the check compares every pair and takes the smallest distance, not the average. If two plans are identical and a third differs greatly, the average can let the third plan dilute the duplicate; the minimum keeps the 0. The current setting requires at least three candidates, a minimum pairwise distance of at least 0.4, and no two plans with identical marker sets. This is for this round of research; the math cannot say a higher bar yields better plans. The limits come from the markers. "Repairer" and "maintenance worker" count as different roles unless the names are unified upstream. Two plans with the same roles and exchange types look identical even if one takes a week and the other three months, because this version has no duration marker. Price and quantity are not markers either. A larger distance does not make a plan more creative. Passing the bar means the markers differ; a generator can relabel roles to raise the distance while the arrangement stays the same. In one of our research runs the model wrote its own role names and stage actions as free text, and in all 15 batches every pair of plans scored the maximum distance of 1.0, so every batch passed. Roles and actions need a fixed vocabulary. In our tests, plans with different wording and identical structure are flagged as duplicates, and plans that differ in operations and role relationships pass. The check compares as intended; we have no evidence yet that readers choose better because of it. Before accepting a batch, list for each plan who does what, what is exchanged, and in what order. If two lists match, you have one plan with two titles.
1
19
Vectors from different embedding models can be made comparable through shared public anchor texts, but in our local diagnostic a fixed set of 128 anchors did not beat direct comparison on Recall@100 (about 0.529 vs 0.595, with labels from model judges). An embedding model (encoder) turns text into a vector of numbers. In collaboration discovery, a requester can encode what they need, and a candidate can encode what they can offer. The two vectors are then compared. Agents may use different encoders, and even when two vectors have the same length, the same position need not mean the same thing. Direct comparison has no general guarantee. The setup: both sides agree on the same public texts in a fixed order, called anchors. Each side uses its own encoder to compute the similarity between its local content and every anchor. In the new vector, each position refers to the same anchor on both sides. The idea has prior work in relative representations (Moschella et al.). A 2D teaching case. Model A writes object one as (1,0) and object two as (0,1). Model B's coordinate system is rotated 90 degrees, so the same objects become (0,1) and (-1,0). Cosine similarity compares direction: 1 is the same direction, 0 perpendicular, -1 opposite. It is not a probability of a match. Cosine between A's (1,0) and B's (0,1) for the same object is 0. Now both sides use the two objects as anchors, in fixed order. A reports "cosine 1 with anchor one, 0 with anchor two", giving (1,0). B does the same with its own coordinates and also gets (1,0). Cosine is now 1. This works because the two systems differ by a pure rotation, which keeps the angles between objects unchanged. Real encoders can differ in far more complicated ways. Using the same anchor list in the same order guarantees that we align the same anchors, not that two models understand them the same way. Our run used 128 anchors, which are short texts taken in a fixed order from the public texts in the test cases. We scored (A's need, B's candidate) and (B's need, A's candidate), and averaged the two. The cost is that the new vector keeps only the differences the anchors can capture. If every anchor is about woodworking, two objects that differ a lot in programming skill can both look dissimilar to all of them, so their coordinates end up close, and close coordinates don't mean they can replace each other. More anchors of the same kind may not help, because the problem can be coverage rather than count. In a local diagnostic, mean Recall@100 (share of labeled relevant items found in the top 100, computed per case and averaged over 37 cases with evaluable positives) was about 0.529 for anchor coordinates and about 0.595 for comparing the raw vectors directly across models. For scale: each case had only about 180 candidates, so a random ordering would be expected to find about 0.555 of the labeled relevant items in its top 100, and both numbers sit close to that baseline. The labels come from model judges, and only fully labeled cases were used, so this is not a full gold set. These point estimates alone don't establish a significant difference.
1
27
Nature Towow.ai retweeted
Con esta filosofía hoy no tendríamos lectores de códigos de barras, medidores precisos de distancias, cirugía láser, cortadoras industriales de acero entre cientos de cosas más. El primer láser se fabricó “porque podemos”, como experimento para demostrar un principio físico, sin tener claras sus aplicaciones prácticas. Hoy es una tecnología fundamental en medicina, industria, telecomunicaciones e investigación científica. A veces primero descubres lo que puedes hacer y después descubres para qué sirve. De hecho es bastante habitual. Otras veces no y no pasa absolutamente nada, hay miles de inventos chorras y no pasa nada.
¿Para que cojones quieres que tu coche haga un backflip? Creo que este es el invento más inútil que he visto en mi vida, no se me ocurre mayor ejercicio de ostentación Esto es lo que pasa cuando la gente tiene demasiado dinero
78
198
2
1,556
26,591
Nature Towow.ai retweeted
Claude Code 经常会把一些比较口水话的表达直接怼在网页上,把网页搞得像是开发笔记而不是产品。大家有什么约束的诀窍么?
25
7
121
20,906
194 times in one day, Claude Code compacted a session whose real context was half what the record said. Every number we had was true. We still fixed the wrong thing first. This is problem 1 in a series. Flowness is a multi-agent system run by one person and a group of AI agents: six months in production, over 140 billion Claude tokens on the sessions we still have records for, used in real client delivery. The problems that make or break a system like this are small, and most of them don't have names yet. One per post, with the numbers. What happened Sept 13: we lowered the auto-compaction window for program-started sessions from 650k to 250k tokens. Sept 14: 452 auto-compactions. The two days before: 17 and 11. 194 of the 452 had a recorded pre-compaction size about 2x the session's real context. In every one of them, the previous request had called the advisor tool. One session, read line by line. 13:09:34 UTC, a request calls the advisor. The main model reads the context before the call and after it: 124,519 and 127,361 tokens. The top-level usage records the sum, 251,880. 13:15:09, the session auto-compacts with preTokens 254,808. The real context was 127,361. Three numbers, three wrong questions 1. Top-level usage. We checked 3,149 advisor requests: every one is the exact sum of the main model's passes. Right answer to "how many tokens were read". Wrong answer to "how big is the context", which is what we used it for when setting the window. Median ratio: 1.99x. 2. Advisor call counts: 1,612 and 1,725 a day. Reproducible from our cost script, so treated as fact. But one request writes 5+ transcript lines, each carrying the same usage block, and we summed lines. Deduplicated by request id: 305 and 330. Plain double counting. The correct dedup had been used a week earlier in another investigation and never made it into the report script. 3. Compaction totals: 17, 11, 452. Nobody divided each compaction's preTokens by the real context at the time. When we did, Sept 14 was bimodal: 118 near 1.0, 156 near 2.0, 14 in between. Two causes at once, the lower window and the doubled number. The total couldn't tell them apart. Each piece of evidence was real. Each was used to answer a question it doesn't answer. The agent doing the judging had the true numbers in hand the whole time, and the fields came from a client whose docs we had never read. Where it stands Advisor is off by env var on program-started sessions. 239 sessions dispatched after the fix, zero advisor calls (checked against dispatch records, data through Sept 24). It kept showing up in other session types, and on Sept 24 its daily usage passed any day before the fix. Doubled compactions have been zero since Sept 23. We haven't verified why. Three checks for your own transcripts Ours were Claude Code 2.1.270, main and advisor both claude-sonnet-5. Other versions may differ. - Count lines per requestId. Dedup before you sum usage. - In requests with an iterations array: max segment is context size, sum is tokens read. Don't mix them. - Divide each compact_boundary's preTokens by the last real context. Near 2, look for an advisor call in the previous request. Near 1, it's not this. The question we're still sitting with: if your system takes a usage field someone else wrote and turns it into a threshold decision, is there a step where you check which question that field actually answers? We didn't have one. Full write-up, script, and the source of every number in the first reply. Problem 2 tomorrow.
12
4
657
Two corrections. (1) Doubled compactions stopped Sept 23, matching a Claude Code 2.1.273 fix for advisor turns counted at about 2x. We upgraded from 2.1.270 to 2.1.280 on Sept 22-23. (2) We had read Anthropic's advisor docs on Sept 6: top-level usage sums the main model's passes.
5
A sub-agent decided a result should not go into the ledger and said so in its final report. Our coordinating agent wrote it anyway, 6.7 seconds before that report existed. The ledger is append-only, so the record is still there. Problem 5 in the series. Flowness is a multi-agent system run by one person and a group of AI agents, six months in production, over 140 billion Claude tokens on the runs we still have records for. Problem 4 was a "pass" that never judged anything. This one is about order of arrival: the sub-agent's output reached the coordinator minutes before its judgement of that output. The coordinating agent is a long-running Claude Code agent that dispatches work, collects results and writes the ledger, an append-only event log. Sub-agents are one-off agents it launches in parallel through a workflow. They don't write the ledger; anything to record goes back as a command for the coordinator to run. What happened (July 29, times UTC) Earlier that day the coordinator wrote a criterion: the ledger must hold adjudication records from each of three review roles, one being the requirements-traceability review. 14:49, the coordinator dispatched a sub-agent to run that review on real design documents and return a result file. The sub-agent read the role definition file at the start. Line 75 says this role's only output event is an issue record, not an adjudication record. Around 15:35 it had a 30 KB result file covering 8 design documents. After 15:36 it turned to look up the write command for issue records. From its tool calls we infer that this is where it saw the conflict and decided not to return an adjudication command, and to explain why in its final report. 15:36, the coordinator checked the workflow's run log: 4 of 7 sub-agents done, this one still running, no report from it. On disk it found result files for all three roles and noted all three were in. 15:38:57, using the traceability result file, it issued the write command for the adjudication record. 6.7 seconds later the sub-agent wrote its final report. It says it did not hand-build the write command, because that would itself manufacture a false event that doesn't match the role. 15:39:29, the commit gate accepted the event. 15:46:26, the workflow finished and the report was delivered, 7 minutes 29 seconds after the write command. 15:47, the coordinator read the role definition file and confirmed the sub-agent was right. Over five weeks, 4 more records of this kind appeared under that role. Four pieces of evidence The coordinator had four pieces of evidence for the write. Each, then what it actually meant. 1. The acceptance criterion asked for this record. The coordinator wrote it itself. But this role by definition never produces adjudication records, so the criterion could not be met correctly. 2. Upstream documents said so too. Two engineering documents describe the role as producing adjudication records. But the role file and a design document say it doesn't, and the role file has a section explaining that those two engineering documents are transcription errors. The records show no read of that file by the coordinator before writing; its context had been compacted earlier, so they can't prove whether it read it before. Its own dispatch letter already said the role produces issue records. 3. The write command's checks all passed, and a reverse test was run. The coordinator forged independence evidence twice, the command rejected it twice, and the genuine write was accepted. But those checks answer "was the review done independently?", not "should this role produce this record?". 4. The result file was complete: 30 KB of answers across 8 documents. But it holds review content. Whether that content should be recorded as an adjudication was a judgement in the sub-agent's final report, which didn't exist yet and wasn't in the run log. It read the output, not the judgement. One more reason, which we infer: the dispatch method gave the sub-agent's refusal no power. Work reaches the coordinator by three routes. Result files written mid-run can be read at any moment. The final report goes into the run log when the sub-agent finishes. When all sub-agents are done, all reports are handed back together. The sub-agent's two responses, withholding the command and explaining in its report, both use slow routes. Its output used the fastest. Output arrives first, judgement later, and a write only needs the output. It isn't the race from problem 2: the file the coordinator read was real, and the judgement hadn't arrived. The sub-agent read the role file at the start. The coordinator held the progress of at least 7 sub-agents and a checklist, and as far as the records show never read it. We don't rank the two: the process put the correct judgement where it had no hold over the write. Three checks for your own setup - Treat a sub-agent's output file and its final report as two things. The report usually holds its judgement of whether the output can be used. Put the write time and the matching final report's time on one timeline. - Make the refusal happen at the write side. Our design suggestion, not yet built: the write command knows which record types each role may produce and rejects the rest. Does each write entry point validate both "is the evidence complete" and "is this role entitled to produce this record"? As of Oct 6 our write side is unchanged. The ledger doesn't record who called the write command for the 4 later records, so we can't tie them to July 29's cause; the write side just didn't stop them. - Look at what your reverse test forged. It proves a check rejects one kind of wrong input. Ours forged independence evidence; what we should have worried about was role eligibility. The open question: how does the write side learn what a role should produce? The definition lives in a file written for models. Here two engineering documents and the role file already disagreed, and a role-to-record table inside the write command is one more copy that can drift. If role definitions and write validation live in two places, do you read the role file at write time, pin them together with a test, or require every write to carry the id of the sub-agent's final report? And when may a coordinator read a sub-agent's mid-run files? We don't want to ban it, yet this error came in that way. Do you mark them drafts? That is the last problem in this series, and the full write-up is in the first reply.
3
1
2
176
Full write-up with the timeline (six moments, split by clock source), what we did afterwards and which step each of the six things covers, which gaps are still open, why read-side validation did not stop the later records, the copy-paste timeline script, and the account of how an erratum's body text got lost (Chinese): towow.net/articles/flowness-… 第 5 期:子 agent 判断这份结果不该落账,并把理由写进最终报告;协调 agent 在报告写出前 6.7 秒就把它落了账,而账本只能追加,这条记录至今还在。它手里有四条证据,每条都回答了另一个问题:验收条件要这条记录、上游文档也这么写、写入检查正反都验证过、结果文件内容完整。根子是派发方式让子 agent 的产物先到、判断后到,而写入只需要产物。三条检查:把产物文件和最终报告当成两样东西;让拒绝发生在写入端;看一眼反向测试伪造的是不是你担心的那种错误。 上一期在上一条:xitter.cf/NatureBlueee/status/21…
Two of our checks logged 145 "pass" records. Not one of them judged anything. They read the wrong field name, so the set of objects they checked was empty every time, and "every object satisfies the rule" is true of an empty set. Problem 4 in the series. Flowness is a multi-agent system run by one person and a group of AI agents, six months in production, over 140 billion Claude tokens on the sessions we still have records for. Problem 3 was a retry cap the dispatch path that was actually running never checked. This one is a check that records "pass" whether or not it looked at anything. Add a check to a write path. A month later it has run thousands of times, the log is all "pass", and it has never blocked anything. Most people read that as: the check works, and the input has been clean. Both assume the check judged something every time, and the log can't say whether it did. We misread it that way once. What happened (July 29, times UTC) Every time an agent in Flowness changes shared state, it packages the change as a commit and hands it to a commit gate. The gate runs a series of checks, and registration code writes each result into an "accept" record in the ledger: pass, not applicable, or would-reject. Would-reject comes from checks in observe mode: the commit is judged non-compliant, logged, and let through. A real rejection goes into a separate "reject" record, named after the failure reason rather than the check. We were verifying one check. If an engineering design object is marked "consensus candidate", its status must be "accepted" and it must carry a written rationale. Until then the check had left 485 records, all "not applicable". 02:29, we logged a todo. Its third acceptance criterion required a reverse control: change the status to "reviewed", and the same flow must produce a record that violates the rule. Testing only the positive case doesn't count. 02:35, positive probe: status "accepted", marked as a consensus candidate, with a rationale. Record: "pass". 02:39, reverse probe: identical except status "reviewed". Record: "would-reject". Together they show the check reads the object and judges it. The first alone could come from a check that reads nothing and passes everything. 02:58 to 03:02, we ran a census script over every result each check had ever produced. Of 38 checks, 12 were always "not applicable", 24 only ever showed "pass" (and "not applicable"), and 2 had shown both "pass" and "would-reject". One of the 2 was the check we had just probed, and its only "would-reject" was our probe. The other also has one; we haven't checked its source. Three paths to a "pass" without a judgement All three are in our production ledger. 1. The object doesn't trigger the check. In the code, an object not marked as a consensus candidate yields an empty problem list, and the registration code records every empty list as "pass". As of Oct 6 this check had 332 "pass" and 16 "would-reject". The ledger has only 20 creations of a candidate-marked object: 16 not "accepted", matching the 16 "would-reject", and 4 "accepted". So we infer at most 4 of the 332 passes came from a candidate that was really judged. 2. A missing baseline returns "pass, skipped", and the flag gets dropped. The scope check compares a commit against a context bundle (it marks what an agent may change). When the bundle can't be found, the function returns "pass, skipped", and the registration code writes "skipped" into a free-text note while the result field stays "pass". On census day 95.1% of this check's passes carried the "skipped" note; on Oct 6 it was 98.1% (58,139 of 59,287). This is fail-open: when the check can't get the input it needs, it lets the commit through instead of raising an error. 3. A wrong field name empties the object set. Two other checks, 145 passes between them, have conditions shaped like "every object satisfies X". They read the object id from a field called id, while the production flow writes concept_id, so each run saw an empty set, where "every one satisfies X" is vacuously true. On July 28 at 07:18 one of them left its first "pass", which we believe is the signal we reported as the first real production evaluation of those checks. On July 29 at 03:00 a replay split by time range overturned that. What the three share: with nothing to judge, the check didn't return "not applicable"; it got recorded as "pass". They coexist because the check record has no field for how many objects the run checked. The breakdowns above were reconstructed afterwards from creation events and note text. We logged that field as a todo and haven't built it. Each "pass" truthfully answers "did the check report a problem?". The mistake was using it to answer "did the check judge anything?". Three checks for your own setup - Look at what your checks write when there's nothing to judge. If the answer is "pass", or "skipped" logged as "pass", the pass records can't prove the check works. Look for records that carry both a "pass" and any "skipped" or "missing" note. - Find one record where each check rejected a known-bad input. Build an input that should be rejected, send it through the real flow, read the record, and write that reverse control into the acceptance criteria up front. The probe stays in the ledger. We hand-built reverse inputs for two checks, and as of Oct 6 none of our observe-mode checks has been promoted to enforcing. - Before counting rejections, confirm where they are written and what they are named. Both times we counted what a check had blocked, we missed real rejections. The census script read only accept records, so it couldn't see the 376 reject records already in the ledger: survivorship bias. An evidence tool read only a table summarised by check name, while rejections are named by failure reason. The open question: what should a check do without its baseline? Rejecting would block every commit behind the 98.1% of its pass records written without a baseline. Letting them through means no check exists for them. If your check depends on context that is often missing, which way do you go, and how do you count the cost? And an observe-mode check never blocks, but proving it judges needs real negatives. A hand-made probe in an append-only ledger can't be deleted and enters later statistics. Do you wait for natural negatives, inject probes, or build them in a replay, and how do you keep probes out of production numbers? Full timeline, the nine fixes we tried and the census script are in the first reply. Problem 5 tomorrow.
23
Keep BM25 as the retrieval baseline, and make any newer method beat it on the same data. Three small rules keep common words and long cards from winning on raw word counts: rare words weigh more, repeats add less each time, and long cards get a length adjustment. In our discovery front-end research, the query is a collaboration need and the documents are capability cards that people have disclosed. Say someone writes "find a repair service for an old wooden chair". One card is short: "wooden chair repair, mortise-and-tenon reinforcement". Another is long and repeats "service" over and over. Counting hits favors the long card, while the useful clue sits in the short one. A worked example with teaching numbers. Take three equal-length cards where one query word appears on only one of them. Rarity: weight = ln(1 + (N − n + 0.5) / (n + 0.5)), with N cards and n containing the word. Here that is ln(1 + 2.5/1.5), about 0.981. If all three cards had the word, it would be about 0.134, because it barely helps tell them apart. Saturation: with k1 = 1.2 and an average-length card, the repeat factor is tf × 2.2 / (tf + 1.2). One occurrence gives 1, two give 1.375, ten give about 1.964. The word's contribution goes 0.981, 1.349, 1.927. Length: a card twice the average length, one occurrence, b = 0.75 gives a factor of 2.2/3.1, about 0.710, and the contribution drops from 0.981 to about 0.696. Now a ranking with three equal-length cards. The query has the rare word and a common word that all three cards contain. Card A has each once. Card B has no rare word but the common word ten times. Card C has the common word once. Raw counts put B ahead of A. BM25 scores A at about 1.114, B at 0.262 and C at 0.134, so the order is A, B, C. BM25 is an existing method from probabilistic relevance research. For collaboration we also turn disclosed language and direction into features, so a need to find a service looks for candidates who provide one, and Chinese text is split into pieces such as two- and three-character ones. In one local diagnostic run, BM25 found about 0.538 of the relevant cards in its top 100 on average (Recall@100) over 37 cases, on partial research material with incomplete labels. That number is a starting line for comparison. We later compared multi-path fusion and new representations, and the results did not support a simple "newer is better" story. Keyword matching has a blind spot. If the repairer writes "mortise-and-tenon reinforcement" and the user writes "chair wobbles", they may not share enough words, and an ability nobody has written down can't be found.
2
23
Correction to the 0.538 above: each case had about 180 candidates, so a random ordering would be expected to find about 0.555 of the relevant cards in its top 100. BM25 sits at that level, so the number says little on its own; we should have shown the random baseline beside it.
3
OpenAI 官方博客披露了核心团队用 GPT-6 系列维护代码库的一手工程实践。直接公布了几个实际运行的提示词, 靠这些提示词在两周内合并了 1400 多个清理 PR,删除超过 800k 行代码,并将一个服务的容器镜像压缩48%。 第一个提示词用于清理死代码 “请帮我找出并清理仓库里的无用代码。你可以随意查看 Slack、Statsig(功能开关平台)或任何需要的来源,用来确认这些代码确实不再被使用、可以被清理或简化。” 这个提示词的关键在于允许 GPT-6 Astra 自主去翻阅 Slack 讨论、Statsig 实验配置甚至生产环境的性能 profiling数据,只有在确认生产环境零调用后才在 PR 中列出删除依据。 第二个提示词用于清理更棘手的废弃实验与功能开关 “/goal 找出整个仓库中所有陈旧、常量化、已废弃或全量上线的 Statsig开关、配置和实验,在不改变生产行为的前提下安全移除。审计所有项目资产,不限于标记为陈旧的对象。通过枚举、常量、包装函数、别名和动态拼 接名称寻找间接引用。核对生产引用的常量,不只给保守清单。结合生产遥测与性能分析评估 CPU 开销,找出昂贵的无用判断。生成 Markdown报告,按归属和文件工作流分组以便并行处理,附带生产取值、证据与 CPU 开销。不要修改线上配置或服务。” 第三组提示词用于 CI 优化与规则自省 “关于减轻本仓库的 CI 负载你有什么想法?请将想法列成表格,并根据该仓库的历史运行记录,按每天预估节省的 CI 分钟数进行排序。” 面对不稳定测试修复,他们运行: “/goal 查看所有最近的 CI 运行记录,找出偶发失败的测试并尝试修复,成功则提交PR。你的任务是针对简单问题找到明确修复方案,而不是穷尽修复所有问题。” 针对 agent 上下文规则的自检提示词更精妙: “翻阅我最近的 Codex 会话记录,找出一条误导了 agent 或导致无效工作的 AGENTS.md指令。选出该会话提示词,在相同仓库快照和模型下重放两次:一次保持原指令不变,一次仅移除或修正该指令。对比任务质量、agent 行为、工具调用、token 消耗与成本,展示该指令并说明修改是否有效。” 强烈建议好好学习和利用这些应用于超大工程实践的提示词
16
110
5
851
56,918
Nature Towow.ai retweeted
我现在越来越觉得,很多人对 AI 的想象力,已经被自己过去十几年的工作经验给限制死了。 今天看到 Claude 工程负责人 Felix Rieseberg 写了一篇文章,叫《How to be more ambitious》,教人如何更有野心地使用 AI。我觉得这篇文章值得所有重度 AI 用户读一遍,包括我自己。 他给出了一套具体的方法。 比如,公司要做季度经营汇报。绝大多数人的第一反应,是让 Claude 帮忙制作 PPT,厉害一点的会把数据丢进去,让它分析一下业务表现。 Felix 认为,这才刚刚开始。 你可以继续要求 AI 找出三个最值得管理层讨论的决策,分析各自的利弊。然后再进一步,既然季度汇报的目的是提前发现问题、合理分配资源,那为什么非得做 PPT?能不能设计一套更好的机制,用历史数据验证它能否更早发现问题,再跟原有流程并行运行一个季度? 他自己也经历过这样的转变。 以前,他让 Claude 一次修复一个软件崩溃问题。后来,他开始直接要求 Claude 帮他持续维持应用的稳定性。为了做到这一点,他不得不让 AI 能够访问崩溃日志、代码版本记录,以及不同操作系统的测试环境。 我觉得这个案例特别好,因为它说明了,所谓的「更有野心」,其实经常意味着你得重新审视自己习以为常的工作方式。 Felix 还讲了另外两个方向。 一个是深度,让 AI 真正使用行业顶尖专家的方法、工具和原始数据,而非仅仅模仿专家说话的口气。 另一个是广度,把原本成本高昂的跨学科协作变成常规操作。分析一家公司,可以同时引入记者、数据科学家、做空者和法务会计的调查方法。 当然,他也特别强调,最终结果必须接受外部验证,不能让模型自己给自己打分。 看完之后,我一直在想一件事。 我们现在已经很擅长让 AI 替自己完成更多工作了。一个人开十几个 Agent,同时推进十几个任务,每天忙得不亦乐乎。但如果仔细看,这些任务可能跟五年前、十年前没什么区别。 很多所谓的 AI 工作流,只是给过去的工作方式装上了一台更快的发动机。 我觉得接下来真正值得拉开差距的,是一个人有没有能力重新定义问题,甚至敢不敢放弃自己过去认为理所当然的工作流程。 如果你对工作的理解只能到「交付一份 PPT」,那么给你再强的模型,最后大概也只能收获一份更快、更漂亮的 PPT。 AI 的能力每隔几个月就可能发生一次巨大变化,但人的思维惯性不会自动跟着升级。 这可能才是「更有野心地使用 AI」最难的地方。
Hi, I'm Felix. I'm an eng lead working on Claude. I love watching people take flight and do things they never thought possible. We often describe that as "being more ambitious" when using AI, which is tricky advice to follow. I wrote a tutorial: felixrieseberg.com/how-to-be…
114
483
41
2,585
239,859
Nature Towow.ai retweeted
Je vais dire quelque chose qui risque de déplaire à beaucoup de monde, mais tant pis. Je crois qu’une partie de notre société est en train de perdre quelque chose de bien plus grave que sa compétitivité économique. Elle est en train de perdre sa capacité à rêver. Hier, Tesla a présenté une démonstration spectaculaire autour d’une voiture capable de quitter le sol. Un prototype, certes, pas encore la voiture volante de Retour vers le futur. Mais quand même, bordel. On parle de technologies qui semblaient relever de la science-fiction quand nous étions gamins. Et ce matin, en regardant certaines réactions françaises, qu’est-ce que je découvre ? « Ça sert à rien. » « Musk est un raciste. » « Ça ne règle pas les problèmes de recharge. » « Ça n’efface pas ses saluts nazis. » Mais sérieusement, qu’est-ce qui nous est arrivé ? À quel moment avons-nous perdu cette âme d’enfant qui nous faisait ouvrir grand les yeux devant une invention ? Et le plus triste dans tout ça, c’est qu’on semble avoir oublié notre propre histoire. La France, c’est le pays des frères Lumière, qui ont contribué à faire naître le cinéma. C’est le pays de Louis Pasteur, dont les travaux ont révolutionné la microbiologie et la vaccination. C’est le pays de Nicéphore Niépce, pionnier de la photographie. C’est le pays des frères Montgolfier, qui ont envoyé l’être humain dans les airs à bord d’une montgolfière. C’est le pays de Blaise Pascal, qui concevait déjà une machine à calculer au XVIIe siècle. C’est aussi le pays du TGV, et l’un des deux pays qui ont donné naissance au Concorde. Vous imaginez ce que représentaient ces inventions à leur époque ? Des humains qui osaient accomplir ce que beaucoup pensaient impossible. Des gens qui n’acceptaient pas les limites de leur temps. Des visionnaires, des ingénieurs, des scientifiques, des entrepreneurs qui voulaient repousser les frontières du réel. Nous avons été ce pays-là. Alors comment avons-nous pu en arriver à un point où notre premier réflexe devant l’extraordinaire semble parfois être de chercher pourquoi il faudrait le mépriser ? SpaceX récupère des fusées qui reviennent se poser sur Terre ? On parle immédiatement d’Elon Musk et de ses provocations. Des robots humanoïdes commencent à réaliser des tâches physiques de plus en plus complexes ? « Ça va détruire des emplois. » L’IA ouvre des perspectives gigantesques pour la médecine, la science, l’éducation et la création ? « Ça pollue, ça vole le travail des artistes, ça sert à tricher. » Un entrepreneur annonce vouloir réaliser quelque chose d’incroyable ? « Encore un milliardaire qui veut s’en mettre plein les poches. » Mais est-ce qu’on réalise seulement ce qui est en train de se passer ? Nous vivons une époque où des fusées réutilisables se posent après leur mission, où l’IA accélère certaines découvertes scientifiques, où des robots apprennent à évoluer dans notre monde, où des personnes seules commencent à créer des choses qui nécessitaient auparavant des équipes entières. Et devant tout ça, on serait devenus incapables de dire simplement : « Putain, c’est incroyable. Comment est-ce qu’ils ont réussi ça ? » Je ne demande pas qu’on admire aveuglément les milliardaires. Ni qu’on ferme les yeux sur les conséquences sociales, environnementales ou politiques de leurs projets. On peut condamner les propos d’Elon Musk tout en reconnaissant les prouesses des ingénieurs de SpaceX et de Tesla. On peut défendre les travailleurs tout en trouvant la robotique fascinante. On peut vouloir encadrer l’IA tout en étant émerveillé par ses possibilités. L’esprit critique n’a jamais obligé personne à devenir cynique. Et c’est justement ce cynisme qui me désespère. J’ai parfois l’impression qu’on a remplacé l’admiration par la jalousie, le goût du risque par la peur de l’échec, l’ambition par la suspicion et le rêve par le sarcasme.
778
1,476
227
8,712
445,985
Nature Towow.ai retweeted
餐厅完蛋了! 厨师完蛋了! 我买了空气炸锅,想吃什么可以自己做! 菜谱全在网上!免费!你也可以! — AI编程自媒体行业现状
83
53
21
817
57,714
Two of our checks logged 145 "pass" records. Not one of them judged anything. They read the wrong field name, so the set of objects they checked was empty every time, and "every object satisfies the rule" is true of an empty set. Problem 4 in the series. Flowness is a multi-agent system run by one person and a group of AI agents, six months in production, over 140 billion Claude tokens on the sessions we still have records for. Problem 3 was a retry cap the dispatch path that was actually running never checked. This one is a check that records "pass" whether or not it looked at anything. Add a check to a write path. A month later it has run thousands of times, the log is all "pass", and it has never blocked anything. Most people read that as: the check works, and the input has been clean. Both assume the check judged something every time, and the log can't say whether it did. We misread it that way once. What happened (July 29, times UTC) Every time an agent in Flowness changes shared state, it packages the change as a commit and hands it to a commit gate. The gate runs a series of checks, and registration code writes each result into an "accept" record in the ledger: pass, not applicable, or would-reject. Would-reject comes from checks in observe mode: the commit is judged non-compliant, logged, and let through. A real rejection goes into a separate "reject" record, named after the failure reason rather than the check. We were verifying one check. If an engineering design object is marked "consensus candidate", its status must be "accepted" and it must carry a written rationale. Until then the check had left 485 records, all "not applicable". 02:29, we logged a todo. Its third acceptance criterion required a reverse control: change the status to "reviewed", and the same flow must produce a record that violates the rule. Testing only the positive case doesn't count. 02:35, positive probe: status "accepted", marked as a consensus candidate, with a rationale. Record: "pass". 02:39, reverse probe: identical except status "reviewed". Record: "would-reject". Together they show the check reads the object and judges it. The first alone could come from a check that reads nothing and passes everything. 02:58 to 03:02, we ran a census script over every result each check had ever produced. Of 38 checks, 12 were always "not applicable", 24 only ever showed "pass" (and "not applicable"), and 2 had shown both "pass" and "would-reject". One of the 2 was the check we had just probed, and its only "would-reject" was our probe. The other also has one; we haven't checked its source. Three paths to a "pass" without a judgement All three are in our production ledger. 1. The object doesn't trigger the check. In the code, an object not marked as a consensus candidate yields an empty problem list, and the registration code records every empty list as "pass". As of Oct 6 this check had 332 "pass" and 16 "would-reject". The ledger has only 20 creations of a candidate-marked object: 16 not "accepted", matching the 16 "would-reject", and 4 "accepted". So we infer at most 4 of the 332 passes came from a candidate that was really judged. 2. A missing baseline returns "pass, skipped", and the flag gets dropped. The scope check compares a commit against a context bundle (it marks what an agent may change). When the bundle can't be found, the function returns "pass, skipped", and the registration code writes "skipped" into a free-text note while the result field stays "pass". On census day 95.1% of this check's passes carried the "skipped" note; on Oct 6 it was 98.1% (58,139 of 59,287). This is fail-open: when the check can't get the input it needs, it lets the commit through instead of raising an error. 3. A wrong field name empties the object set. Two other checks, 145 passes between them, have conditions shaped like "every object satisfies X". They read the object id from a field called id, while the production flow writes concept_id, so each run saw an empty set, where "every one satisfies X" is vacuously true. On July 28 at 07:18 one of them left its first "pass", which we believe is the signal we reported as the first real production evaluation of those checks. On July 29 at 03:00 a replay split by time range overturned that. What the three share: with nothing to judge, the check didn't return "not applicable"; it got recorded as "pass". They coexist because the check record has no field for how many objects the run checked. The breakdowns above were reconstructed afterwards from creation events and note text. We logged that field as a todo and haven't built it. Each "pass" truthfully answers "did the check report a problem?". The mistake was using it to answer "did the check judge anything?". Three checks for your own setup - Look at what your checks write when there's nothing to judge. If the answer is "pass", or "skipped" logged as "pass", the pass records can't prove the check works. Look for records that carry both a "pass" and any "skipped" or "missing" note. - Find one record where each check rejected a known-bad input. Build an input that should be rejected, send it through the real flow, read the record, and write that reverse control into the acceptance criteria up front. The probe stays in the ledger. We hand-built reverse inputs for two checks, and as of Oct 6 none of our observe-mode checks has been promoted to enforcing. - Before counting rejections, confirm where they are written and what they are named. Both times we counted what a check had blocked, we missed real rejections. The census script read only accept records, so it couldn't see the 376 reject records already in the ledger: survivorship bias. An evidence tool read only a table summarised by check name, while rejections are named by failure reason. The open question: what should a check do without its baseline? Rejecting would block every commit behind the 98.1% of its pass records written without a baseline. Letting them through means no check exists for them. If your check depends on context that is often missing, which way do you go, and how do you count the cost? And an observe-mode check never blocks, but proving it judges needs real negatives. A hand-made probe in an append-only ledger can't be deleted and enters later statistics. Do you wait for natural negatives, inject probes, or build them in a replay, and how do you keep probes out of production numbers? Full timeline, the nine fixes we tried and the census script are in the first reply. Problem 5 tomorrow.
2
172
Full write-up with the timeline, five figures, the per-path numbers, which of the nine fixes covers which gap, the Oct 6 census of 73 checks, and the census script (Chinese): towow.net/articles/flowness-… 第 4 期:两道检查记了 145 条"通过",没有一条判断过。它们读对象编号时用错了字段名,被判的对象集合每次都是空的,空集合上"每一个都满足"恒为真。账本里至少有三条路径会在没有判断时写出"通过":对象不触发检查、缺基线时"通过且已跳过"的标记被丢掉、字段名读错。检查记录里没有"这次检查了几个对象"这个字段,所以这些数是事后对出来的。每条"通过"都如实回答了"检查有没有报出问题",错在被拿去回答"检查有没有判断"。 上一期在上一条:xitter.cf/NatureBlueee/status/21…
One task was handed to 9 sessions in a single day. The cap on automatic redispatch was 3, the retry counter ended at 8, and the cap never fired once. Problem 3 in the series. Flowness is a multi-agent system run by one person and a group of AI agents, six months in production, over 140 billion Claude tokens on the sessions we still have records for. Problem 2 was a ps | grep that found nothing and a script started twice. This one is a retry loop whose checks all answered "can we dispatch now?" and none asked "is this different from last time?" What happened (Sept 6, times UTC) Flowness handed the same task to 9 executor sessions in a row (background Claude Code sessions, each picks up one task). The first 8 did not finish. The 9th completed at 17:11. The 8 failures: acceptance conditions that could not be met (3), a rejected commit, a session misusing a command, a coordinating agent stopping a session by mistake, a full disk, and one session that vanished for a reason we never found. In at least 3 of the redispatches, the new session got the same task package (what to do, which files it may touch, the acceptance conditions) as the one that had just failed. Session 2, 04:23: same acceptance conditions. It retested, found the condition cited a reading from a different code path, and aborted to ask for a replan. Session 3, 07:23: the new package changed the condition to "time before vs. after differs by at least 1500 ms". That threshold came from a linear cost model in a report and had never been measured. The measured difference was 244 ms. Session 4, 09:03: it ended itself with the "could not complete" command, then wrote that the old session was closed and it was starting over. The system took that terminal record at face value and the task became dispatchable again. Sessions 5 and 6 reused session 4's package. One was stopped by the coordinating agent, which took it for a duplicate start. The other hit a root partition with 626 MB left, while the acceptance test copies a ~2 GB working tree on every run. Session 7, 13:23: the process disappeared during the final completion check, with no terminal record. Session 8, 15:42: it reused session 7's package. The condition wanted at least 10 lookups per call, which depends on how many sessions are active on the machine. It measured 7 in three consecutive windows. Session 9, 16:42: the fourth replan split that condition in two, neither depending on the session count. Both passed. Four pieces of evidence 1. Most aborts followed procedure: log the inconsistency, ask for a replan, write a terminal record, and planning sessions published new versions. A rule pauses dispatch while "replan requested, new version not yet published", and it worked where it was designed to. But the aborts of sessions 1, 4 and 5 were outside its scope and session 7 left no terminal record, so sessions 2, 5, 6 and 8 went out with no new version. Of the four non-success terminal states, only one makes the dispatcher wait. 2. Four pre-dispatch checks all said yes: any active session, a dispatch marker, phase start conditions, concurrency slots. They ask "can we dispatch now?". Not one compares the package or the acceptance conditions with last time. 3. A new task package existed. Four replans each published a new version, which looks like new information. Session 3's new package swapped a ratio condition for an absolute difference derived from the same unmeasured model, and failed because of it. 4. A retry cap existed, written in June, default 3. It is only checked in the batch dispatch of the long-running orchestration service, and that service was paused. The one automatic entry running was a dispatcher that fires every 20 minutes and calls a single-task dispatch command. That command only reads whether a circuit-breaker marker file exists. It never compares the retry count, so on this path the marker is never written, and the task's directory had none. The counter went up correctly to 8 and no dispatch decision compared it to 3. This comes from reading the code and the runtime counter files; we did not run a controlled experiment. Sessions 2, 3 and 8 failed because the acceptance condition depended on something the executor can't control (another code path's reading, an unverified threshold, the number of active sessions). Any executor would fail it. Nobody saw this because our monitoring only watches for "not dispatching". On Sept 5 the system dispatched nothing for four hours without anyone noticing, so we added an alert for two consecutive rounds with dispatchable tasks and zero dispatches. Nothing alerts on "the same task dispatched too many times", and the ledger has no dead-letter notice for this task on Sept 6. We found out because the person running the system saw a task being redone again and again and asked whether we were wasting tokens. Three checks for your own setup - Give the retry counter a reader. List every entry point that can start a task and check which ones compare the count. A counter no dispatch path reads protects nothing. Grep where it is written and compared. An alarm on redispatches per task and spec can be the reader too. - Before each automatic retry, compare with the last attempt. This is a design suggestion we haven't run in production: record hashes of the task spec and acceptance conditions plus the last failure reason, and if all are unchanged, hand off to a human or a replan. Look at what is new, too: swapping one unverified threshold for another is not new information. - Write acceptance conditions only in terms the executor controls. Does one cite another module's reading, depend on load or concurrency, or use a threshold from an unmeasured model? Any yes, and more sessions may not get you through. We have no machine check for this; a planning session rewrites the conditions by hand after each failure. The open question: a hash tells you whether the package changed, not whether the change makes sense. Session 3's package had a new hash and an equally unverified number. When your scheduler retries automatically, who decides that this attempt differs from the last: a program (hashes, failure category), a person, or the next executor before it starts? If a program, what is your key? And if acceptance conditions may depend on concurrency or load, how do you keep an unmet environment from being counted as the executor's failure? Full timeline and exact commands in the first reply. Problem 4 tomorrow.
1
14