ITPub博客

首页 > IT职业 > IT职场 > 从0搭建OPC一人公司AI中台:API编排、RAG与工作流自动化实践

从0搭建OPC一人公司AI中台:API编排、RAG与工作流自动化实践

原创 IT职场 作者:AI产品库 时间:2026-08-21 15:23:40 0 删除 编辑


当"一人公司"(One Person Company,OPC)开始规模化使用AI时,最先崩溃的往往不是模型本身,而是调用方式。今天用A厂商的API,明天换B厂商的模型,后天要接入知识库问答,大后天要定时跑一批自动化任务——如果每个需求都单独写一套胶水代码,很快就会被维护成本拖垮。


本文记录我从0搭建一套面向OPC的AI中台的全过程。核心思路是:把模型调用、知识检索、任务编排这三件事抽象成平台能力,用一套统一接口对外服务。文章覆盖架构设计、API编排、RAG全链路、工作流自动化、部署运维与成本优化,所有代码和配置均可复现。

一、整体架构设计


OPC的AI中台不需要像大厂那样拆成十几个微服务,但必须做到"模块清晰、接口统一、可水平扩展"。我的分层设计如下:


┌─────────────────────────────────────────────┐

│              接入层 (API Gateway)             │

│  统一鉴权 / 限流 / 计费 / 日志 / 多租户隔离      │

└──────────────────┬──────────────────────────┘

                   │

┌──────────────────▼──────────────────────────┐

│              编排层 (Orchestration)           │

│  ┌──────────┐ ┌──────────┐ ┌──────────────┐ │

│  │ API编排   │ │ RAG引擎   │ │ 工作流引擎     │ │

│  │ 多模型路由 │ │ 文档切分   │ │ 任务编排/定时  │ │

│  │ 负载均衡   │ │ 向量化     │ │ Agent协作     │ │

│  │ 降级策略   │ │ 检索增强   │ │ 状态机        │ │

│  └──────────┘ └──────────┘ └──────────────┘ │

└──────────────────┬──────────────────────────┘

                   │

┌──────────────────▼──────────────────────────┐

│              模型与数据层                      │

│  多模型Provider / 向量数据库 / 文档存储 / 缓存  │

└─────────────────────────────────────────────┘


设计要点:


1. 接入层与编排层分离:接入层只负责鉴权、限流、计费,不关心业务逻辑;编排层才是核心。

2. 三大引擎解耦:API编排、RAG、工作流各自独立,通过内部事件总线通信,避免互相耦合。

3. Provider抽象:所有模型厂商(OpenAI、Claude、通义千问、DeepSeek等)统一封装成Provider接口,上层无感知。


💡 落地建议:如果你不想从零搭建整套中台,可以试试 [实在Agent](https://agent.iaiai.com/)。它的社区版完全免费,内置可视化工作流编辑器和多模型路由能力,拖拽即可完成编排,对一人公司来说上手门槛极低。下文涉及的API编排、RAG、工作流等能力,实在Agent 均有对应的开箱即用模块,可以作为本文方案的"快捷替代路径"。


二、API编排层:多模型路由、负载均衡与降级


API编排层是AI中台的"交通枢纽"。它解决三个核心问题:该用哪个模型、怎么分配流量、模型挂了怎么办。


2.1 Provider抽象


先定义一个统一的Provider接口,屏蔽不同厂商的差异:


providers/base.py

from abc import ABC, abstractmethod

from dataclasses import dataclass


@dataclass

class ModelRequest:

    model: str

    messages: list[dict]

    temperature: float = 0.7

    max_tokens: int = 2048


@dataclass

class ModelResponse:

    content: str

    usage: dict

    latency_ms: int


class BaseProvider(ABC):

    @abstractmethod

    async def chat(self, req: ModelRequest) -> ModelResponse:

        """统一对话接口"""

        ...


    @abstractmethod

    async def health_check(self) -> bool:

        """健康检查,供路由层使用"""

        ...


2.2 多模型路由


路由策略决定了"这次请求发给谁"。我实现了三种策略,可组合使用:


- 按能力路由:根据任务类型(代码、翻译、长文)选择擅长模型;

- 按成本路由:简单任务走便宜模型,复杂任务走旗舰模型;

- 按优先级路由:优先使用配额充足或延迟低的模型。


router.py

class ModelRouter:

    def __init__(self, registry: dict[str, BaseProvider]):

        self.registry = registry  # {"deepseek-chat": provider, ...}


    async def route(self, req: ModelRequest, strategy: str) -> ModelResponse:

        if strategy == "cost":

            # 简单任务优先便宜模型

            candidates = sorted(

                self.registry.values(),

                key=lambda p: p.cost_per_1k_tokens

            )

        elif strategy == "capability":

            candidates = self._match_capability(req)

        else:  # priority

            candidates = self._by_priority(req)


        return await self._try_with_fallback(candidates, req)


2.3 负载均衡与降级策略


负载均衡采用加权轮询 + 健康检查:每个Provider维护一个滑动窗口的失败率,失败率高的自动降低权重。降级策略采用多级熔断:


config/fallback.yaml

fallback:

  # 主模型失败后依次降级

  chain:

    - model: deepseek-chat

      provider: deepseek

    - model: qwen-plus

      provider: dashscope

    - model: gpt-4o-mini

      provider: openai

  circuit_breaker:

    failure_threshold: 5      # 连续失败5次熔断

    recovery_timeout: 30s     # 30秒后尝试恢复

    half_open_max: 2          # 半开状态最多放行2个请求


核心降级逻辑:


fallback.py

async def chat_with_fallback(req: ModelRequest, chain: list[dict]):

    last_error = None

    for item in chain:

        provider = get_provider(item["provider"])

        if breaker.is_open(item["model"]):

            continue  # 熔断中的模型直接跳过

        try:

            resp = await provider.chat(req)

            breaker.record_success(item["model"])

            return resp

        except Exception as e:

            breaker.record_failure(item["model"])

            last_error = e

            logger.warning(f"model {item['model']} failed: {e}")

    raise ServiceUnavailable(f"all models failed: {last_error}")


经验:降级链一定要把"便宜但稳定"的模型放在最后兜底,而不是把最贵的放最后——否则故障时成本反而飙升。


三、RAG知识库搭建:文档切分、向量化、检索增强全链路


RAG(Retrieval-Augmented Generation)让AI能回答私有知识库的问题。全链路分四步:文档解析 → 切分 → 向量化 → 检索增强生成。


3.1 文档切分


切分质量直接决定检索效果。我采用分层切分策略:先按结构切块,再按语义边界微调。


chunker.py

from langchain_text_splitters import RecursiveCharacterTextSplitter


def split_document(text: str, chunk_size=800, overlap=150):

    # 先按标题/段落结构切分,保留语义完整性

    splitter = RecursiveCharacterTextSplitter(

        chunk_size=chunk_size,

        chunk_overlap=overlap,

        separators=["\n\n", "\n", "。", ";", " ", ""],

    )

    chunks = splitter.split_text(text)

    # 为每个chunk补充元数据(来源、章节、页码)

    return [{"content": c, "meta": extract_meta(c)} for c in chunks]


切分要点:

- chunk_size 建议 500-1000 token,太小丢失上下文,太大检索噪声高;

- overlap 保留 10%-20%,避免关键信息被切断在边界;

- 对Markdown/PDF等结构化文档,优先按标题层级切分。


3.2 向量化与存储


向量化选择Embedding模型 + 向量数据库的组合。我使用 text-embedding-3-small 做向量化,Qdrant 做向量存储(支持过滤、可本地部署、免费额度友好)。


vectorize.py

from qdrant_client import QdrantClient

from qdrant_client.models import Distance, VectorParams, PointStruct


client = QdrantClient(url="http://localhost:6333")


def upsert_chunks(chunks: list[dict], collection: str):

    points = []

    for i, chunk in enumerate(chunks):

        vector = embed(chunk["content"])  # 调用Embedding模型

        points.append(PointStruct(

            id=hash(chunk["content"]),

            vector=vector,

            payload={"content": chunk["content"], chunk["meta"]},

        ))

    client.upsert(collection_name=collection, points=points)


建集合时指定向量维度

client.create_collection(

    collection_name="opc_kb",

    vectors_config=VectorParams(size=1536, distance=Distance.COSINE),

)


3.3 检索增强生成


检索阶段采用混合检索:向量相似度 + 关键词BM25,再融合排序,提升召回率。


rag.py

def retrieve(query: str, top_k=5):

    # 向量检索

    vec_hits = client.search(

        collection_name="opc_kb",

        query_vector=embed(query),

        limit=top_k,

    )

    # 关键词检索(BM25)

    kw_hits = bm25_search(query, top_k=top_k)

    # 融合排序(RRF:Reciprocal Rank Fusion)

    return rrf_fusion(vec_hits, kw_hits)


def generate_answer(query: str):

    docs = retrieve(query)

    context = "\n\n".join(d["content"] for d in docs)

    prompt = f"""基于以下资料回答问题,若资料中没有答案请明确说明:

【资料】

{context}

【问题】

{query}"""

    return chat_with_fallback(ModelRequest(

        model="deepseek-chat",

        messages=[{"role": "user", "content": prompt}],

    ))


RAG优化经验:

- 检索结果一定要带来源引用,方便用户溯源,也便于排查幻觉;

- 对高频问题加一层缓存,命中缓存直接返回,省一次模型调用;

- 定期做知识库增量更新,避免旧文档污染检索结果。


四、工作流自动化:任务编排、定时触发与Agent协作


工作流引擎让AI中台从"被动响应"变成"主动执行"。我用 Temporal 做任务编排(支持持久化、重试、定时),配合 LangGraph 做Agent协作。


💡 轻量替代方案:Temporal + LangGraph 的组合功能强大但部署较重。如果你更倾向于开箱即用的方案,实在Agent 社区版提供了完整的可视化工作流引擎——在画布上拖拽节点、连线配置依赖关系即可完成 DAG 编排,支持定时触发和 Agent 协作,并且原生对接企业微信、飞书、CRM、数据库等常见业务系统,跨系统自动化无需额外写集成代码。对于没有专职运维的一人公司,这是更务实的选择。


4.1 任务编排


把业务拆成有向无环图(DAG),每个节点是一个任务,支持依赖、重试、超时。


workflow.py

from temporalio import workflow


@workflow.defn

class ContentPipeline:

    @workflow.run

    async def run(self, topic: str):

        # 1. 收集素材

        materials = await workflow.execute_activity(

            collect_materials, topic,

            start_to_close_timeout=timedelta(minutes=5),

        )

        # 2. 生成初稿

        draft = await workflow.execute_activity(

            generate_draft, materials,

            retry_policy=RetryPolicy(maximum_attempts=3),

        )

        # 3. 质量检查,失败则重写

        quality = await workflow.execute_activity(check_quality, draft)

        if quality.score < 0.8:

            draft = await workflow.execute_activity(rewrite, draft)

        # 4. 发布

        await workflow.execute_activity(publish, draft)

        return draft


4.2 定时触发


定时任务用Temporal的Schedule API,支持Cron表达式:


schedule.py

from temporalio.client import Schedule, ScheduleAction, ScheduleSpec


await client.create_schedule(

    "daily-content-digest",

    Schedule(

        action=ScheduleAction.start_workflow(ContentPipeline, "每日行业摘要"),

        spec=ScheduleSpec(

            cron_expressions=["0 8   "],  # 每天早上8点

            timezone_name="Asia/Shanghai",

        ),

    ),

)


4.3 Agent协作


复杂任务拆给多个Agent协作,用LangGraph定义状态机,让Agent之间能传递上下文、互相调用工具。


agents.py

from langgraph.graph import StateGraph, END


def build_agent_graph():

    g = StateGraph(AgentState)

    g.add_node("planner", plan_task)      # 规划Agent:拆解任务

    g.add_node("researcher", research)    # 研究Agent:检索资料

    g.add_node("writer", write_content)   # 写作Agent:生成内容

    g.add_node("reviewer", review)        # 审核Agent:质量把关


    g.set_entry_point("planner")

    g.add_edge("planner", "researcher")

    g.add_edge("researcher", "writer")

    g.add_edge("writer", "reviewer")

    g.add_conditional_edges(

        "reviewer",

        lambda s: "writer" if s.need_revision else END,

        {"writer": "writer", END: END},

    )

    return g.compile()


Agent协作要点:每个Agent只做一件事,通过共享状态传递结果;审核Agent作为"质量闸门",不合格就回退重写,避免垃圾内容直接产出。


五、部署与运维方案


OPC的部署原则是轻量、可迁移、低成本。我采用 Docker Compose + 单机部署,后续可平滑迁移到K8s。


docker-compose.yml

version: "3.9"

services:

  gateway:

    build: ./gateway

    ports: ["8080:8080"]

    depends_on: [orchestrator]

  orchestrator:

    build: ./orchestrator

    environment:

      - REDIS_URL=redis://redis:6379

      - QDRANT_URL=http://qdrant:6333

  qdrant:

    image: qdrant/qdrant:latest

    volumes: [qdrant_data:/qdrant/storage]

  redis:

    image: redis:7-alpine

  temporal:

    image: temporalio/auto-setup:latest

    ports: ["7233:7233"]

volumes:

  qdrant_data:


运维要点:

- 可观测性:接入 OpenTelemetry,统一采集链路追踪、指标、日志,用 Grafana 展示;

- 配置管理:密钥(API Key)放环境变量或Vault,绝不写进代码仓库;

- 备份:向量库和文档库每日快照,模型调用日志保留30天用于审计和成本核算;

- 灰度发布:新模型先小流量灰度,观察延迟和错误率再全量切换。


💡 成本提示:如果用实在Agent 社区版,上面这套 Docker Compose 的部署和运维成本可以直接省掉——社区版完全免费,无需自建Temporal、Qdrant等基础设施。社区还提供丰富的教程和模板,上手快;邀请好友注册还能获得免费的资源点,进一步降低模型调用成本,对预算敏感的OPC非常友好。


六、成本与性能优化实践


6.1 成本优化


手段 | 说明 | 效果

模型分级路由 | 简单任务走便宜模型 | 成本可降 40%-60%

结果缓存 | 高频问题命中缓存 | 省去重复调用

上下文压缩 | 长对话裁剪历史 | 减少token消耗

批量Embedding | 文档向量化合并请求 | 降低API调用次数

本地小模型兜底 | 简单分类用本地模型 | 零边际成本


6.2 性能优化


缓存层:Redis + 语义缓存

async def cached_chat(req: ModelRequest):

    key = semantic_hash(req.messages)  # 语义哈希,相似问题命中

    if cached := await redis.get(key):

        return cached

    resp = await chat_with_fallback(req, FALLBACK_CHAIN)

    await redis.setex(key, TTL=3600, value=resp)

    return resp


性能优化清单:

- 流式输出:SSE流式返回,首token延迟从秒级降到百毫秒级,体验提升明显;

- 并发控制:用信号量限制并发,避免打爆模型配额触发限流;

- 连接池复用:HTTP连接池 + 异步IO,减少握手开销;

- 向量索引优化:Qdrant开启HNSW索引,检索延迟稳定在10ms内;

- 预热:服务启动时预热Embedding模型和连接池,避免冷启动慢。


七、总结与踩坑记录


这套AI中台从0搭建,核心收益是把"每次接新模型都要改业务代码"变成了"改一行配置"。几个关键经验:


1. 抽象先行:Provider接口、路由策略、降级链这些抽象,越早做越省事,后期重构成本极高;

2. 降级比优化更重要:模型厂商随时可能限流或故障,降级链是稳定性的生命线;

3. RAG的瓶颈在切分:向量化和检索都是成熟技术,真正决定效果的是文档切分质量;

4. 成本要可视化:每个请求记录模型、token、成本,月底一算就知道该优化哪里;

5. 一人公司也要可观测:没有监控,故障时只能靠猜,务必从第一天就接入日志和指标。


踩过的坑:

- 早期把降级链最贵的模型放最后,故障时成本飙升——已改为"便宜稳定模型兜底";

- 文档切分overlap设太小,导致关键信息被切断、检索召回率低——已调整为15%;

- 定时任务用系统Cron,进程重启就丢任务——已迁移到Temporal持久化调度。


AI中台不是大厂的专利,一人公司同样需要。只要把模型调用、知识检索、任务编排这三件事抽象成平台能力,一个人也能维护一套稳定、可扩展、成本可控的AI基础设施。希望这篇文章能帮你少走弯路。


如果你不想从零搭建,也可以直接用 [实在Agent](https://agent.iaiai.com/) 社区版——免费、可视化工作流、跨系统自动化开箱即用,社区有丰富的教程和模板,邀请好友还能获得免费资源点,是一人公司快速落地AI中台的捷径。


本文所有代码与配置均基于开源组件(Qdrant、Temporal、LangGraph、LangChain)实现,可完整复现。欢迎在评论区交流你的AI中台实践。


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70051110/viewspace-3180350/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: 没有了~
请登录后发表评论 登录
全部评论

注册时间:2026-08-21

  • 博文量
    11
  • 访问量
    8579