支柱五·Agent 核心(主循环)
解读引擎——产品论题(同一语料库,按受众分层呈现)在这里执行。inference(backend/internal/conversation/inference/)包裹了 CloudWego 的 eino ADK 循环(Anthropic → 原生 Messages API;Gemini → 自己的适配器;其余所有供应商 → OpenAI 兼容适配器——eino_model.go);前端只是一个薄薄的 SSE 消费者。两个近期的结构性改动定义了这根支柱:可独立启动的核心——backend/agentcore/(刻意放在 internal/ 之外)暴露出 Driver 和 BuildVisitorAgent(driver, input),使核心可以独立启动(bridge.go 把一个 Driver 适配到循环的内部端口上;eval-harness/ 是一个独立的 Go module,用自己的 EvalDriver 驱动同一个循环——"eval 只是又一个消费者");以及入口无关原则——agent 对入口无关:各入口填好一个中立的 _meta.standmeet/session 就发起调用。
现状(2026-09-07,36789537d): Bridge/Driver 已经落地,此前的 fixture 偏差已经纠正——核心里不再残留任何 fixture("Driver 本身就是环境");inject-and-launch 目前仍只用于测试:BuildVisitorAgent 只有一个非测试调用方(eval-harness/main.go:164、candidate.go:138),backend/internal 和 backend/cmd 下没有任何包 import agentcore。生产的网页路径是直接组装 agent 的——internal/routes/public/sessions.go → capreg.AssembleVisitorBundle → inference.RunAgentTurn(把它提升进运行时是剩下的一步)。
flowchart LR
subgraph SM["StandMeet — prod box"]
WEB["web visitor entry
(fills neutral _meta session)"] --> ASM["routes/public sessions.go
(capreg AssembleVisitorBundle)"]
IM["im-bridge (Telegram)
via @standmeet/sdk-core"] --> ASM
ASM --> LOOP["eino ADK loop
(anthropic native / gemini / openai-compat)"]
LOOP --> SSE["SSE stream → app (frontend)"]
end
subgraph DEV["dev estate — same repo, separate go.mod"]
EV["eval-harness"] --> ED["EvalDriver
(canned data)"]
end
ED --> BUILD["BuildVisitorAgent(driver, input)
(bridge.go: Driver → loop ports)"]
BUILD --> LOOP
FUT["runtime promotion
(prod through BuildVisitorAgent — not yet)"] -.-> BUILD
一次对话轮次(时序图)
sequenceDiagram
participant A as app (SSE)
participant R as routes/session
participant L as eino loop
participant T as tool (mcp-server / connector)
A->>R: POST message, SSE opens
R->>L: RunAgentTurn (capreg-assembled tools)
loop until final answer
L-->>A: stream deltas (unbuffered passthrough)
L->>T: tool call (stdio MCP / connector handle)
T-->>L: result (+ ui:// card)
end
L-->>A: final answer
Note over R,L: client disconnect does NOT kill the turn (detached)
L->>R: turn completes → persist messages
Note over R: persist-at-completion — history lands once, whole
L-->>A: done, then optional epilogue frame "ghost" (agent_epilogue.go)
轮次生命周期(状态图)
stateDiagram-v2 [*] --> Streaming : turn starts Streaming --> Detached : client disconnects Streaming --> Completed : final answer Detached --> Completed : loop finishes anyway Completed --> Persisted : write messages once Persisted --> [*] : reload recovers from DB
子条目
- agent-core-diagram-coverage ——类视图覆盖索引(哪些已经画出,哪些还欠着)。
- agent-as-injectable-driver ——Bridge/Driver,启动的接缝(已落地)。
- entry-agnostic-agent ——各入口都是消费者;对内对外对称。
- detached-turn-persist-at-completion ——轮次生命周期与持久化的关系。
- force-final-answer ——循环终止的纪律。
- system-prompt-hash-regression ——确定性组装 → 漂移探测仪。
- unbuffered-sse-passthrough ——不缓冲的流式透传。
- eval-harness-on-prod-loop ——eval 作为真实循环的一个 Driver 消费者。
- ghost-steering —— 已构建,并在真模型上验证过。 用一条建议消息扭转对话方向:waypoint 作为软性关卡、默认单 ghost、动量/沉默/不重复,以及遥测闭环。