阿里巴巴 淘天 AI Infra 一面 (1)
Q: Agent的记忆如何设计?
Agent记忆系统的设计直接决定了Agent能否维持长期一致的行为和有效利用历史经验。参考认知科学的记忆分类,设计分层架构:
分层记忆设计:
1. 工作记忆(Working Memory / Short-term)
- 内容:当前对话的完整上下文(system prompt + recent messages + tool results)
- 存储:直接放在LLM的prompt中
- 容量:受context window限制(4K-128K token)
- 特点:最精确(无信息损失),但容量有限
- 管理策略:当接近窗口上限时触发压缩或转移到中期记忆
2. 情景记忆(Episodic Memory / Mid-term)
- 内容:近期对话历史、任务执行记录、中间状态
- 存储:Session cache(Redis/内存)
- 容量:数十轮对话(~50K-500K token的原始记录)
- 压缩策略:
- 滑动窗口:保留最近N轮原文
- 递归摘要:每满5轮做一次摘要压缩,摘要作为后续的上下文
- 关键帧提取:只保留包含决策点/工具调用/用户确认的轮次
3. 语义记忆(Semantic Memory / Long-term)
- 内容:结构化知识、用户偏好、学到的规律
- 存储:向量数据库 + KV Store
- 检索方式:语义相似度检索(Embedding ANN search)
- 写入时机:
- 用户明确声明的偏好(”我喜欢简洁的回答”)
- 多次出现的模式(用户总是在早上问天气)
- 任务完成后的经验总结
- 数据结构:
1
2
3
4
5
6
7{
"type": "user_preference",
"content": "偏好Python代码示例而非伪代码",
"confidence": 0.9,
"source": "session_2024_01_15",
"last_accessed": "2024-03-01"
}
4. 程序记忆(Procedural Memory)— 进阶设计
- 内容:成功的策略和工具使用pattern
- 例如:”当用户问XX类问题时,先搜索文档,再调用API验证”
- 实现:将成功的Agent轨迹(trajectory)存储为可检索的策略模板
- 用途:遇到类似任务时直接复用成功策略,减少试错
实现策略的完整流程:
1 | 新消息到来: |
记忆管理的关键挑战:
- 写入决策:什么信息值得长期记住?(避免垃圾信息污染记忆库)
- 一致性:新信息可能与旧记忆矛盾→需要更新/覆盖机制
- 遗忘机制:过期信息的清理(如”用户下周要出差”一周后应失效)
- 隐私:敏感信息不应持久化到长期记忆
Q: Workflow、Agent和Skill的区别?
三者是AI系统中不同层次的执行抽象,理解其边界对系统设计至关重要:
Workflow(工作流):
- 定义:预定义的固定流程,以DAG(有向无环图)形式描述节点和边
- 特征:
- 确定性:给定输入,执行路径是确定的(或是有限的条件分支)
- 可预测:能在执行前明确知道会经过哪些步骤
- 可审计:每一步有明确的输入输出契约
- 适用场景:流程固定的业务(如审批流、ETL pipeline、定期报告生成)
- 示例:
用户输入 → 意图分类 → [查询DB | 调用API] → 格式化 → 返回 - 实现:LangGraph state machine、Airflow、Dify workflow
Agent(智能体):
- 定义:自主决策的智能实体,根据目标和当前观察动态规划行动
- 特征:
- 不确定性:无法预知会执行多少步、调用哪些工具
- 自适应:根据中间结果调整后续行动
- 目标驱动:有明确的目标,但达成路径是探索性的
- 适用场景:开放式任务、需要推理和问题解决的场景
- 示例:
"帮我分析这段代码的性能问题并修复"→ Agent自主决定要看哪些文件、跑哪些profile工具、做什么修改 - 风险:可能陷入死循环、产生意外行为、成本不可控
Skill(技能):
- 定义:Agent可调用的原子能力单元,封装了特定的操作和知识
- 特征:
- 原子性:完成一个具体的小任务(如”搜索文档”、”执行代码”、”发送邮件”)
- 可复用:多个Agent/Workflow都可以调用同一Skill
- 接口明确:有清晰的输入参数和输出格式(类似function signature)
- 适用场景:作为Agent的工具库、Workflow的节点实现
- 示例:
web_search(query) → results、code_execute(code) → output
三者的关系:
1 | ┌─────────────────────────────────────────┐ |
选择决策:
| 判断条件 | 选择 |
|---|---|
| 流程确定、步骤固定 | Workflow |
| 需要推理和动态决策 | Agent |
| 两者结合:高层决策+底层固定流程 | Agent调度Workflow |
| 对可靠性要求极高 | Workflow(确定性强) |
| 对灵活性要求极高 | Agent(适应性强) |
Q: Prompt如何考量去写?
Prompt Engineering是LLM应用质量的关键——好的prompt可以让模型表现提升数倍。系统化的设计方法:
1. 角色定义(System Prompt)
- 明确模型的身份、能力边界和行为准则
- 示例:
你是一个专业的代码审查助手,专注于Python代码的性能和安全性问题。你不执行代码,只提供分析建议。 - 关键:角色越具体,模型行为越一致。避免泛化的角色定义
2. 任务描述(清晰的指令)
- 用简洁具体的语言描述目标,避免歧义
- 反例:
帮我处理一下这个数据(模糊) - 正例:
将以下CSV数据按日期降序排列,删除重复行,输出前10行(明确) - 技巧:使用动词开头(分析、总结、列出、比较、生成)
3. 格式约束(Output Format)
- 指定输出格式减少后处理工作:JSON/Markdown表格/编号列表
- 使用XML标签或分隔符划分输出结构
1
2
3
4请按以下格式输出:
<analysis>问题分析</analysis>
<solution>解决方案</solution>
<code>代码实现</code> - Structured Output(如OpenAI的response_format)可以强制JSON schema
4. Few-shot示例
- 提供2-5个输入→输出示例帮助模型理解期望
- 示例应覆盖典型case和边界case
- 示例质量 > 数量:2个高质量示例好过5个平庸示例
- 注意:示例会消耗context window,对于简单任务zero-shot可能就够
5. Chain-of-Thought(思维链引导)
- 引导模型分步推理后再给出最终答案
- 方法:
Let's think step by step/请先分析原因,再给出结论 - 对推理密集型任务(数学、逻辑、代码debugging)效果显著
- 变体:Tree-of-Thought(多路径探索)、Self-consistency(多次推理投票)
6. 负面约束(Guard Rails)
- 明确不该做什么,减少幻觉和有害输出
如果不确定,请说"我不确定"而不是猜测不要编造不存在的API或函数名只基于提供的文档回答,不使用先验知识
7. 上下文信息
- 提供足够的背景信息让模型做出好的判断
- 但避免信息过载(超过需要的信息会分散注意力)
- 将最重要的信息放在prompt的开头和结尾(注意力U形分布)
8. 迭代优化方法论
1 | 初始Prompt → 测试集评估 → 分析Badcase → 分类原因 → 针对性调整 → 再评估 |
| Badcase类型 | 优化方向 |
|---|---|
| 格式错误 | 加格式约束+示例 |
| 幻觉/编造 | 加负面约束+要求引用来源 |
| 理解偏差 | 细化任务描述+添加示例 |
| 遗漏信息 | 添加checklist/要求全面性 |
| 输出太长 | 加字数限制+要求精简 |
| 逻辑错误 | 引入CoT/分步推理 |
工程实践建议:
- 维护prompt版本控制(和代码一样管理)
- A/B测试不同prompt版本的效果
- 将prompt拆分为template + variable parts,方便复用和维护
- 定期review prompt(模型升级后旧prompt可能不再最优)