@rong/agentscript 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,11 +12,11 @@ main agent ResearchAgent {
12
12
  use input.question
13
13
 
14
14
  scratch = []
15
- use scratch.summary < 2k
15
+ use scratch.summary max 2k
16
16
 
17
17
  done = false
18
18
 
19
- loop until done < 4 {
19
+ loop until done max 4 {
20
20
  thought = reason(input.question, scratch)
21
21
  action = act(input.question, thought)
22
22
  observation = observe(action)
@@ -30,9 +30,9 @@ main agent ResearchAgent {
30
30
 
31
31
  func reason(question, scratch) {
32
32
  use question
33
- use scratch.summary < 1k
33
+ use scratch.summary max 1k
34
34
 
35
- generate({ input: "Choose the next search focus", limit: 300 }) -> {
35
+ generate({ input: "Choose the next search focus", max_output: 300 }) -> {
36
36
  focus string
37
37
  why string
38
38
  }
@@ -60,7 +60,7 @@ main agent ResearchAgent {
60
60
 
61
61
  use raw
62
62
 
63
- generate({ input: "Summarize the useful observation", limit: 400 }) -> {
63
+ generate({ input: "Summarize the useful observation", max_output: 400 }) -> {
64
64
  facts list[string]
65
65
  source string
66
66
  }
@@ -68,9 +68,9 @@ main agent ResearchAgent {
68
68
 
69
69
  func enough(question, scratch) {
70
70
  use question
71
- use scratch.summary < 1k
71
+ use scratch.summary max 1k
72
72
 
73
- verdict = generate({ input: "Decide whether the observations are enough", limit: 200 }) -> {
73
+ verdict = generate({ input: "Decide whether the observations are enough", max_output: 200 }) -> {
74
74
  done boolean
75
75
  }
76
76
 
@@ -79,9 +79,9 @@ main agent ResearchAgent {
79
79
 
80
80
  func answer(question, scratch) {
81
81
  use question
82
- use scratch.summary < 2k
82
+ use scratch.summary max 2k
83
83
 
84
- generate({ input: "Answer using only the observations", limit: 800 }) -> {
84
+ generate({ input: "Answer using only the observations", max_output: 800 }) -> {
85
85
  ok boolean
86
86
  text string
87
87
  error string
@@ -10,13 +10,13 @@ main agent SelfImprover {
10
10
  goal string
11
11
  }) {
12
12
  past = Lessons.query({
13
- kind: "lesson"
14
- text: input.goal
13
+ kind: "lesson",
14
+ text: input.goal,
15
15
  limit: 5
16
16
  })
17
17
 
18
18
  use input.goal
19
- use past < 2k
19
+ use past max 2k
20
20
 
21
21
  result = generate({
22
22
  input: "Answer the goal using any relevant lessons.",
@@ -28,15 +28,15 @@ main agent SelfImprover {
28
28
  }
29
29
 
30
30
  lesson = reflect({
31
- goal: input.goal
32
- result: result
31
+ goal: input.goal,
32
+ result: result,
33
33
  past: past
34
34
  })
35
35
 
36
36
  Lessons.add({
37
- kind: "lesson"
38
- text: lesson.insight
39
- goal: input.goal
37
+ kind: "lesson",
38
+ text: lesson.insight,
39
+ goal: input.goal,
40
40
  ok: result.ok
41
41
  })
42
42
 
@@ -1,492 +0,0 @@
1
- # AgentScript Role / Label 设计
2
-
3
- 本文档定义 AgentScript 中 `agent role`、`context label` 和底层 provider message role 的分层设计,用于指导当前 prompt 构造、`use ... as ...` 语法和 trace 展示的实现。
4
-
5
- ## 1. 核心结论
6
-
7
- AgentScript 应明确区分三类概念:
8
-
9
- ```text
10
- agent role 表示“谁在生成 / 谁在发言”。
11
- context label 表示“这段上下文在当前 prompt 中的用途”。
12
- provider role 表示底层 LLM API message 的 system/user/assistant/tool。
13
- ```
14
-
15
- 这三者属于不同层级,不能混用。
16
-
17
- - `agent role` 是 AgentScript 层的生成身份。
18
- - `context label` 是 prompt 内部的上下文组织标签。
19
- - `provider role` 是 OpenAI / Anthropic / Ollama 等 adapter 的传输协议细节。
20
-
21
- 用户不应通过 `use ... as system` 之类的写法直接操纵底层 provider role。
22
-
23
- ## 2. Agent Role
24
-
25
- `role` 是 agent 的身份声明:
26
-
27
- ```agentscript
28
- agent ResearchAgent {
29
- model Qwen
30
- role "Senior Researcher"
31
- description "Answer questions with search and structured reasoning."
32
- }
33
- ```
34
-
35
- 它的含义是:
36
-
37
- ```text
38
- 当前 agent 以什么身份进行 generate。
39
- ```
40
-
41
- 每次 `generate` 都应把当前 agent 的 `role` 和 `description` 放入 identity 层 prompt。例如:
42
-
43
- ```text
44
- You are a Senior Researcher.
45
- Answer questions with search and structured reasoning.
46
- ```
47
-
48
- 因此当前实现目标是:
49
-
50
- ```text
51
- agent.role -> generation identity
52
- agent.description -> generation identity
53
- ```
54
-
55
- 在 multi-agent 场景中,agent 输出被其他 agent 使用时,`role` 也可以作为 speaker provenance 展示:
56
-
57
- ```text
58
- [plan]
59
- Produced by: Planner
60
- Role: Planner
61
- Output:
62
- ...
63
- ```
64
-
65
- 这里的 `Role: Planner` 仍然是 AgentScript 层的 agent role,不是 provider message role。
66
-
67
- ## 3. Context Label
68
-
69
- Context label 是 `use` 注入上下文时的语义标签。
70
-
71
- 当前语法支持:
72
-
73
- ```agentscript
74
- use expr
75
- use expr < budget
76
- use expr as label
77
- use expr < budget as label
78
- ```
79
-
80
- 固定顺序是:
81
-
82
- ```text
83
- 选择什么 -> 限制多少 -> 作为何种上下文
84
- ```
85
-
86
- 例如:
87
-
88
- ```agentscript
89
- use input.question as user
90
- use scratch.summary < 2k as memory
91
- use docs.summary < 4k as evidence
92
- use search_result as observation
93
- use policy as constraint
94
- ```
95
-
96
- `context label` 的含义是:
97
-
98
- ```text
99
- 这段内容在当前 generate prompt 中作为何种材料被呈现。
100
- ```
101
-
102
- 它只影响:
103
-
104
- - prompt section label
105
- - trace display
106
- - context organization
107
- - debug / audit readability
108
-
109
- 它不改变:
110
-
111
- - agent identity
112
- - provider message role
113
- - tool 权限
114
- - system / user / assistant 权限
115
-
116
- ## 4. Provider Role
117
-
118
- Provider role 是底层 LLM API 的 message role,例如:
119
-
120
- ```text
121
- system
122
- user
123
- assistant
124
- tool
125
- ```
126
-
127
- 它属于 provider adapter 的实现细节。
128
-
129
- 默认映射:
130
-
131
- ```text
132
- system = 当前 agent identity + runtime rules
133
- user = generate instruction + selected context + output shape
134
- ```
135
-
136
- 也就是说,AgentScript 的 context label 应作为 prompt 内部结构渲染,而不是映射为多条 provider message role。
137
-
138
- Runtime 不把 memory、evidence、observation 等材料伪装成 assistant message:
139
-
140
- ```text
141
- assistant: [memory] ...
142
- assistant: [evidence] ...
143
- ```
144
-
145
- 原因是 `assistant` 在 chat protocol 中表示模型真实历史输出,而 memory / evidence / observation 是外部材料。
146
-
147
- ## 5. Prompt 构造模型
148
-
149
- 一次 `generate` 的 prompt 分为四层。
150
-
151
- ### 5.1 Agent Identity
152
-
153
- 来自当前 agent 的配置:
154
-
155
- ```agentscript
156
- role "Senior Researcher"
157
- description "Answer questions with search and structured reasoning."
158
- ```
159
-
160
- 渲染为 provider `system` message 的一部分:
161
-
162
- ```text
163
- You are a Senior Researcher.
164
- Answer questions with search and structured reasoning.
165
- ```
166
-
167
- ### 5.2 Generate Instruction
168
-
169
- 来自 `generate(...)` 的 `input` 字段:
170
-
171
- ```agentscript
172
- generate({
173
- input: "Answer using only the selected context"
174
- }) -> {
175
- ok boolean
176
- answer string
177
- }
178
- ```
179
-
180
- 渲染为:
181
-
182
- ```text
183
- Instruction:
184
- Answer using only the selected context.
185
- ```
186
-
187
- ### 5.3 Selected Context
188
-
189
- 来自当前 scope 和父 scope 中可见的 `use` 声明:
190
-
191
- ```agentscript
192
- use input.question as user
193
- use scratch.summary < 2k as memory
194
- use docs.summary < 4k as evidence
195
- ```
196
-
197
- 渲染为:
198
-
199
- ```text
200
- Context:
201
-
202
- [user]
203
- ...
204
-
205
- [memory]
206
- ...
207
-
208
- [evidence]
209
- ...
210
- ```
211
-
212
- 如果没有 label,可以使用 source expression 作为默认 label 或显示为普通 context item。
213
-
214
- ### 5.4 Output Shape
215
-
216
- 来自 `generate(...) -> shape`:
217
-
218
- ```agentscript
219
- generate({ input: "Answer" }) -> {
220
- ok boolean
221
- answer string
222
- }
223
- ```
224
-
225
- 渲染为:
226
-
227
- ```text
228
- Required output shape:
229
- {
230
- ok: boolean
231
- answer: string
232
- }
233
- ```
234
-
235
- 当 `generate` 没有 `-> shape` 时,不应注入输出 schema,也不应要求 provider 结构化输出。
236
-
237
- ## 6. `use ... as label` 规则
238
-
239
- ### 6.1 Label 类型
240
-
241
- `as` 后面的 label 是语法层面的字面标签,不是表达式,不参与变量解析,也不会求值。
242
-
243
- ```agentscript
244
- use docs as evidence
245
- use scratch as memory
246
- use docs.summary < 4k as retrieved-evidence
247
- ```
248
-
249
- 其中:
250
-
251
- ```text
252
- evidence
253
- memory
254
- retrieved-evidence
255
- ```
256
-
257
- 都是 context label 的字面值。即使当前作用域中存在名为 `evidence` 或 `memory` 的变量,`as evidence` 和 `as memory` 也不会读取这些变量。
258
-
259
- Label 不需要双引号。它不是字符串表达式,而是 `use` 语句的一部分:
260
-
261
- ```agentscript
262
- use docs as retrieved evidence
263
- ```
264
-
265
- 上例中的 label 是字面标签 `retrieved evidence`。Parser 应把 `as` 之后到语句结束之间的内容作为 label 文本;如果存在预算,则 label 位于预算之后:
266
-
267
- ```agentscript
268
- use docs.summary < 4k as retrieved evidence
269
- ```
270
-
271
- Label 文本应在 AST 中保存为普通字符串,例如:
272
-
273
- ```json
274
- {
275
- "label": "retrieved evidence"
276
- }
277
- ```
278
-
279
- Label 不支持嵌套表达式、函数调用、字段访问或插值:
280
-
281
- ```agentscript
282
- use docs as label_name -- label 是 "label_name",不是变量 label_name 的值
283
- use docs as input.label -- label 是 "input.label",不是字段访问结果
284
- use docs as label() -- label 是 "label()",不会调用函数
285
- ```
286
-
287
- ### 6.2 保留 label
288
-
289
- 为避免和 provider role 混淆,以下 label 保留,不作为普通 context label 使用:
290
-
291
- ```text
292
- system
293
- assistant
294
- tool
295
- developer
296
- ```
297
-
298
- `user` 允许作为 context label,但它只是 context label,不是 provider role:
299
-
300
- ```agentscript
301
- use input.question as user
302
- ```
303
-
304
- 这里的 `user` 表示“这段上下文是用户输入”,不是把该 context item 变成 provider `user` message。
305
-
306
- ### 6.3 继承规则
307
-
308
- `use` 声明原本可被 child scope 继承。加入 label 后,label 应随 use declaration 一起继承。
309
-
310
- ```agentscript
311
- use input.question as user
312
-
313
- func answer() {
314
- generate({ input: "Answer" }) -> {
315
- answer string
316
- }
317
- }
318
- ```
319
-
320
- `answer()` 内部的 `generate` 仍可看到:
321
-
322
- ```text
323
- [user]
324
- input.question
325
- ```
326
-
327
- ### 6.4 重复 label
328
-
329
- 允许多个 context source 使用同一个 label:
330
-
331
- ```agentscript
332
- use docs1 as evidence
333
- use docs2 as evidence
334
- ```
335
-
336
- 重复 label 按声明顺序分别渲染:
337
-
338
- ```text
339
- [evidence]
340
- docs1...
341
-
342
- [evidence]
343
- docs2...
344
- ```
345
-
346
- ## 7. Multi-Agent Provenance
347
-
348
- Agent 调用结果应在 trace 或内部 metadata 中保留 provenance:
349
-
350
- ```json
351
- {
352
- "agent": "Planner",
353
- "role": "Planner",
354
- "function": "main",
355
- "trace_id": "..."
356
- }
357
- ```
358
-
359
- 这类 metadata 不一定暴露给用户代码,但应可用于 trace 和 context renderer。
360
-
361
- 用法:
362
-
363
- ```agentscript
364
- plan = Planner(input)
365
- critique = Critic(plan)
366
-
367
- use plan.summary < 2k as plan
368
- use critique.summary < 2k as critique
369
- ```
370
-
371
- 渲染时可以结合 provenance:
372
-
373
- ```text
374
- [plan]
375
- Produced by: Planner
376
- Role: Planner
377
- Output:
378
- ...
379
-
380
- [critique]
381
- Produced by: Critic
382
- Role: Skeptical Reviewer
383
- Output:
384
- ...
385
- ```
386
-
387
- 这样能表达 multi-agent 中“不同角色发言”的感觉,同时不污染 provider message role。
388
-
389
- ## 8. Trace 展示
390
-
391
- Trace 同时显示 agent identity、instruction、context label、source expression 和 budget。
392
-
393
- ```text
394
- Generate #1
395
- Agent:
396
- name: ResearchAgent
397
- role: Senior Researcher
398
-
399
- Instruction:
400
- Answer using only the selected context.
401
-
402
- Selected context:
403
- [user]
404
- source: input.question
405
- budget: none
406
-
407
- [memory]
408
- source: scratch.summary
409
- budget: 2k
410
-
411
- [evidence]
412
- source: docs.summary
413
- budget: 4k
414
-
415
- Output shape:
416
- ok boolean
417
- answer string
418
- ```
419
-
420
- Multi-agent trace 可以显示:
421
-
422
- ```text
423
- Agent call:
424
- Planner.main
425
- role: Planner
426
-
427
- Agent call:
428
- Critic.main
429
- role: Skeptical Reviewer
430
-
431
- Generate #3
432
- Agent:
433
- Coordinator
434
- role: Coordinator
435
-
436
- Selected context:
437
- [plan]
438
- produced_by: Planner
439
- producer_role: Planner
440
-
441
- [critique]
442
- produced_by: Critic
443
- producer_role: Skeptical Reviewer
444
- ```
445
-
446
- ## 9. 当前实现方案
447
-
448
- 当前实现包括:
449
-
450
- 1. `role` 和 `description` 进入每次 `generate` 的 system / identity prompt。
451
- 2. `UseStmt` 增加可选 `label` 字段,保存 label 字面文本。
452
- 3. Parser 支持 `use expr as label` 和 `use expr < budget as label`。
453
- 4. Parser 将 `as` 后面的 label 保存为原始标签文本,不按表达式解析。
454
- 5. Semantic analyzer 校验保留 label,避免和 provider role 混淆。
455
- 6. Context builder 在 trace 和 prompt renderer 中使用 label。
456
- 7. Agent call trace 保留 agent name、role、function 等 provenance。
457
-
458
- 当前设计保持执行和上下文注入分离:
459
-
460
- ```agentscript
461
- critique = Critic(draft)
462
- use critique as critique
463
- ```
464
-
465
- ## 10. 术语表
466
-
467
- ```text
468
- provider role:
469
- 底层 chat message role,例如 system/user/assistant/tool。
470
-
471
- agent role:
472
- agent 生成输出时使用的身份,也可作为 agent 输出的 speaker provenance。
473
-
474
- context label:
475
- 通过 use ... as ... 附加到 selected context 的用途标签。
476
-
477
- speaker provenance:
478
- agent 调用产物携带的来源元信息,包括 agent name、role、function 和 trace id。
479
-
480
- agent transcript:
481
- 在 prompt 或 trace 中按 agent 来源组织的多 agent 输出展示形式。
482
- ```
483
-
484
- ## 11. 一句话总结
485
-
486
- ```text
487
- provider role 是消息协议;
488
- agent role 是生成身份和发言者身份;
489
- context label 是上下文用途标签。
490
- ```
491
-
492
- AgentScript 应在语言层构造 labeled context 和 agent transcript,再由 runtime 映射到底层 provider messages。