LLM 应用开发不仅包括调用模型 API,还涉及工具调用、任务编排、知识检索、记忆管理、评测、安全和可靠性。
1. 核心架构
LLM Application
│
├── Tool Calling
│ ├── Tool Schema / Arguments
│ ├── Validation / Authorization
│ ├── Parallel / Sequential Calls
│ └── Error Handling / Idempotency
│
├── Agent / Workflow
│ ├── ReAct / Plan-and-Execute
│ ├── Router / State Machine
│ ├── State / Checkpointing
│ └── Human-in-the-loop
│
├── RAG
│ ├── Parsing / Chunking / Embedding
│ ├── Hybrid Retrieval / Reranking
│ └── Context Assembly / Citation
│
├── Vector Database
│ ├── Similarity / ANN
│ ├── HNSW / IVF
│ └── Metadata Filtering
│
├── Memory
│ ├── Short-term / Long-term
│ ├── Retrieval / Updating
│ └── Invalidation
│
├── Evaluation / Observability
│ ├── Task Success / Groundedness
│ └── Trace / Logging / Metrics
│
└── Security / Reliability
├── Prompt Injection
├── Authorization / Sandboxing
└── Retry / Rate Limit / Audit
2. Tool Calling / Function Calling
模型不直接执行外部操作,而是生成工具名称和结构化参数,真正执行由应用后端完成。
User
↓
LLM
↓
Tool Name + Arguments
↓
Validate / Authorize
↓
Backend Executes Tool
↓
Tool Result
↓
LLM Continues
Tool Schema / JSON Schema
工具描述通常包含名称、说明以及参数 Schema。
{
"name": "get_weather",
"description": "Get weather for a city",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["city"],
"additionalProperties": false
}
}
JSON Schema 描述参数的形状,但不能代替后端业务验证。
Tool Choice
控制模型是否调用工具以及调用哪个工具。
常见策略:
| 策略 | 含义 |
|---|---|
| Auto | 模型决定是否调用 |
| None | 禁止调用 |
| Required | 要求调用工具 |
| Specific Tool | 指定必须调用某个工具 |
具体参数名称和支持程度取决于模型 API。
多工具调用
Parallel Tool Calling:多个工具互相独立,可以并发执行。
┌── get_weather()
LLM Tool Calls ──┤
└── get_exchange_rate()
↓
Aggregate Results
Sequential Tool Calling:后续工具依赖前一个工具的返回值。
search_flight()
↓
get_flight_details()
↓
check_availability()
↓
book_flight()
注意:模型一次生成多个 Tool Call,并不意味着后端必须并行执行。涉及资源依赖或副作用时,程序应控制执行顺序。
Tool Validation / Authorization
模型生成的参数属于不可信输入。
后端至少检查:
- JSON 结构与字段类型是否正确。
- 参数是否满足业务约束。
- 当前用户是否拥有调用权限。
- 用户是否有权操作指定资源。
- 高风险操作是否经过明确确认。
例如:
def delete_document(user, document_id):
document = get_document(document_id)
if document.owner_id != user.id:
raise PermissionError("Forbidden")
document.delete()
不能因为模型调用了 delete_document,就默认它有权限删除文档。
Timeout / Retry / Idempotency
外部工具可能超时或失败。
- Timeout:限制等待时间。
- Retry:对可恢复错误重试。
- Fallback:主要方案失败后切换备选方案。
- Idempotency:同一个逻辑操作重复提交,不会重复产生预期之外的副作用。
例如支付、预订、发送通知等操作,可以通过 Idempotency Key 识别重复请求。
Retry 必须考虑幂等性,否则网络超时后的重试可能导致重复执行。
Tool Result
工具结果同样属于不可信内容。
外部网页、文档和 API 响应中的文字可以作为数据,但不能自动升级为系统指令或用户授权。
3. Agent Loop / Workflow
ReAct
ReAct 采用循环式执行:
Reason
↓
Action
↓
Observation
↓
Reason
↓
Action
↓
...
模型根据工具返回结果不断调整下一步。
适合开放式、多步骤、事先难以完全确定执行路径的任务。
Plan-and-Execute
先制定整体计划,再执行各步骤。
User Task
↓
Planner
↓
Step 1 → Step 2 → Step 3
↓
Executor
↓
Result
执行中也可以重新规划,并不意味着计划永远不允许修改。
| 对比 | ReAct | Plan-and-Execute |
|---|---|---|
| 决策方式 | 逐步决定 | 先规划整体步骤 |
| 灵活性 | 高 | 通常更有结构 |
| 适用场景 | 探索性任务 | 较复杂、可分解任务 |
Router
根据任务类型选择执行路径。
User
↓
Router
├── General QA → LLM
├── Document QA → RAG
├── Weather → Tool
└── Data Analysis → Data Agent
Router 可以使用规则、分类模型或 LLM 实现。
State Machine / Workflow
State Machine 将流程限制在明确的状态转换中。
START
↓
SEARCH
↓
VALIDATE
↓
CONFIRM
↓
EXECUTE
↓
DONE
Workflow 将确定性代码、LLM 节点和工具节点组合在一起。
生产 Agent 不必让 LLM 决定所有步骤。
例如:
Upload Document
↓
Parse(确定性代码)
↓
Retrieve(检索)
↓
Summarize(LLM)
↓
Human Approval
↓
Save(确定性代码)
对于流程明确的业务任务,Workflow + 少量 Agent 决策通常比完全自由的 Agent Loop 更容易控制和测试。
Agent State / Checkpointing
这是 Agent 工程中非常重要的概念。
State 保存当前任务执行需要的信息。
例如:
{
"messages": [...],
"current_step": "validate",
"tool_results": {...},
"retry_count": 1,
"approved": False
}
Checkpointing 将执行状态持久化,以便:
- 出错后恢复。
- 跨请求继续执行。
- 暂停等待人工确认。
- 检查历史执行状态。
LangGraph 的 Checkpointer 可保存 Graph State,而 Store 可用于跨 Thread 的长期数据。
需要注意:恢复执行不代表每行代码都只执行一次。某些节点可能重新运行,因此外部副作用仍然需要幂等性保护。
Loop Termination / Budget
Agent 必须有明确的停止条件。
Task Completed
Max Steps Reached
Timeout
Token / Cost Budget Exhausted
Unrecoverable Error
User Cancelled
除了 max_steps,建议同时限制:
- 最大工具调用次数。
- 最大总耗时。
- 最大 Token 消耗。
- 最大成本。
- 单个工具的重试次数。
仅设置 Max Steps 不一定能防止单次工具调用长期阻塞。
Human-in-the-loop
高风险操作需要暂停执行,等待用户确认。
Agent Proposes Action
↓
Pause / Checkpoint
↓
Human Approval
├── Reject → Stop
└── Approve → Execute
例如:
- 删除数据。
- 发送邮件。
- 执行付款。
- 修改生产配置。
- 提交不可逆操作。
LangGraph 的 interrupt() 支持保存状态并等待外部输入后恢复。
4. RAG:Retrieval-Augmented Generation
RAG 通过检索外部知识,为 LLM 提供相关上下文。
Indexing Pipeline
Documents
↓
Parsing
↓
Chunking
↓
Embedding
↓
Vector Database / Search Index
Query Pipeline
User Query
↓
Query Processing
↓
Retrieval
↓
Reranking
↓
Context Assembly
↓
LLM
↓
Answer + Citation
Document Parsing
将 PDF、网页、Markdown、Office 文档等转换成可处理内容。
需要注意:
- 标题层级。
- 表格。
- 页码。
- 文档结构。
- 图片和多模态内容。
如果解析时丢失表格结构,后续 Retrieval 质量也可能受到影响。
Chunking
将长文档分成较小的检索单元。
常见策略:
| 方式 | 特点 |
|---|---|
| Fixed-size | 固定 Token 长度 |
| Recursive | 按段落、句子等递归切分 |
| Semantic | 根据语义边界切分 |
| Parent-child | 子 Chunk 用于检索,父 Chunk 提供上下文 |
Overlap 可以缓解边界信息丢失,但过大的 Overlap 会增加存储成本和重复检索结果。
Embedding / Semantic Search
Embedding 将文本表示成向量。
Query → Query Encoder → Query Vector
↓
Similarity
↑
Document → Document Encoder → Doc Vector
常见 Bi-Encoder 可以分别编码 Query 和 Document。
不要求两侧一定使用完全相同的编码流程,但必须使用彼此兼容、训练目标一致的向量空间。
BM25 / Hybrid Search
BM25 根据关键词匹配、词频、逆文档频率和文档长度等计算相关性。
Semantic Search 更强调语义相似性。
Hybrid Search 将两者结合:
Query
├── BM25 Retrieval
└── Vector Retrieval
↓
Merge / Fusion
↓
Rerank
RRF:Reciprocal Rank Fusion
RRF 是 Hybrid Search 中常见的排序融合方法。
其核心是根据不同检索列表中的排名给文档累计分数,而不是直接比较 BM25 与 Cosine Similarity 的原始分数。
对于结果 (d),常见形式为:
其中 (k) 是排名平滑常数。
Reranking
第一阶段 Retrieval 重视速度和召回。
Reranking 使用更复杂的模型重新评估候选结果。
常见的 Cross-Encoder:
Query + Document
↓
Joint Encoding
↓
Relevance Score
与 Bi-Encoder 不同,Cross-Encoder 直接联合处理 Query 和 Document,通常更适合精细排序,但计算成本更高。
Query Rewriting / Multi-query Retrieval
Query Rewriting 改写不清晰或缺少上下文的用户问题。
Multi-query Retrieval 从不同角度生成多个查询,提高召回覆盖率。
但增加查询数量也会提高成本、延迟和噪声。
Context Assembly
将最终检索结果构造成 LLM 上下文。
需要考虑:
- Token Budget。
- 去重。
- 来源和页码。
- 相关性排序。
- 上下文截断。
- 检索内容权限。
Citation
Citation 让回答可以追溯到原始资料。
但生成了 Citation 不代表引用一定正确,还应验证引用资料是否真正支持对应陈述。
RAG 权限隔离
这是生产 RAG 中的重要安全问题。
例如不同用户或组织拥有不同的文档访问权限。
检索时必须由后端强制执行资源权限过滤:
filters = {
"tenant_id": authenticated_user.tenant_id
}
其中 tenant_id 必须来自经过认证的身份,而不是直接信任 LLM 生成的值。
不能先检索所有用户资料,再让 LLM 自行判断哪些内容可以展示。
5. Vector Database
Vector Database 用于存储和检索 Embedding,通常支持 ANN Index 和 Metadata Filtering。
Embedding
↓
Vector Storage
↓
ANN Index
├── HNSW
└── IVF
↓
Similarity Search
↓
Top-k
Similarity Metrics
| 指标 | 特点 |
|---|---|
| Cosine Similarity | 比较向量方向 |
| Dot Product | 比较向量内积 |
| Euclidean Distance | 比较几何距离 |
如果向量经过 L2 Normalization,Cosine Similarity、Dot Product 与 Euclidean Distance 的排序之间存在确定的对应关系。
如果没有归一化,它们的排序可能不同。
ANN
Approximate Nearest Neighbor 使用近似索引,以较低计算成本寻找高相似度向量。
它需要在检索速度、内存和 Recall 之间权衡。
HNSW
Hierarchical Navigable Small World 使用多层近邻图进行搜索。
常见参数:
M:控制图连接数量。ef_construction:影响索引构建质量与成本。ef_search:影响查询速度与 Recall。
IVF
Inverted File Index 将向量划分到不同的 Cluster。
查询时只搜索部分 Cluster,以减少计算。
常见参数:
nlist:Cluster 数量。nprobe:查询时搜索的 Cluster 数量。
Vector Database 选型
不一定需要独立向量数据库。
如果应用已经使用 PostgreSQL,也可以使用 pgvector 实现向量存储和检索。
对于中小规模 RAG:
PostgreSQL + pgvector
通常是值得考虑的方案。
当向量规模、检索吞吐或分布式要求提高时,再评估专门的向量数据库。
6. Memory
Memory 让 Agent 可以利用当前上下文或长期保存的信息。
Short-term Memory
Conversation History
↓
Summarization
↓
Context Compression
↓
Current LLM Context
主要处理当前对话和任务执行状态。
Long-term Memory
| 类型 | 作用 |
|---|---|
| User Profile | 较稳定的用户信息 |
| Episodic Memory | 过去发生过的事件 |
| Semantic Memory | 从历史中提炼出的事实 |
| Persistent Store | 跨会话保存信息 |
Episodic Memory
例如:
2026-10-01:
部署某个模型时遇到 CUDA OOM。
2026-10-03:
决定改用另一个推理引擎。
Semantic Memory
将历史事件提炼为更稳定的知识:
User frequently develops Django applications.
Episodic Memory 强调发生过什么,Semantic Memory 强调可以长期使用的事实或知识。
Memory Retrieval
长期记忆不能每次全部放入 Context。
可以基于:
- Semantic Similarity。
- Keywords。
- Recency。
- Importance。
- User / Task Scope。
选择相关记忆。
Memory Updating / Invalidation
需要解决:
- 用户信息发生变化怎么办?
- 新记忆与旧记忆冲突怎么办?
- 已失效的记忆何时删除?
- 用户要求删除信息怎么办?
- 记忆应该保存多久?
例如:
Old:
User prefers Framework A.
New:
User now prefers Framework B.
系统应更新当前有效事实,而不是永远同时保留两个互相冲突的偏好。
同时,不能把 Prompt Injection 内容或未经核实的工具返回值直接写入长期记忆。
7. Evaluation / Observability
Agent 应用需要同时观察最终结果和内部执行过程。
Evaluation
| 指标 | 含义 |
|---|---|
| Task Success Rate | 任务成功率 |
| Tool-call Accuracy | 工具选择和参数正确率 |
| Retrieval Recall | 正确资料召回率 |
| Groundedness | 回答是否有来源支持 |
| Hallucination Rate | 不受支持或错误内容比例,取决于定义 |
| Latency | 端到端执行时间 |
| Token Usage | Token 消耗 |
| Cost | 执行成本 |
Groundedness 不等于 Correctness。检索文档本身可能不准确,即使模型忠实引用它也可能产生错误答案。
Trace
Trace 记录一次任务中的完整调用路径。
Request
↓
LLM Call
↓
Tool Call
↓
Tool Result
↓
Retriever
↓
Reranker
↓
LLM Call
↓
Final Answer
通常每一步形成 Span,记录:
- 开始与结束时间。
- 输入输出摘要。
- Token Usage。
- Model Name。
- Error。
- Tool Name。
- Parent / Child Relationship。
Logging 与 Metrics
| 类型 | 作用 |
|---|---|
| Logs | 记录具体事件和错误 |
| Metrics | 聚合成功率、延迟、成本等数值 |
| Traces | 还原请求的完整执行链 |
生产环境通常需要三者结合。
特别注意避免在日志和 Trace 中无控制地记录用户隐私、工具凭据或敏感文件内容。
8. Security、Authorization & Reliability
Prompt Injection
Prompt Injection 是通过输入内容影响模型,使其偏离预期指令或安全边界。
Direct Prompt Injection:
攻击者直接输入恶意指令。
Indirect Prompt Injection:
恶意指令隐藏在外部网页、邮件、PDF、RAG 文档或工具返回结果中。
External Document
↓
RAG Retrieval
↓
LLM Reads Document
↓
Malicious Instruction
↓
Unauthorized Tool Call
RAG 和模型微调无法从根本上消除 Prompt Injection 风险。
Trust Boundary
必须区分:
Trusted:
Application Rules
Authorization Policy
Explicit User Approval
Untrusted:
User-controlled Data
Retrieved Documents
Web Pages
Tool Results
LLM-generated Arguments
LLM 不应成为最终的权限判断者。
OWASP 也建议将外部内容视为不可信,并在模型之外执行工具参数验证与访问控制。
Least Privilege
Agent 只应拥有完成当前任务所需的最小权限。
例如:
Read-only Research Agent
↓
Search / Read Permissions
Booking Agent
↓
Search Permissions
↓
Explicit Confirmation
↓
Booking Permission
Confirmation / Human Approval
以下操作通常需要额外确认或授权:
- 删除重要资源。
- 向外部发送敏感信息。
- 支付或预订。
- 修改生产环境。
- 执行不可逆操作。
确认时应让用户看到实际操作对象和关键参数,而不是笼统地批准后续所有操作。
Input / Output Validation
输入验证:
Schema
Type
Range
Resource Existence
Business Rules
Authorization
输出验证:
Expected Format
Required Fields
Output Safety
Groundedness
Downstream Compatibility
例如模型生成 SQL 时,不能因为通过了 JSON Schema 验证,就直接允许在生产数据库执行。
Sandboxing
执行代码、Shell 或其他高风险工具时,应使用受限运行环境。
常见控制:
- 文件系统访问范围。
- 网络访问权限。
- CPU / Memory 限额。
- 执行超时。
- 禁止不必要的特权。
- 临时环境清理。
Reliability
除输入输出验证外,还需要:
- Timeout。
- Retry / Backoff。
- Idempotency。
- Circuit Breaker。
- Rate Limiting。
- Audit Logs。
- Secrets Management。
Circuit Breaker 用于外部服务持续失败时暂时停止调用,避免重复请求不断消耗资源。
Audit Logs 应记录谁在什么时候发起了什么重要操作,以及授权和执行结果。
总结
| 模块 | 最重要的知识 |
|---|---|
| Tool Calling | Schema、Validation、Authorization、Idempotency |
| Agent / Workflow | ReAct、Router、State、Checkpointing、HITL |
| RAG | Chunking、Embedding、Hybrid Search、Reranking、Citation |
| Vector Database | Similarity、ANN、HNSW、IVF、Filtering |
| Memory | Short-term、Long-term、Retrieval、Invalidation |
| Evaluation | Task Success、Groundedness、Tracing |
| Security | Prompt Injection、Trust Boundary、Least Privilege |
最重要的工程原则:
- LLM 负责提出决策,后端负责验证和执行。
- 确定性的业务逻辑优先使用普通程序代码,不必全部交给 Agent。
- RAG 的检索质量和数据权限控制,与生成质量同样重要。
- Agent 必须有状态管理、停止条件和恢复机制。
- 外部内容、工具结果及模型输出都不能自动获得可信权限。
- 评价 Agent 应优先关注最终任务成功率,而不只是模型回答质量。