From Prompt to Policy 从一次提问开始,和 Klara 一起构造一个逐步成长的 Artificial Friend。
中文 | English
Klara 首页:v0.2 中,一个问题可以进入 Klara 的本地知识系统。
Run Margin:v0.2 的公开运行链路,包含 intent router、RAG retrieval、writer、latency 与 token。
Klara 的名字来自石黑一雄的小说《克拉拉与太阳》。
Klara 是一位 Artificial Friend。她温暖、安静、敏锐,总是在观察世界,试着理解人类的语言、情绪、关系和愿望。她并不是一开始就理解一切,而是在不断观察、陪伴和学习中,慢慢看清世界的形状。
在这个项目里,我们会和 Klara 一起成长。
最开始,她只是一个只能完成单次问答的 Artificial Friend。你问一个问题,她的大脑,也就是 LLM,会直接生成一个回答。
但这只是第一步。
之后,我们会一步步为她增加新的能力:让她能够调用工具,检索你提供的知识库,理解你的意图,记住上下文,搜索网页,综合证据,评估自己的回答,并最终通过运行轨迹和反馈不断改进。
我们关心的不只是 Klara 最后说了什么,也关心她是如何观察问题、如何选择行动、如何形成回答的。
当你输入一个问题时,就像有一束光进入 Klara 的视野。她开始观察这束光里包含的信息:
你的问题是什么?
你的意图在哪里?
应该直接回答吗?
需要检索资料吗?
需要调用工具吗?
证据是否足够?
回答是否可以被验证?
她在运行中的每一步,都会留下可观察的痕迹:
她创建了什么状态?
她调用了什么模型?
她是否使用了工具?
每一步花了多长时间?
消耗了多少 token?
是否保存了 trace?
是否可以被评估和改进?
这些 token 可以被理解为她的“太阳能源”。
因此,Klara: Agent Ladder 不是一个一次性的 demo,而是一条成长路径。我们会从最小的一次 LLM Call 开始,逐步构造出一个可以被观察、被测试、被扩展、被评估、被优化的 Artificial Friend。
跟着 Klara,我们不仅是在做一个 Agent。
我们也在理解 GPT、Claude 和其他 AI 系统背后的运行方式:
它们如何接收问题?
如何理解意图?
如何选择行动?
如何调用工具?
如何组织证据?
如何形成答案?
如何判断自己是否可靠?
如何从反馈中继续进化?
更具体地说,Agent Ladder 会逐步回答这些问题:
| 问题 | 我们会在 Klara 身上看到什么 |
|---|---|
| 什么是 Agent Loop? | Klara 如何从观察问题,到行动、观察结果、更新状态、生成回答 |
| 什么是 Harness? | Klara 的运行框架如何控制上下文、工具、状态、预算、重试和权限 |
| 什么是 State? | Klara 如何把一次运行拆成 AskState、AnswerState、RunLog、EvidencePack 等结构 |
| 什么是 Trace? | Klara 的每一步如何被记录,方便观察、复盘、测试和优化 |
| 什么是 AnswerFrame? | Klara 的答案如何从一段文本,成长为带来源、证据、claim 和 citation 的结构化回答 |
| 什么是 Tool Use? | Klara 如何通过 ToolRegistry / MCP 调用外部工具,并留下审计记录 |
| 什么是 Eval / Judge? | 我们如何判断 Klara 的 route、retrieval、evidence、citation、answer 是否可靠 |
| 什么是 Policy? | Klara 如何决定什么时候 direct answer、什么时候 RAG、什么时候 research、什么时候调用工具 |
| 什么是 RL for Agent? | Klara 如何从 trace、eval、reward 和 trajectory 中改进自己的行为策略 |
所以,一个 Agent 并不只是一个 LLM。
更准确地说:
Agent = Model + Harness + State + Tools + Memory + Trace + Eval + Policy
其中:
| 组成 | 作用 |
|---|---|
| Model | 负责生成、判断、推理和表达 |
| Harness | 控制运行过程:上下文、工具、状态、预算、重试、权限 |
| State | 记录当前任务处于哪个阶段 |
| Tools | 让 Klara 能行动,而不只是说话 |
| Memory | 让 Klara 能理解上下文和追问 |
| Trace | 让每一步都可以被观察 |
| Eval / Judge | 判断她哪里做得好,哪里做得不好 |
| Policy | 决定她下一次遇到类似问题时,应该选择哪条路径 |
Agent Ladder 的每一层,都在回答三个问题:
Klara 现在多理解了什么?
Klara 现在能多做什么?
Klara 的运行现在多可观察、多可验证、多鲁棒?
如果你想设计自己的 Agent,或者只是想理解一个 Agent 到底如何行动,Klara 会陪着你走一条安静而清晰的学习路径。
当前最新分支:
v0.2-rag-agent
当前主题:
RAG Agent: Klara's Sun Library
只需要切换到这个 branch,就可以看到当前阶段的 Klara 形态:
git checkout v0.2-rag-agent现在的 Klara 已经从第一章的单次 LLM Call,成长为一个可以读取本地知识库的 RAG Agent。
她不再只依靠模型参数回答项目问题,而是可以先检索自己的小书房 Klara's Sun Library,再把相关 evidence 交给 writer 生成回答:
用户提问
→ Intent Router 判断是否需要 RAG
→ Local Knowledge Index 召回相关 chunk
→ Dense Retrieval + BM25 形成候选
→ Hybrid Retrieval 融合排序
→ Reranking 选择更适合回答的 evidence
→ Context Builder 组织给 writer 的上下文
→ Klara Writer 生成 grounded answer
→ AnswerFrameV1 保存 question / answer / evidence
→ Run Chain 展示每一步公开运行信息
这一章的核心不是做复杂 Agentic RAG,而是让 Klara 拥有第一条标准、可复用、可观察的 RAG 主线。
你可以理解这些核心概念:
| 概念 | Klara 学会了什么 |
|---|---|
Document |
把 markdown 和 metadata 读成标准资料对象 |
TextChunk |
把长文档切成适合检索的小块 |
IndexRecord |
把 chunk 转成可进入索引层的记录 |
Embedding |
把文本变成可计算相似度的 dense vector |
BM25 |
用关键词和词频补足向量检索的盲区 |
Hybrid Retrieval |
合并 dense / sparse 两路召回结果 |
Reranking |
从候选 chunk 中选出最适合进入上下文的 evidence |
SourceCard / Citation |
为后续引用和溯源保留结构 |
AnswerFrameV1 |
把最终问题、回答和 evidence 保存为结构化答案 |
Run Chain |
在右侧卡片中展示每个模块的公开输入、输出、耗时和 token |
这一阶段完成后,你应该能理解:
一个 Agent 如何从“直接回答”,成长为“先检索证据,再基于证据回答”。
这就是 Klara 的第二步。
她还不会复杂查询改写、检索规划、证据验证和不足证据 fallback。
这些会放到下一章:v0.3-agentic-rag。
Klara 不会一下子变成完整强大的 Research Agent。
她会沿着 Agent Ladder,一层一层长大。
这条路线不是简单地“增加功能”,而是让 Klara 逐渐获得一个 Agent 所需要的完整能力:
感知问题
→ 理解意图
→ 选择路径
→ 调用模型或工具
→ 观察结果
→ 更新状态
→ 组织证据
→ 生成回答
→ 验证回答
→ 记录 trace
→ 接受评估
→ 根据反馈改进策略
下面是 Klara 的成长总览:
| 阶段 | Branch | Klara 的新能力 | 新增核心概念 | 可观察性 / 鲁棒性增长 |
|---|---|---|---|---|
| v0.1 | v0.1-minimal-agent |
完成一次 LLM Call,并保存 trace | AskState, AnswerState, RunLog, MinimalAgent, LLMClient, JSONL Trace |
每次回答都有 run_id、latency、model、error、trace |
| v0.2 | v0.2-rag-agent |
从本地知识中检索答案 | Document, Chunk, Embedding, Retriever, SourceCard, Citation, RetrievalRecord, AnswerFrameV1 |
回答开始有来源、有引用、有 direct / rag 区分 |
| v0.3 | v0.3-agentic-rag |
围绕证据进行计划、读取和验证 | RouteState, SubQuestion, RetrievalPlan, EvidenceItem, EvidencePack, Verifier, WorkflowState, AnswerFrameV2 |
writer 不直接吃 raw chunks;claim 可以绑定 evidence;证据不足可返回 insufficient_info |
| v0.4 | v0.4-memory-agent |
理解上下文、追问和上一轮来源 | MemoryContext, LastAnswerMemory, SelectedSourceMemory, ResolvedReference, LongTermMemoryItem, Memory Write Policy |
能解析“刚才那篇”“第二个来源”;记忆写入有策略,不乱记 |
| v0.5 | v0.5-research-agent |
进行本地 + 联网 research | ResearchPlan, SearchQuery, WebSourceCard, WebEvidenceItem, EvidenceTable, SourceQuality, ResearchReport, AnswerFrameV4 |
能比较来源、标记冲突、说明限制和不确定性 |
| v0.6 | v0.6-mcp-tool-agent |
通过工具协议行动 | ToolRegistry, MCPToolSpec, MCPToolCall, PermissionCheck, AuditLog, Tool Adapter |
工具调用有 schema、有权限、有审计、有失败记录 |
| v0.7 | v0.7-production-agent |
从 demo 变成可靠运行系统 | ExecutionContext, BudgetState, JobState, RetryPolicy, RateLimitState, Streaming, Cancellation |
支持超时、重试、取消、预算、成本、并发和可观测性 |
| v0.8 | v0.8-eval-data-flywheel |
系统性评估自己的行为 | EvalCase, EvalRecord, MetricResult, RuleJudge, LLMJudge, FailureTaxonomy, TraceDatasetItem, AnswerFrameV5 |
能判断 route、retrieval、evidence、citation、answer、safety、cost 是否合格 |
| v0.9 | v0.9-rl-for-agent |
从 trace 和 reward 中改进 policy | PolicyDecision, RewardRecord, Trajectory, PolicyDataset, OptimizationRun, GRPO, PPO, DPO-style Optimization, Bandit Optimization |
从 trace → eval → reward → policy update,逐步优化路由、检索、工具选择和回答策略 |
Branch:
v0.1-minimal-agent
最开始,Klara 只会做一件事:回答一个问题。
用户输入一个问题,Klara 调用一次 LLM,生成一个回答。
这看起来只是最普通的 LLM Call,但我们不会把它写成一个随手的 demo。
在这一层,我们会引入最基础的运行结构:
AskState
→ MinimalAgent
→ LLMClient
→ AnswerState
→ RunLog
→ JSONL Trace
此时 Klara 的 Agent Loop 还非常短:
Ask
→ Answer
→ Trace
但这已经足够重要。
因为从第一步开始,我们就让 Klara 的回答变成一个可以观察的 run。
她会记录:
ask_id
run_id
question
answer
model
latency_ms
prompt_tokens
completion_tokens
error
created_at
trace_saved
这一层的核心不是复杂,而是建立习惯:
每一次回答,都应该留下 trace。
在 v0.1 中,Klara 还没有正式的 AnswerFrame。
她只有最简单的 AnswerState。
这是刻意的。
因为第一章的重点是让学习者看清:
一次用户提问如何变成一次 LLM call?
一次 LLM call 如何变成一个 answer?
一次 answer 如何变成可复盘的 run?
这一层之后,Klara 还不会检索,也不会记忆。
但她已经开始拥有一个最小的大脑,并且开始留下自己的第一批运行轨迹。
Branch:
v0.2-rag-agent
当 Klara 只依赖模型参数时,她只能回答模型已经“知道”的内容。
但用户经常会问:
根据这个文档,结论是什么?
这个项目里的设计原则是什么?
这篇论文支持什么 claim?
所以在第二层,我们让 Klara 学会读取外部知识。
她会获得这些结构:
Document
Chunk
Embedding
Vector Index
Retriever
RetrievalRecord
SourceCard
Citation
AnswerFrameV1
此时 Klara 的 loop 变成:
Ask
→ Decide direct or rag
→ Retrieve
→ Build SourceCards
→ Write Answer
→ Add Citations
→ Trace
这里开始正式引入 AnswerFrameV1:
answer_type
final_text
sources
citations
这非常关键。
因为 Klara 的回答不再只是一段文本,而是一个带结构的回答对象。
她需要区分:
这是 direct answer 还是 rag answer?
用了哪些来源?
引用指向哪些 source?
哪些内容是基于检索材料生成的?
这一层让 Klara 更可靠。
因为她不再只靠“记忆”说话,而是开始基于资料说话。
Branch:
v0.3-agentic-rag
普通 RAG 很容易变成:
检索几个 chunk
→ 全部塞给模型
→ 让模型回答
但这不够鲁棒。
Klara 需要学会判断问题结构、规划检索、读取证据、验证回答。
所以第三层会引入 Agentic RAG:
RouteState
SubQuestion
RetrievalPlan
Query Rewriter
Retrieval Grader
EvidenceItem
EvidencePack
Verifier
WorkflowState
AnswerFrameV2
此时 Klara 的 Agent Loop 变成:
Understand
→ Route
→ Split Questions
→ Plan Retrieval
→ Retrieve
→ Grade Retrieval
→ Rewrite Query if needed
→ Read Evidence
→ Build EvidencePack
→ Write Answer
→ Verify Claims
→ Trace
这一层最重要的原则是:
Writer 不直接吃 raw chunks。
Writer 只看 EvidencePack。
也就是说,我们先把检索材料整理成证据结构,再让 Klara 基于证据回答。
AnswerFrameV2 会开始支持:
answer_type: direct / rag / mixed / insufficient_info
sub_questions
sections
claims
sources
evidence_items
citations
final_text
Klara 从这一层开始,不只是“找到资料”,而是学会:
证据够不够?
证据是否冲突?
哪个 claim 被哪个 evidence 支持?
如果证据不足,是否应该返回 insufficient_info?
这会让她明显更鲁棒。
Branch:
v0.4-memory-agent
一个只看当前问题的 Agent,很难成为真正的 Artificial Friend。
用户不会每一次都完整复述上下文。
他们会说:
刚才那篇呢?
第二个来源具体怎么做的?
你刚刚说的那个证据可靠吗?
所以 Klara 需要 memory。
但这里的 memory 不是简单地把 message history 全塞回 prompt。
这一层会引入:
MemoryContext
ConversationSummary
LastAnswerMemory
SelectedSourceMemory
ResolvedReference
LongTermMemoryItem
Memory Write Policy
AnswerFrameV3
此时 Klara 的 loop 变成:
Ask
→ Load MemoryContext
→ Resolve Follow-up Reference
→ Retrieve Selected / Previous Sources
→ Answer
→ Update LastAnswerMemory
→ Maybe Write Long-term Memory
→ Trace
这一层最关键的原则是:
Message history 不是 memory。
Memory 是经过选择、解析和约束的上下文结构。
Klara 会学会理解:
“第二篇”指哪篇?
“刚才那个证据”指哪个 evidence?
用户当前问题和上一轮 answer frame 有什么关系?
哪些东西应该被记住?
哪些东西不应该乱写入长期记忆?
从这一层开始,Klara 不只是一次性回答问题。
她开始能陪着用户继续往下走。
Branch:
v0.5-research-agent
本地知识库并不总是足够。
当问题需要最新资料、跨来源比较、研究性综合时,Klara 需要进入 research mode。
这一层会引入:
ResearchPlan
SearchQuery
Web Search
Browser Fetch
WebReader
WebSourceCard
WebEvidenceItem
EvidenceTable
SourceQuality
Cross-check
ResearchReport
AnswerFrameV4
此时 Klara 的 loop 变成:
Ask
→ Route to Research
→ Build ResearchPlan
→ Local RAG Search
→ Web Search
→ Fetch Pages
→ Read Sources
→ Extract Evidence
→ Build Evidence Table
→ Cross-check
→ Synthesize Report
→ Verify
→ Trace
这时 Klara 会开始说明:
哪些来源质量更高?
哪些来源互相支持?
哪些来源存在冲突?
哪些结论还不确定?
当前研究有什么限制?
AnswerFrameV4 会支持:
evidence_table
source_quality_notes
conflicts
limitations
uncertainty_notes
这一层之后,Klara 不只是回答一个问题。
她开始帮助用户理解一个问题背后的证据地形。
Branch:
v0.6-mcp-tool-agent
一个 Agent 不应该只会生成文字。
Klara 还需要能够调用工具,访问外部资源,执行受控动作。
这一层会引入:
ToolRegistry
MCPToolSpec
MCPToolCall
MCP Client
MCP Server
Tool Adapter
PermissionCheck
AuditLog
此时 Klara 的 loop 变成:
Understand Task
→ Decide Tool
→ Check Permission
→ Call Tool
→ Receive Observation
→ Update State
→ Continue or Answer
→ Audit
→ Trace
这里最重要的是 harness 控制。
Klara 不能随便调用工具。
工具必须有:
name
description
input_schema
output_schema
permission policy
audit log
failure handling
这一层的原则是:
Agent 的行动必须可控。
工具调用必须可审计。
从这里开始,Klara 不只是“会说”,也开始“会做”。
但她做的每一步,都必须被 harness 约束,并被 trace 记录。
Branch:
v0.7-production-agent
一个 demo 可以只跑通一次。
但真正可用的 Agent 需要面对真实环境:
模型调用失败怎么办?
工具超时怎么办?
用户想取消怎么办?
多个请求同时发生怎么办?
token 预算超了怎么办?
成本怎么记录?
streaming 中断怎么办?
这一层会引入 production runtime:
ExecutionContext
BudgetState
JobState
RetryPolicy
RateLimitState
Async Runtime
Streaming
Timeout
Cancellation
Queue
Cache
Cost Tracking
Observability
此时 Klara 的 loop 不再只是“生成回答”,而是一个可靠运行系统:
Receive Request
→ Create Job
→ Apply Budget
→ Stream Output
→ Retry on Recoverable Failure
→ Timeout if Needed
→ Allow Cancellation
→ Track Cost
→ Save Logs and Trace
→ Return Final State
这一层让 Klara 更鲁棒。
因为真实世界里,失败不是异常,而是常态。
Klara 必须知道:
什么时候重试?
什么时候停止?
什么时候降级?
什么时候报告错误?
什么时候保存 partial output?
从这里开始,Klara 不再只是教学 demo。
她开始具备真实运行系统的雏形。
Branch:
v0.8-eval-data-flywheel
如果没有评估,我们就不知道 Klara 是否真的变好了。
这一层会引入 eval harness:
EvalCase
EvalRunner
MetricResult
EvalRecord
Rule Judge
LLM Judge
Route Metrics
Retrieval Metrics
Evidence Metrics
Citation Metrics
Answer Metrics
Safety Metrics
Cost Metrics
Failure Taxonomy
TraceDatasetItem
AnswerFrameV5
此时 Klara 的 loop 外面会多一层 evaluation loop:
EvalCase
→ Run Klara
→ Collect Trace
→ Apply Metrics
→ Judge Output
→ Classify Failure
→ Save EvalRecord
→ Build Trace Dataset
我们会评估的不只是最终答案,而是整个 Agent Loop:
Route 是否正确?
Retriever 是否找到了正确 source?
EvidenceReader 是否抽取了正确 evidence?
Writer 是否忠实于 EvidencePack?
Citation 是否真的支持 claim?
Tool 是否选对?
Answer 是否满足用户问题?
Safety 是否越界?
Latency / Cost 是否可接受?
这一层的核心是 failure taxonomy。
也就是说,我们不只是说:
这个回答不好。
而是要知道它为什么不好:
route_error
retrieval_miss
weak_evidence
unsupported_claim
citation_mismatch
hallucination
tool_error
memory_resolution_error
format_error
safety_violation
latency_too_high
cost_too_high
从这一层开始,Klara 的失败会变成数据。
而数据会成为下一层改进的燃料。
Branch:
v0.9-rl-for-agent
到了最后一层,Klara 已经有了完整链路:
输入
→ 理解
→ 路由
→ 检索
→ 证据整理
→ 工具调用
→ 回答生成
→ 验证
→ 运行记录
→ 自动评估
→ 失败分类
这时,我们才开始谈真正的 policy optimization。
这一层会引入:
PolicyDecision
RewardRecord
Trajectory
PolicyDataset
OptimizationRun
Prompt Optimization
Router Policy
Tool Selection Policy
Retrieval Parameter Optimization
Offline Policy Evaluation
Bandit Optimization
PPO
GRPO
DPO-style Optimization
Rollback
此时 Klara 的 improvement loop 是:
Trace
→ EvalRecord
→ Failure Taxonomy
→ RewardRecord
→ Trajectory
→ PolicyDataset
→ OptimizationRun
→ New Policy
→ Offline Evaluation
→ Rollback or Promote
这里的重点不是一上来训练一个大模型。
更现实的路线是先优化 Agent 的可控决策:
什么时候 direct answer?
什么时候 RAG?
什么时候 agentic_rag?
什么时候 research?
retrieval top_k 应该是多少?
query rewrite 要不要开?
web search 要不要开?
是否需要 full verifier?
是否使用 compact answer 还是 research report?
调用哪个 tool?
什么时候停止搜索?
这些决策会被记录成 PolicyDecision。
一次完整运行会变成 Trajectory。
评估结果会变成 RewardRecord。
然后我们可以使用不同方式优化 Klara:
Prompt Optimization
Bandit Optimization
Router Training
Tool Policy Optimization
Retrieval Parameter Search
PPO / GRPO / DPO-style Optimization
Offline Policy Evaluation
其中,GRPO / PPO 这类方法可以用于更高级的策略优化;而在实际工程中,我们会先从更可控的方式开始,比如 prompt version 对比、router policy 调整、top_k 搜索、tool selection policy 和 offline eval。
这一层的核心是:
从 trace 到 eval,
从 eval 到 reward,
从 reward 到 policy。
这就是:
From Prompt to Policy
Klara 不只是回答更多问题。
她开始从自己的运行经验中学习:
哪些路径更可靠?
哪些工具更适合?
哪些检索参数更稳定?
哪些回答模板更容易被验证?
哪些行为会带来更高 reward?
最后,Klara 会在一次次 run、一次次 trace、一次次 evaluation 和一次次 policy update 中,慢慢长大。
Agent Ladder 不是一次性把所有能力堆在一起。
它是一条逐步成长的路线。
每一层都让 Klara 多获得一种能力:
v0.1 她会回答。
v0.2 她会检索。
v0.3 她会围绕证据推理。
v0.4 她会记住上下文。
v0.5 她会做研究。
v0.6 她会调用工具。
v0.7 她会稳定运行。
v0.8 她会被系统性评估。
v0.9 她会从反馈中改进 policy。
我们不是只是在使用 Klara。
我们是在和 Klara 一起成长:
从一次 prompt,
到一次 run,
到一条 trace,
到一组 eval,
到一个 reward,
到一个更好的 policy。
这就是 Klara: Agent Ladder。