hello.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. """
  2. lambdagent Hello World
  3. 从最简单开始,逐步展示 11 个 Lambda 构造。
  4. 每一步都标注 Lambda 演算对应。
  5. 用法:
  6. export ANTHROPIC_API_KEY=sk-...
  7. python hello.py
  8. """
  9. import sys, os
  10. sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
  11. from lambdagent import (
  12. Lam, Tool, Compose, If, Loop, Pair, Fst, Snd,
  13. Route, Guard, Context, Dataset,
  14. )
  15. from lambdagent.extensions import Memory
  16. def main():
  17. ctx = Context()
  18. # ════════════════════════════════════════════
  19. # 1. Lam — λ 抽象
  20. # λx. LLM(x)
  21. # ════════════════════════════════════════════
  22. print("─── 1. Lam (λ abstraction) ───")
  23. hello = Lam(
  24. "hello",
  25. "You are a friendly assistant. Reply in one short sentence.",
  26. max_tokens=64,
  27. )
  28. print(f" λ> {hello('Hello!', ctx)}")
  29. print()
  30. # ════════════════════════════════════════════
  31. # 2. Tool — 原语 / Oracle
  32. # λx. f(x) where f is a Python function
  33. # ════════════════════════════════════════════
  34. print("─── 2. Tool (primitive) ───")
  35. shout = Tool("shout", lambda x: str(x).upper() + "!!!")
  36. print(f" λ> {shout('hello world', ctx)}")
  37. print()
  38. # ════════════════════════════════════════════
  39. # 3. Compose — 函数组合
  40. # f >> g = λx. g(f(x))
  41. # ════════════════════════════════════════════
  42. print("─── 3. Compose (f >> g) ───")
  43. pipeline = hello >> shout # 先让 LLM 回复,再全大写
  44. print(f" λ> {pipeline('Hi there', ctx)}")
  45. print()
  46. # ════════════════════════════════════════════
  47. # 4. Dataset → Lam — 数据集变函数
  48. # D.to_lam() = λx. LLM_{prompt=encode(D)}(x)
  49. # ════════════════════════════════════════════
  50. print("─── 4. Dataset → Lam ───")
  51. succ = Dataset(
  52. examples=[("0","1"), ("1","2"), ("2","3"), ("9","10")],
  53. description="Given n, output n+1. Output ONLY the number.",
  54. ).to_lam("SUCC")
  55. print(f" SUCC(41) = {succ('41', ctx)}")
  56. print(f" SUCC(99) = {succ('99', ctx)}")
  57. print()
  58. # ════════════════════════════════════════════
  59. # 5. Pair / Fst / Snd — Church 对
  60. # PAIR = λa.λb.λf. f a b
  61. # ════════════════════════════════════════════
  62. print("─── 5. Pair / Fst / Snd ───")
  63. both = Pair(hello, shout)
  64. result = both("Hey", ctx)
  65. print(f" Pair result: {result}")
  66. print(f" Fst: {Fst()('(a, b) tuple test: ' + str(result), ctx) if False else result[0]}")
  67. print(f" Snd: {result[1]}")
  68. print()
  69. # ════════════════════════════════════════════
  70. # 6. If — Church 条件
  71. # IF c t e = c t e
  72. # ════════════════════════════════════════════
  73. print("─── 6. If (Church boolean) ───")
  74. branch = If(
  75. cond=lambda x: int(x) > 10,
  76. then_=Tool("big", lambda x: f"{x} is BIG"),
  77. else_=Tool("small", lambda x: f"{x} is small"),
  78. )
  79. print(f" If(5 > 10): {branch('5', ctx)}")
  80. print(f" If(42 > 10): {branch('42', ctx)}")
  81. print()
  82. # ════════════════════════════════════════════
  83. # 7. Loop — Y 组合子
  84. # Y(λself.λx. if done then x else self(body(x)))
  85. # ════════════════════════════════════════════
  86. print("─── 7. Loop (Y combinator) ───")
  87. counter = Tool("inc", lambda x: str(int(x) + 1))
  88. loop = Loop(
  89. body=counter,
  90. condition=lambda result, step: int(result) >= 5,
  91. max_steps=20,
  92. )
  93. print(f" Y(inc)(0) until ≥5: {loop('0', ctx)}")
  94. print()
  95. # ════════════════════════════════════════════
  96. # 8. Route — 广义 Church 布尔 (CASE)
  97. # CASE classifier(x) [(l₁,a₁), (l₂,a₂), ...]
  98. # ════════════════════════════════════════════
  99. print("─── 8. Route (CASE) ───")
  100. classifier = Lam(
  101. "classify",
  102. "Classify the input as exactly one word: 'math' or 'greeting'. Output ONLY that word.",
  103. max_tokens=8,
  104. )
  105. router = Route(
  106. classifier=classifier,
  107. routes={
  108. "math": Tool("math_handler", lambda x: f"[MATH] {x}"),
  109. "greeting": Tool("greet_handler", lambda x: f"[GREET] Hello! {x}"),
  110. },
  111. default=Tool("default", lambda x: f"[DEFAULT] {x}"),
  112. )
  113. print(f" Route('2+2'): {router('2+2', ctx)}")
  114. print(f" Route('Hi!'): {router('Hi!', ctx)}")
  115. print()
  116. # ════════════════════════════════════════════
  117. # 9. Guard — 依赖类型 {x:T | P(x)}
  118. # if P(result) then result else retry
  119. # ════════════════════════════════════════════
  120. print("─── 9. Guard (dependent type) ───")
  121. strict_num = Guard(
  122. agent=succ,
  123. validator=lambda x: str(x).strip().isdigit(),
  124. retry=2,
  125. )
  126. print(f" Guard(SUCC(7)): {strict_num('7', ctx)}")
  127. print()
  128. # ════════════════════════════════════════════
  129. # 10. Memory — 环境扩展 Γ' = Γ ∪ store
  130. # ════════════════════════════════════════════
  131. print("─── 10. Memory (Γ extension) ───")
  132. greeter = Lam(
  133. "greeter",
  134. "Greet the user. If you know their name from memory, use it. One sentence.",
  135. max_tokens=64,
  136. )
  137. stateful = Memory(greeter, store={"user_name": "Alice", "mood": "happy"})
  138. print(f" Memory(greeter): {stateful('Hello!', ctx)}")
  139. print()
  140. # ════════════════════════════════════════════
  141. # 11. 组合: 完整 Agent pipeline
  142. # extract >> Pair(analyze, critique) >> synthesize >> Loop(refine)
  143. # ════════════════════════════════════════════
  144. print("─── 11. Full pipeline ───")
  145. extract = Lam("extract", "Extract the key claim from this text. One sentence.", max_tokens=64)
  146. analyze = Lam("analyze", "Is this claim true or false? One sentence.", max_tokens=64)
  147. combine = Tool("combine", lambda pair: f"Claim: {pair[0]}\nAnalysis: {pair[1]}")
  148. full = extract >> Pair(analyze, shout) >> combine
  149. result = full("The Earth orbits the Sun in approximately 365 days.", ctx)
  150. print(f" {result}")
  151. print()
  152. # ════════════════════════════════════════════
  153. # β-规约追踪
  154. # ════════════════════════════════════════════
  155. print("─── β-reduction trace ───")
  156. ctx.print_trace()
  157. print(f"\nTotal: {len(ctx.trace)} β-reductions")
  158. if __name__ == "__main__":
  159. main()