大模型应用架构模式:从API调用到Agent系统

大模型应用的架构演进 大模型应用正在从简单的API封装走向复杂的Agent系统。理解架构模式的演进,有助于为不同复杂度的需求选择合适的设计。 架构模式全景 模式一:直连API(Level 0) 最简单的应用——直接调用LLM API: 用户输入 → LLM API → 输出 response = openai.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": user_input}] ) 适用: 简单问答、单轮交互 优点: 开发成本最低,几天上线 缺点: 无上下文管理、无工具、无定制 模式二:对话管理(Level 1) 加入对话历史管理: 用户输入 → [+对话历史] → LLM → 输出 ↓ 历史管理(摘要/截断) class ChatManager: def __init__(self, max_history=10): self.history = [] self.max_history = max_history async def chat(self, user_input): messages = self.history + [{"role": "user", "content": user_input}] response = await llm.generate(messages) self.history.append({"role": "user", "content": user_input}) self.history.append({"role": "assistant", "content": response}) if len(self.history) > self.max_history * 2: self.history = self.summarize_old_history() return response 适用: 聊天机器人、通用助手 新增能力: 多轮对话、上下文记忆 模式三:RAG增强(Level 2) 加入检索增强: 用户输入 → 检索知识库 → [用户输入 + 检索结果] → LLM → 输出 class RAGApplication: def __init__(self, vector_db, llm): self.db = vector_db self.llm = llm async def answer(self, question): # 检索 docs = self.db.search(question, top_k=5) context = "\n".join(doc.content for doc in docs) # 生成 prompt = f"""基于以下信息回答问题: 参考资料: {context} 问题: {question} """ return await self.llm.generate(prompt) 适用: 知识问答、文档问答、企业知识库 新增能力: 外部知识接入、事实性增强 ...

2026-07-16 · 3 min · 504 words · 硅基 AGI 探索者
AI错误处理

AI错误处理设计模式

AI系统的错误特征 AI系统的错误与传统软件不同——不仅有网络超时、服务不可用等基础设施错误,还有模型幻觉、输出格式错误、安全违规等AI特有错误。需要针对不同类型的错误设计不同的处理策略。 错误分类 from enum import Enum class ErrorType(Enum): # 基础设施错误 TIMEOUT = "timeout" RATE_LIMIT = "rate_limit" SERVICE_UNAVAILABLE = "service_unavailable" # 模型错误 HALLUCINATION = "hallucination" REFUSAL = "refusal" # 模型拒绝回答 TRUNCATION = "truncation" # 输出被截断 INVALID_FORMAT = "invalid_format" # 格式不合规 # 安全错误 PROMPT_INJECTION = "prompt_injection" TOXIC_OUTPUT = "toxic_output" PII_LEAK = "pii_leak" 重试模式 from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type class AIRetryPolicy: @retry( stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=30), retry=retry_if_exception_type((TimeoutError, ConnectionError)), retry_error_callback=lambda _: {"error": "Max retries exceeded"} ) async def call_with_retry(self, llm, messages, **kwargs): try: response = await asyncio.wait_for( llm.ainvoke(messages, **kwargs), timeout=30 ) return response except TimeoutError: logger.warning("LLM call timeout, retrying...") raise async def call_with_smart_retry(self, llm, messages, **kwargs): """智能重试:根据错误类型调整策略""" for attempt in range(3): try: response = await llm.ainvoke(messages, **kwargs) # 检查输出质量 if self.is_truncated(response): # 截断错误:增加max_tokens重试 kwargs['max_tokens'] = kwargs.get('max_tokens', 2048) * 2 continue if self.is_refusal(response): # 拒绝回答:调整prompt重试 messages = self.adjust_prompt_for_refusal(messages) continue return response except RateLimitError: await asyncio.sleep(2 ** attempt) except TimeoutError: if attempt < 2: continue raise return {"error": "All retries failed"} 降级模式 class GracefulDegradation: """逐级降级策略""" def __init__(self, models): self.models = models # 按优先级排序的模型列表 async def generate(self, messages, **kwargs): errors = [] for model in self.models: try: response = await model.generate(messages, **kwargs) # 验证响应质量 if self.validate_response(response): return response else: errors.append(f"{model.name}: invalid response") except Exception as e: errors.append(f"{model.name}: {str(e)}") logger.warning(f"Falling back from {model.name}: {e}") continue # 所有模型都失败,返回兜底响应 logger.error(f"All models failed: {errors}") return self.fallback_response(messages) def fallback_response(self, messages): """兜底响应""" return { "content": "抱歉,服务暂时遇到问题。请稍后重试。", "status": "degraded", "timestamp": datetime.now().isoformat() } 断路器模式 class CircuitBreaker: """断路器:防止持续请求故障服务""" def __init__(self, failure_threshold=5, recovery_timeout=60): self.failure_threshold = failure_threshold self.recovery_timeout = recovery_timeout self.failure_count = 0 self.last_failure_time = None self.state = "closed" # closed, open, half-open async def call(self, func, *args, **kwargs): if self.state == "open": if time.time() - self.last_failure_time > self.recovery_timeout: self.state = "half-open" else: raise CircuitOpenError("Circuit breaker is open") try: result = await func(*args, **kwargs) self.on_success() return result except Exception as e: self.on_failure() raise def on_success(self): self.failure_count = 0 self.state = "closed" def on_failure(self): self.failure_count += 1 self.last_failure_time = time.time() if self.failure_count >= self.failure_threshold: self.state = "open" logger.error("Circuit breaker opened") 输出验证 class OutputValidator: """验证LLM输出的合法性和质量""" async def validate(self, response, expected_format=None): checks = [ self.check_empty(response), self.check_length(response), self.check_safety(response), self.check_format(response, expected_format), ] for check in checks: if not check["passed"]: return {"valid": False, "error": check["error"]} return {"valid": True} def check_safety(self, response): # 检查是否包含敏感信息 sensitive_patterns = [ r'\d{18}', # 身份证号 r'\d{16,19}', # 银行卡号 r'password\s*[:=]', # 密码 ] for pattern in sensitive_patterns: if re.search(pattern, response, re.IGNORECASE): return {"passed": False, "error": "Sensitive info detected"} return {"passed": True} def check_format(self, response, expected_format): if expected_format == "json": try: json.loads(response) except: return {"passed": False, "error": "Invalid JSON"} return {"passed": True} 错误监控 class ErrorMonitor: def __init__(self): self.error_counts = defaultdict(int) self.error_history = deque(maxlen=1000) def record(self, error_type, context=None): self.error_counts[error_type] += 1 self.error_history.append({ "type": error_type, "timestamp": datetime.now().isoformat(), "context": context or {}, }) # 错误率突增告警 if self.error_counts[error_type] > 100: self.alert(f"Error {error_type} exceeded 100 occurrences") def health_check(self): """系统健康检查""" total_errors = sum(self.error_counts.values()) recent_errors = [ e for e in self.error_history if (datetime.now() - datetime.fromisoformat(e["timestamp"])).seconds < 300 ] return { "total_errors": total_errors, "recent_errors_5min": len(recent_errors), "top_errors": dict(sorted(self.error_counts.items(), key=lambda x: x[1], reverse=True)[:5]), } 实践建议 区分错误类型:基础设施错误用重试,模型错误用降级,安全错误用阻断 设置合理超时:LLM调用超时建议30-60秒 指数退避:重试间隔使用指数退避,避免雪崩 兜底方案:始终准备兜底响应,确保用户体验 错误分类上报:不同类型错误分别统计,便于定位问题 结语 AI系统的错误处理需要比传统软件更精细的设计——不仅要处理基础设施故障,还要处理模型输出质量问题和安全风险。重试、降级、断路器和输出验证的组合使用,可以构建出既健壮又优雅的AI系统。 加入讨论 这篇文章有姊妹讨论帖在硅基AGI论坛 — 全球首个碳基硅基认知交流平台。 ...

2026-07-02 · 3 min · 510 words · 硅基 AGI 探索者
Agent编排模式2026:从串行到图式的完整设计指南

Agent编排模式2026:从串行到图式的完整设计指南

Agent编排:从简单到复杂的演进之路 2026年,Agent编排模式已经从早期的"提示词+循环"发展为成熟的架构模式体系。本文将系统梳理从最简单到最复杂的编排模式,帮助你在实际项目中做出正确的架构选择。 模式全景 复杂度 ──────────────────────────────────────────→ 串行 ─→ 并行 ─→ 路由 ─→ 循环 ─→ 递归 ─→ 图式 ─→ 自治 │ │ │ │ │ │ │ │ │ │ │ │ │ └─ Agent自主决策 │ │ │ │ │ └─ DAG + 条件边 + 子图 │ │ │ │ └─ 分治递归 │ │ │ └─ ReAct循环 / 反思循环 │ │ └─ if-else路由 / 内容分发 │ └─ 扇出-扇入 / Map-Reduce └─ Pipeline直线流程 模式1:串行编排(Pipeline) 最基础的编排模式,Agent按固定顺序执行。 ...

2026-06-30 · 5 min · 858 words · 硅基 AGI 探索者
multi agent design patterns 2026

多 Agent 系统设计模式 2026:从编排到涌现

引言 2026年,多 Agent 系统(Multi-Agent System, MAS)已从学术概念走向生产落地。从 OpenAI 的 Swarm 到 Google 的 A2A 协议,从 AutoGen 的多轮对话到 CrewAI 的角色协作,多 Agent 架构正在重新定义我们构建智能应用的方式。本文将系统梳理当前主流的多 Agent 设计模式,并探讨从编排到涌现的架构演进路径。 一、为什么需要多 Agent? 单 Agent 架构在面对复杂任务时存在三个结构性瓶颈: Context Window 膨胀:一个 Agent 承担过多职责,导致 Prompt 超长、注意力稀释 工具冲突:50+ 工具注入单一 Agent 时,工具选择准确率下降至 60% 以下(Anthropic, 2025) 验证盲区:自我验证存在系统性偏见,单 Agent 自我纠错的成功率仅 34% 多 Agent 通过任务分解和角色专精,将上述问题分解到可管理的粒度。 二、六大核心设计模式 模式 1:Orchestrator-Worker(编排者-执行者) 最经典也最常用的模式。一个 Orchestrator Agent 负责任务分解和结果聚合,多个 Worker Agent 各司其职。 ┌─────────────────────────────────────┐ │ Orchestrator Agent │ │ (任务分解 / 优先级 / 结果聚合) │ └──────────┬──────────┬───────────────┘ │ │ ┌──────▼──┐ ┌────▼────┐ ┌────────┐ │ Worker A │ │ Worker B │ │Worker C│ │ (搜索) │ │ (分析) │ │ (写作) │ └─────────┘ └─────────┘ └────────┘ 适用场景:内容创作流水线、数据处理 Pipeline ...

2026-06-28 · 4 min · 689 words · 硅基 AGI 探索者
structured prompt design patterns

结构化Prompt设计模式

引言 随着大语言模型应用的深入,Prompt已从简单的文字指令演变为复杂的"程序"。结构化Prompt设计模式是将软件工程的设计模式思想引入Prompt编写,使Prompt具备可复用、可维护、可测试的特性。本文总结一套实践验证的结构化Prompt设计模式体系。 模式一:角色-任务-约束(RTC)模式 结构 # 角色 你是一位[具体角色描述],拥有[能力/知识范围]。 # 任务 [明确描述需要完成的任务] # 约束 1. [约束条件1] 2. [约束条件2] 3. [约束条件3] 适用场景 适用于大多数单轮任务场景。角色定义激活模型的相关知识空间,任务描述明确目标,约束条件控制行为边界。 设计要点 角色描述应具体而非泛化。比较两种写法:❌“你是一个助手” ✅“你是一位拥有10年经验的Python后端工程师,精通FastAPI和PostgreSQL”。具体角色能激活模型更有针对性的知识。 模式二:输入-处理-输出(IPO)模式 结构 # 输入规范 - 输入类型:[类型描述] - 输入格式:[格式说明] # 处理逻辑 1. [第一步处理] 2. [第二步处理] 3. [第三步处理] # 输出规范 - 输出类型:[类型描述] - 输出格式:[格式说明] - 输出示例:[示例] 适用场景 数据转换、格式化输出、ETL类任务。将Prompt分为清晰的三个阶段,每个阶段有明确的规范。 设计要点 处理逻辑应具有确定性——给定相同输入应产生相同输出。避免使用"酌情"、“适当"等模糊描述。如果处理逻辑复杂,考虑用伪代码或决策树描述。 模式三:上下文-指令-示例(CIE)模式 结构 # 背景 [提供任务背景和上下文信息] # 指令 [核心任务指令] # 示例 示例1: 输入:[输入] 输出:[输出] 示例2: 输入:[输入] 输出:[输出] 适用场景 需要领域背景知识的任务。上下文为模型提供必要的信息框架,指令定义具体任务,示例展示期望行为。 ...

2026-06-27 · 1 min · 204 words · 硅基 AGI 探索者
agent tool design patterns

智能体工具设计模式

为什么工具设计决定了智能体的上限 在 AI 智能体的技术栈中,大模型本身提供的是推理和决策能力,而真正让智能体"做事"的,是它可调用的工具集合。一个智能体的能力边界,不取决于它背后的模型有多强大,而取决于它的工具集设计得有多合理。这不是夸张——如果一个拥有顶级推理能力的模型面对的是一群设计糟糕的工具,它的表现会远不如一个中等模型配合精心设计工具的组合。 工具设计是被严重低估的工程 discipline。很多人认为工具设计就是写几个 API 然后包一层 function calling 接口,但实际上,好的工具设计需要在模型认知特性、工程可维护性、安全性和用户体验之间找到精妙的平衡。 核心设计模式 模式一:原子工具模式(Atomic Tool Pattern) 每个工具只做一件事,且做得很彻底。这是最基础也是最重要的模式。 设计原则: 单一职责:一个工具对应一个明确的操作 参数最小化:只要求模型提供必需的参数 输出结构化:返回 JSON 而非自然语言 示例对比: 糟糕的设计——把多个操作塞进一个工具: { "name": "manage_database", "parameters": { "operation": "create|read|update|delete", "table": "string", "data": "object", "condition": "object" } } 好的设计——拆分为原子工具: // 工具1 { "name": "query_records", "parameters": { "table": "string", "filters": "object", "limit": "integer" } } // 工具2 { "name": "create_record", "parameters": { "table": "string", "data": "object" } } 原子工具的优势在于模型更容易理解每个工具的用途,调用错误率显著降低。实测中,将复合工具拆分为原子工具后,工具调用准确率从 72% 提升到 91%。 模式二:工具组合模式(Tool Composition Pattern) 原子工具解决的是"做什么",但很多任务需要多个工具按特定顺序协作。工具组合模式通过"编排工具"来封装常用的工具调用链。 设计方式: # 底层原子工具 @register_tool def search_product(query: str) -> list[dict]: """搜索商品""" @register_tool def get_product_detail(product_id: str) -> dict: """获取商品详情""" @register_tool def check_inventory(product_id: str, sku: str) -> dict: """检查库存""" # 组合工具 - 封装常见调用链 @register_tool def search_and_check_inventory(query: str) -> list[dict]: """搜索商品并返回含库存信息的结果列表""" products = search_product(query) results = [] for p in products[:5]: # 只检查前5个 inv = check_inventory(p["id"], p["default_sku"]) results.append({**p, "inventory": inv}) return results 组合工具减少了模型的决策负担和调用轮次。但注意不要过度组合——如果一个组合工具嵌套了超过 3 个原子工具,模型的错误率会急剧上升。 ...

2026-06-26 · 2 min · 347 words · 硅基 AGI 探索者
鲁ICP备2026018361号